int quicktime_write_hdlr(quicktime_t *file, quicktime_hdlr_t *hdlr) { quicktime_atom_t atom; quicktime_atom_write_header(file, &atom, "hdlr"); quicktime_write_char(file, hdlr->version); quicktime_write_int24(file, hdlr->flags); if (file->use_mp4) { int i; quicktime_write_int32(file, 0x00000000); quicktime_write_char32(file, hdlr->component_subtype); for (i = 0; i < 3; i++) { quicktime_write_int32(file, 0x00000000); } quicktime_write_data(file, hdlr->component_name, strlen(hdlr->component_name) + 1); } else { quicktime_write_char32(file, hdlr->component_type); quicktime_write_char32(file, hdlr->component_subtype); quicktime_write_int32(file, hdlr->component_manufacturer); quicktime_write_int32(file, hdlr->component_flags); quicktime_write_int32(file, hdlr->component_flag_mask); quicktime_write_pascal(file, hdlr->component_name); } quicktime_atom_write_footer(file, &atom); }
void quicktime_write_hdlr(quicktime_t *file, quicktime_hdlr_t *hdlr) { quicktime_atom_t atom; quicktime_atom_write_header(file, &atom, "hdlr"); quicktime_write_char(file, hdlr->version); quicktime_write_int24(file, hdlr->flags); quicktime_write_char32(file, hdlr->component_type); quicktime_write_char32(file, hdlr->component_subtype); quicktime_write_int32(file, hdlr->component_manufacturer); quicktime_write_int32(file, hdlr->component_flags); quicktime_write_int32(file, hdlr->component_flag_mask); quicktime_write_pascal(file, hdlr->component_name); quicktime_atom_write_footer(file, &atom); }
void quicktime_finalize_indx(quicktime_t *file) { int i, j; quicktime_riff_t *riff = file->riff[0]; quicktime_hdrl_t *hdrl = &riff->hdrl; quicktime_strl_t *strl; quicktime_indx_t *indx; quicktime_atom_t junk_atom; int junk_size; for(i = 0; i < file->moov.total_tracks; i++) { strl = hdrl->strl[i]; indx = &strl->indx; /* Write indx */ quicktime_set_position(file, strl->indx_offset); quicktime_atom_write_header(file, &indx->atom, "indx"); /* longs per entry */ quicktime_write_int16_le(file, indx->longs_per_entry); /* index sub type */ quicktime_write_char(file, indx->index_subtype); /* index type */ quicktime_write_char(file, indx->index_type); /* entries in use */ quicktime_write_int32_le(file, indx->table_size); /* chunk ID */ quicktime_write_char32(file, indx->chunk_id); /* reserved */ quicktime_write_int32_le(file, 0); quicktime_write_int32_le(file, 0); quicktime_write_int32_le(file, 0); /* table */ for(j = 0; j < indx->table_size; j++) { quicktime_indxtable_t *indx_table = &indx->table[j]; quicktime_write_int64_le(file, indx_table->index_offset); quicktime_write_int32_le(file, indx_table->index_size); quicktime_write_int32_le(file, indx_table->duration); } quicktime_atom_write_footer(file, &indx->atom); /* Rewrite JUNK less indx size and indx header size */ junk_size = strl->padding_size - indx->atom.size - 8; /* * quicktime_atom_write_header(file, &junk_atom, "JUNK"); * for(j = 0; j < junk_size; j += 4) * quicktime_write_int32_le(file, 0); * quicktime_atom_write_footer(file, &junk_atom); */ } }
void quicktime_write_dref_table(quicktime_t *file, quicktime_dref_table_t *table) { int len = strlen(table->data_reference); quicktime_write_int32(file, 12 + len); quicktime_write_char32(file, table->type); quicktime_write_char(file, table->version); quicktime_write_int24(file, table->flags); if(len) quicktime_write_data(file, table->data_reference, len); }
int quicktime_atom_write_header64(quicktime_t *file, quicktime_atom_t *atom, char *text) { int result = 0; atom->start = quicktime_position(file); result = !quicktime_write_int32(file, 1); if(!result) result = !quicktime_write_char32(file, text); if(!result) result = !quicktime_write_int64(file, 0); atom->use_64 = 1; return result; }
int quicktime_atom_write_header(quicktime_t *file, quicktime_atom_t *atom, char *text) { int result = 0; if(file->use_avi) { reset(atom); atom->start = quicktime_position(file) + 8; result = !quicktime_write_char32(file, text); if(!result) result = !quicktime_write_int32_le(file, 0); atom->use_64 = 0; } else { atom->start = quicktime_position(file); result = !quicktime_write_int32(file, 0); if(!result) result = !quicktime_write_char32(file, text); atom->use_64 = 0; } return result; }
void quicktime_init_odml(quicktime_t *file, quicktime_hdrl_t *hdrl) { quicktime_atom_t list_atom, dmlh_atom; // LIST 'odml' quicktime_atom_write_header(file, &list_atom, "LIST"); quicktime_write_char32(file, "odml"); // 'dmlh' quicktime_atom_write_header(file, &dmlh_atom, "dmlh"); // Placeholder for total frames in all RIFF objects hdrl->total_frames_offset = quicktime_position(file); quicktime_write_int32_le(file, 0); quicktime_atom_write_footer(file, &dmlh_atom); quicktime_atom_write_footer(file, &list_atom); }
void quicktime_init_riff(quicktime_t *file) { // Create new RIFF quicktime_riff_t *riff = quicktime_new_riff(file); // Write riff header // RIFF 'AVI ' quicktime_atom_write_header(file, &riff->atom, "RIFF"); quicktime_write_char32(file, "AVI "); // Write header list in first RIFF only if(file->total_riffs < 2) { quicktime_init_hdrl(file, &riff->hdrl); riff->have_hdrl = 1; } quicktime_init_movi(file, riff); }
quicktime_t* quicktime_open(char *filename, int rd, int wr, int append) { quicktime_t *new_file = malloc(sizeof(quicktime_t)); char flags[10]; int exists = 0; quicktime_init(new_file); new_file->wr = wr; new_file->rd = rd; new_file->mdat.start = 0; if (!strcmp(&filename[strlen(filename)-4], ".mp4")) { new_file->use_mp4 = TRUE; } else { new_file->use_mp4 = FALSE; } if(rd && (new_file->stream = fopen(filename, "rb"))) { exists = 1; fclose(new_file->stream); new_file->stream = NULL; } if(rd && !wr) sprintf(flags, "rb"); else if(!rd && wr) sprintf(flags, "wb"); else if(rd && wr) { if(exists) sprintf(flags, "rb+"); else sprintf(flags, "wb+"); } if(!(new_file->stream = fopen(filename, flags))) { perror("quicktime_open"); free(new_file); return 0; } if(rd && exists) { fseek(new_file->stream, 0, SEEK_END); new_file->total_length = ftell(new_file->stream); fseek(new_file->stream, 0, SEEK_SET); if(quicktime_read_info(new_file)) { quicktime_close(new_file); new_file = 0; } } if(wr) { if(!exists || !append) { /* start the data atom */ quicktime_write_int32(new_file, 0); quicktime_write_char32(new_file, "mdat"); } else { quicktime_set_position(new_file, new_file->mdat.start + new_file->mdat.size); fseek(new_file->stream, new_file->mdat.start + new_file->mdat.size, SEEK_SET); } } return new_file; }
void quicktime_init_hdrl(quicktime_t *file, quicktime_hdrl_t *hdrl) { int i; quicktime_atom_t avih_atom; int current_track; // LIST 'hdrl' quicktime_atom_write_header(file, &hdrl->atom, "LIST"); quicktime_write_char32(file, "hdrl"); // avih quicktime_atom_write_header(file, &avih_atom, "avih"); if(file->total_vtracks) { int d = quicktime_frame_rate_d(file, 0); int n = quicktime_frame_rate_n(file, 0); quicktime_write_int32_le(file, (uint32_t)(1000000. * d / n)); } else quicktime_write_int32_le(file, 0); hdrl->bitrate_offset = quicktime_position(file); quicktime_write_int32_le(file, 0); /* bitrate in bytes */ quicktime_write_int32_le(file, 0); /* padding */ quicktime_write_int32_le(file, AVI_TRUSTCKTYPE | AVI_HASINDEX | AVI_MUSTUSEINDEX | AVI_ISINTERLEAVED); /* flags */ hdrl->frames_offset = quicktime_position(file); quicktime_write_int32_le(file, 0); /* nb frames, filled later */ quicktime_write_int32_le(file, 0); /* initial frame */ quicktime_write_int32_le(file, file->moov.total_tracks); /* nb streams */ quicktime_write_int32_le(file, 0); /* suggested buffer size */ if(file->total_vtracks) { quicktime_write_int32_le(file, file->vtracks[0].track->tkhd.track_width); quicktime_write_int32_le(file, file->vtracks[0].track->tkhd.track_height); } else { quicktime_write_int32_le(file, 0); quicktime_write_int32_le(file, 0); } quicktime_write_int32_le(file, 0); /* reserved */ quicktime_write_int32_le(file, 0); /* reserved */ quicktime_write_int32_le(file, 0); /* reserved */ quicktime_write_int32_le(file, 0); /* reserved */ quicktime_atom_write_footer(file, &avih_atom); /* Write stream lists. */ /* Need the track maps to get the WAV ID for audio. */ current_track = 0; for(i = 0; i < file->total_vtracks; i++) { quicktime_video_map_t *video_map = &file->vtracks[i]; quicktime_trak_t *trak = video_map->track; quicktime_strl_t *strl = hdrl->strl[current_track++] = quicktime_new_strl(); quicktime_init_strl(file, 0, video_map, trak, strl); } for(i = 0; i < file->total_atracks; i++) { quicktime_audio_map_t *audio_map = &file->atracks[i]; quicktime_trak_t *trak = audio_map->track; quicktime_strl_t *strl = hdrl->strl[current_track++] = quicktime_new_strl(); quicktime_init_strl(file, audio_map, 0, trak, strl); } /* * for(i = 0; i < file->moov.total_tracks; i++) * { * printf("quicktime_init_hdrl 10 %d %p\n", i, file->riff[0]->hdrl.strl[i]->tag); * } */ /* ODML header */ quicktime_init_odml(file, hdrl); quicktime_atom_write_footer(file, &hdrl->atom); }