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); } }
int quicktime_close(quicktime_t *file) { int result = 0; if(file->wr) { quicktime_codecs_flush(file); // Reenable buffer for quick header writing. quicktime_set_presave(file, 1); if(file->use_avi) { quicktime_atom_t junk_atom; int i; // Finalize last header quicktime_finalize_riff(file, file->riff[file->total_riffs - 1]); int64_t position = quicktime_position(file); // Finalize the odml header quicktime_finalize_odml(file, &file->riff[0]->hdrl); // Finalize super indexes quicktime_finalize_indx(file); // Pad ending quicktime_set_position(file, position); quicktime_atom_write_header(file, &junk_atom, "JUNK"); for(i = 0; i < 0x406; i++) quicktime_write_int32_le(file, 0); quicktime_atom_write_footer(file, &junk_atom); } else { // Atoms are only written here if(file->stream) { quicktime_write_moov(file, &(file->moov)); quicktime_atom_write_footer(file, &file->mdat.atom); } } } quicktime_file_close(file); quicktime_delete(file); free(file); return result; }
int quicktime_write_stsc(quicktime_t *file, quicktime_stsc_t *stsc) { int i, last_same; quicktime_atom_t atom; quicktime_atom_write_header(file, &atom, "stsc"); for(i = 1, last_same = 0; i < stsc->total_entries; i++) { if(stsc->table[i].samples != stsc->table[last_same].samples) { /* An entry has a different sample count. */ last_same++; if(last_same < i) { /* Move it up the list. */ stsc->table[last_same] = stsc->table[i]; } } } last_same++; stsc->total_entries = last_same; quicktime_write_char(file, stsc->version); quicktime_write_int24(file, stsc->flags); quicktime_write_int32(file, stsc->total_entries); for(i = 0; i < stsc->total_entries; i++) { quicktime_write_int32(file, stsc->table[i].chunk); quicktime_write_int32(file, stsc->table[i].samples); quicktime_write_int32(file, stsc->table[i].id); } quicktime_atom_write_footer(file, &atom); }
void quicktime_write_dinf(quicktime_t *file, quicktime_dinf_t *dinf) { quicktime_atom_t atom; quicktime_atom_write_header(file, &atom, "dinf"); quicktime_write_dref(file, &(dinf->dref)); quicktime_atom_write_footer(file, &atom); }
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_avcc(quicktime_t *file, quicktime_avcc_t *avcc) { quicktime_atom_t atom; quicktime_atom_write_header(file, &atom, "avcC"); quicktime_write_data(file, avcc->data, avcc->data_size); quicktime_atom_write_footer(file, &atom); }
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); }
int quicktime_write_nump(quicktime_t *file, quicktime_nump_t *nump) { quicktime_atom_t atom; quicktime_atom_write_header(file, &atom, "nump"); quicktime_write_int64(file, nump->numPackets); quicktime_atom_write_footer(file, &atom); }
int quicktime_write_dimm(quicktime_t *file, quicktime_dimm_t *dimm) { quicktime_atom_t atom; quicktime_atom_write_header(file, &atom, "dimm"); quicktime_write_int64(file, dimm->numBytes); quicktime_atom_write_footer(file, &atom); }
int quicktime_write_tmin(quicktime_t *file, quicktime_tmin_t *tmin) { quicktime_atom_t atom; quicktime_atom_write_header(file, &atom, "tmin"); quicktime_write_int32(file, tmin->milliSecs); quicktime_atom_write_footer(file, &atom); }
int quicktime_write_mdia(quicktime_t *file, quicktime_mdia_t *mdia) { quicktime_atom_t atom; quicktime_atom_write_header(file, &atom, "mdia"); quicktime_write_mdhd(file, &(mdia->mdhd)); quicktime_write_hdlr(file, &(mdia->hdlr)); quicktime_write_minf(file, &(mdia->minf)); quicktime_atom_write_footer(file, &atom); }
int quicktime_write_gmhd(quicktime_t *file, quicktime_gmhd_t *gmhd) { quicktime_atom_t atom; quicktime_atom_write_header(file, &atom, "gmhd"); quicktime_write_gmin(file, &(gmhd->gmin)); quicktime_atom_write_footer(file, &atom); }
void quicktime_write_stsd_audio(quicktime_t *file, quicktime_stsd_table_t *table) { quicktime_write_int16(file, table->version); quicktime_write_int16(file, table->revision); quicktime_write_data(file, table->vendor, 4); quicktime_write_int16(file, table->channels); quicktime_write_int16(file, table->sample_size); quicktime_write_int16(file, table->compression_id); quicktime_write_int16(file, table->packet_size); quicktime_write_fixed32(file, table->sample_rate); // Write header for mp4a if(table->esds.mpeg4_header_size && table->esds.mpeg4_header) { // Android requires leaving out the WAVE header #if 0 // Version 1 info quicktime_write_int32(file, 0); quicktime_write_int32(file, 0); quicktime_write_int32(file, 0); quicktime_write_int32(file, 0); quicktime_atom_t wave_atom; quicktime_atom_t frma_atom; quicktime_atom_t mp4a_atom; quicktime_atom_write_header(file, &wave_atom, "wave"); quicktime_atom_write_header(file, &frma_atom, "frma"); quicktime_write_data(file, "mp4a", 4); quicktime_atom_write_footer(file, &frma_atom); quicktime_atom_write_header(file, &mp4a_atom, "mp4a"); quicktime_write_int32(file, 0x0); quicktime_atom_write_footer(file, &mp4a_atom); #endif // 0 quicktime_write_esds(file, &table->esds, 0, 1); // quicktime_atom_write_footer(file, &wave_atom); } }
int quicktime_write_tmax(quicktime_t *file, quicktime_tmax_t *tmax) { quicktime_atom_t atom; quicktime_atom_write_header(file, &atom, "tmax"); quicktime_write_int32(file, tmax->milliSecs); quicktime_atom_write_footer(file, &atom); return 0; }
void quicktime_write_smhd(quicktime_t *file, quicktime_smhd_t *smhd) { quicktime_atom_t atom; quicktime_atom_write_header(file, &atom, "smhd"); quicktime_write_char(file, smhd->version); quicktime_write_int24(file, smhd->flags); quicktime_write_int16(file, smhd->balance); quicktime_write_int16(file, smhd->reserved); quicktime_atom_write_footer(file, &atom); }
int quicktime_write_tkhd(quicktime_t *file, quicktime_tkhd_t *tkhd) { quicktime_atom_t atom; quicktime_atom_write_header(file, &atom, "tkhd"); quicktime_write_char(file, tkhd->version); quicktime_write_int24(file, tkhd->flags); quicktime_write_int32(file, tkhd->creation_time); quicktime_write_int32(file, tkhd->modification_time); quicktime_write_int32(file, tkhd->track_id); quicktime_write_int32(file, tkhd->reserved1); quicktime_write_int32(file, tkhd->duration); if (file->use_mp4) { int i; for (i = 0; i < 3; i++) { quicktime_write_int32(file, 0x00000000); } if (tkhd->is_audio) { quicktime_write_int16(file, 0x0100); } else { quicktime_write_int16(file, 0x0000); } quicktime_write_int16(file, 0x0000); quicktime_write_int32(file, 0x00010000); for (i = 0; i < 3; i++) { quicktime_write_int32(file, 0x00000000); } quicktime_write_int32(file, 0x00010000); for (i = 0; i < 3; i++) { quicktime_write_int32(file, 0x00000000); } quicktime_write_int32(file, 0x40000000); if (tkhd->is_video) { quicktime_write_int32(file, 0x01400000); quicktime_write_int32(file, 0x00F00000); } else { quicktime_write_int32(file, 0x00000000); quicktime_write_int32(file, 0x00000000); } } else { quicktime_write_data(file, tkhd->reserved2, 8); quicktime_write_int16(file, tkhd->layer); quicktime_write_int16(file, tkhd->alternate_group); quicktime_write_fixed16(file, tkhd->volume); quicktime_write_int16(file, tkhd->reserved3); quicktime_write_matrix(file, &(tkhd->matrix)); quicktime_write_fixed32(file, tkhd->track_width); quicktime_write_fixed32(file, tkhd->track_height); } quicktime_atom_write_footer(file, &atom); }
int quicktime_write_maxr(quicktime_t *file, quicktime_maxr_t *maxr) { quicktime_atom_t atom; quicktime_atom_write_header(file, &atom, "maxr"); quicktime_write_int32(file, maxr->granularity); quicktime_write_int32(file, maxr->maxBitRate); quicktime_atom_write_footer(file, &atom); return 0; }
int quicktime_write_hint(quicktime_t *file, quicktime_hint_t *hint) { quicktime_atom_t atom; int i; quicktime_atom_write_header(file, &atom, "hint"); for (i = 0; i < hint->numTracks; i++) { quicktime_write_int32(file, hint->trackIds[i]); } quicktime_atom_write_footer(file, &atom); }
void quicktime_write_stsd_table(quicktime_t *file, quicktime_minf_t *minf, quicktime_stsd_table_t *table) { quicktime_atom_t atom; quicktime_atom_write_header(file, &atom, table->format); /*printf("quicktime_write_stsd_table %c%c%c%c\n", table->format[0], table->format[1], table->format[2], table->format[3]); */ quicktime_write_data(file, table->reserved, 6); quicktime_write_int16(file, table->data_reference); if(minf->is_audio) quicktime_write_stsd_audio(file, table); if(minf->is_video) quicktime_write_stsd_video(file, table); quicktime_atom_write_footer(file, &atom); }
int quicktime_write_esds_common(quicktime_t *file, quicktime_esds_t *esds, int esid, u_int objectType, u_int streamType) { quicktime_atom_t atom; if (!file->use_mp4) { return 0; } quicktime_atom_write_header(file, &atom, "esds"); quicktime_write_char(file, esds->version); quicktime_write_int24(file, esds->flags); quicktime_write_char(file, 0x03); /* ES_DescrTag */ quicktime_write_mp4_descr_length(file, 3 + (5 + (13 + (5 + esds->decoderConfigLen))) + 3, FALSE); quicktime_write_int16(file, esid); quicktime_write_char(file, 0x10); /* streamPriorty = 16 (0-31) */ /* DecoderConfigDescriptor */ quicktime_write_char(file, 0x04); /* DecoderConfigDescrTag */ quicktime_write_mp4_descr_length(file, 13 + (5 + esds->decoderConfigLen), FALSE); quicktime_write_char(file, objectType); /* objectTypeIndication */ quicktime_write_char(file, streamType); /* streamType */ quicktime_write_int24(file, 0); /* buffer size */ quicktime_write_int32(file, 0); /* max bitrate */ quicktime_write_int32(file, 0); /* average bitrate */ quicktime_write_char(file, 0x05); /* DecSpecificInfoTag */ quicktime_write_mp4_descr_length(file, esds->decoderConfigLen, FALSE); quicktime_write_data(file, esds->decoderConfig, esds->decoderConfigLen); /* SLConfigDescriptor */ quicktime_write_char(file, 0x06); /* SLConfigDescrTag */ quicktime_write_char(file, 0x01); /* length */ quicktime_write_char(file, 0x02); /* constant in mp4 files */ /* no IPI_DescrPointer */ /* no IP_IdentificationDataSet */ /* no IPMP_DescriptorPointer */ /* no LanguageDescriptor */ /* no QoS_Descriptor */ /* no RegistrationDescriptor */ /* no ExtensionDescriptor */ quicktime_atom_write_footer(file, &atom); }
int quicktime_write_tref(quicktime_t *file, quicktime_tref_t *tref) { quicktime_atom_t atom; if (tref->hint.numTracks == 0) { return; } quicktime_atom_write_header(file, &atom, "tref"); quicktime_write_hint(file, &(tref->hint)); quicktime_atom_write_footer(file, &atom); }
void quicktime_write_vmhd(quicktime_t *file, quicktime_vmhd_t *vmhd) { quicktime_atom_t atom; int i; quicktime_atom_write_header(file, &atom, "vmhd"); quicktime_write_char(file, vmhd->version); quicktime_write_int24(file, vmhd->flags); quicktime_write_int16(file, vmhd->graphics_mode); for(i = 0; i < 3; i++) quicktime_write_int16(file, vmhd->opcolor[i]); quicktime_atom_write_footer(file, &atom); }
void quicktime_finalize_riff(quicktime_t *file, quicktime_riff_t *riff) { // Write partial indexes quicktime_finalize_movi(file, &riff->movi); if(riff->have_hdrl) { //printf("quicktime_finalize_riff 1\n"); quicktime_finalize_hdrl(file, &riff->hdrl); //printf("quicktime_finalize_riff 10\n"); // Write original index for first RIFF quicktime_write_idx1(file, &riff->idx1); //printf("quicktime_finalize_riff 100\n"); } quicktime_atom_write_footer(file, &riff->atom); }
int quicktime_write_tkhd(quicktime_t *file, quicktime_tkhd_t *tkhd) { quicktime_atom_t atom; int i = 0; quicktime_atom_write_header(file, &atom, "tkhd"); quicktime_write_char(file, tkhd->version); if (tkhd->flags != 0) { quicktime_write_int24(file, 1); } else { quicktime_write_int24(file, tkhd->flags); } quicktime_write_int32(file, tkhd->creation_time); quicktime_write_int32(file, tkhd->modification_time); quicktime_write_int32(file, tkhd->track_id); quicktime_write_int32(file, tkhd->reserved1); quicktime_write_int32(file, tkhd->duration); for (i = 0; i < 3; i++) { quicktime_write_int32(file, 0x00000000); } if (tkhd->is_audio) { quicktime_write_int16(file, 0x0100); } else { quicktime_write_int16(file, 0x0000); } quicktime_write_int16(file, 0x0000); quicktime_write_int32(file, 0x00010000); for (i = 0; i < 3; i++) { quicktime_write_int32(file, 0x00000000); } quicktime_write_int32(file, 0x00010000); for (i = 0; i < 3; i++) { quicktime_write_int32(file, 0x00000000); } quicktime_write_int32(file, 0x40000000); if (tkhd->is_video) { quicktime_write_int32(file, 0x01400000); quicktime_write_int32(file, 0x00F00000); } else { quicktime_write_int32(file, 0x00000000); quicktime_write_int32(file, 0x00000000); } quicktime_atom_write_footer(file, &atom); return 0; }
int quicktime_write_hnti(quicktime_t *file, quicktime_hnti_t *hnti) { quicktime_atom_t atom; if (hnti->rtp.string == NULL) { return -1; } quicktime_atom_write_header(file, &atom, "hnti"); quicktime_write_rtp(file, &(hnti->rtp)); quicktime_atom_write_footer(file, &atom); return 0; }
void quicktime_write_dref(quicktime_t *file, quicktime_dref_t *dref) { int i; quicktime_atom_t atom; quicktime_atom_write_header(file, &atom, "dref"); quicktime_write_char(file, dref->version); quicktime_write_int24(file, dref->flags); quicktime_write_int32(file, dref->total_entries); for(i = 0; i < dref->total_entries; i++) { quicktime_write_dref_table(file, &(dref->table[i])); } 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_write_elst(quicktime_t *file, quicktime_elst_t *elst, long duration) { quicktime_atom_t atom; int i; quicktime_atom_write_header(file, &atom, "elst"); quicktime_write_char(file, elst->version); quicktime_write_int24(file, elst->flags); quicktime_write_int32(file, elst->total_entries); for(i = 0; i < elst->total_entries; i++) { quicktime_write_elst_table(file, elst->table, duration); } quicktime_atom_write_footer(file, &atom); }
void quicktime_write_mdhd(quicktime_t *file, quicktime_mdhd_t *mdhd) { quicktime_atom_t atom; quicktime_atom_write_header(file, &atom, "mdhd"); quicktime_write_char(file, mdhd->version); quicktime_write_int24(file, mdhd->flags); quicktime_write_int32(file, mdhd->creation_time); quicktime_write_int32(file, mdhd->modification_time); quicktime_write_int32(file, mdhd->time_scale); quicktime_write_int32(file, mdhd->duration); quicktime_write_int16(file, mdhd->language); quicktime_write_int16(file, mdhd->quality); quicktime_atom_write_footer(file, &atom); }
void quicktime_write_stts(quicktime_t *file, quicktime_stts_t *stts) { int i; quicktime_atom_t atom; quicktime_atom_write_header(file, &atom, "stts"); quicktime_write_char(file, stts->version); quicktime_write_int24(file, stts->flags); quicktime_write_int32(file, stts->total_entries); for(i = 0; i < stts->total_entries; i++) { quicktime_write_int32(file, stts->table[i].sample_count); quicktime_write_int32(file, stts->table[i].sample_duration); } quicktime_atom_write_footer(file, &atom); }