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_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_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); }
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_stsd_video(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_int32(file, table->temporal_quality); quicktime_write_int32(file, table->spatial_quality); quicktime_write_int16(file, table->width); quicktime_write_int16(file, table->height); quicktime_write_fixed32(file, table->dpi_horizontal); quicktime_write_fixed32(file, table->dpi_vertical); quicktime_write_int32(file, table->data_size); quicktime_write_int16(file, table->frames_per_sample); quicktime_write_char(file, strlen(table->compressor_name)); quicktime_write_data(file, table->compressor_name, 31); quicktime_write_int16(file, table->depth); quicktime_write_int16(file, table->ctab_id); // Write field order for mjpa if(table->fields) { quicktime_atom_t atom; quicktime_atom_write_header(file, &atom, "fiel"); quicktime_write_char(file, table->fields); quicktime_write_char(file, table->field_dominance); quicktime_atom_write_footer(file, &atom); } // Write header for mp4v if(table->esds.mpeg4_header_size && table->esds.mpeg4_header) { quicktime_write_esds(file, &table->esds, 1, 0); } if(table->avcc.data_size) { quicktime_write_avcc(file, &table->avcc); } // Write another 32 bits if(table->version == 1) quicktime_write_int32(file, 0x0); }
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); }
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); }
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); }
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; }
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_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_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_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); }
int 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); if (file->use_mp4) { quicktime_write_int32(file, 0x00000000); } else { quicktime_write_int16(file, smhd->balance); quicktime_write_int16(file, smhd->reserved); } quicktime_atom_write_footer(file, &atom); }
int quicktime_write_stsd(quicktime_t *file, quicktime_minf_t *minf, quicktime_stsd_t *stsd) { quicktime_atom_t atom; int i; quicktime_atom_write_header(file, &atom, "stsd"); quicktime_write_char(file, stsd->version); quicktime_write_int24(file, stsd->flags); quicktime_write_int32(file, stsd->total_entries); for(i = 0; i < stsd->total_entries; i++) { quicktime_write_stsd_table(file, minf, stsd->table); } quicktime_atom_write_footer(file, &atom); return 0; }
int quicktime_write_hmhd(quicktime_t *file, quicktime_hmhd_t *hmhd) { quicktime_atom_t atom; quicktime_atom_write_header(file, &atom, "hmhd"); quicktime_write_char(file, hmhd->version); quicktime_write_int24(file, hmhd->flags); quicktime_write_int16(file, hmhd->maxPDUsize); quicktime_write_int16(file, hmhd->avgPDUsize); quicktime_write_int32(file, hmhd->maxbitrate); quicktime_write_int32(file, hmhd->avgbitrate); quicktime_write_int32(file, hmhd->slidingavgbitrate); quicktime_atom_write_footer(file, &atom); return 0; }
int quicktime_write_stsz(quicktime_t *file, quicktime_stsz_t *stsz) { int i, result; quicktime_atom_t atom; quicktime_atom_write_header(file, &atom, "stsz"); /* optimize if possible */ /* Xanim requires an unoptimized table for video. */ /* if(!stsz->sample_size) */ /* { */ /* for(i = 0, result = 0; i < stsz->total_entries && !result; i++) */ /* { */ /* if(stsz->table[i].size != stsz->table[0].size) result = 1; */ /* } */ /* */ /* if(!result) */ /* { */ /* stsz->sample_size = stsz->table[0].size; */ /* stsz->total_entries = 0; */ /* free(stsz->table); */ /* } */ /* } */ quicktime_write_char(file, stsz->version); quicktime_write_int24(file, stsz->flags); quicktime_write_int32(file, stsz->sample_size); if(stsz->sample_size) { quicktime_write_int32(file, stsz->total_entries); } else { quicktime_write_int32(file, stsz->total_entries); for(i = 0; i < stsz->total_entries; i++) { quicktime_write_int32(file, stsz->table[i].size); } } quicktime_atom_write_footer(file, &atom); }
int quicktime_write_mvhd(quicktime_t *file, quicktime_mvhd_t *mvhd) { quicktime_atom_t atom; int i = 0; quicktime_atom_write_header(file, &atom, "mvhd"); quicktime_write_char(file, mvhd->version); quicktime_write_int24(file, mvhd->flags); quicktime_write_int32(file, mvhd->creation_time); quicktime_write_int32(file, mvhd->modification_time); quicktime_write_int32(file, mvhd->time_scale); quicktime_write_int32(file, mvhd->duration); quicktime_write_int32(file, 0x00010000); quicktime_write_int16(file, 0x0100); quicktime_write_int16(file, 0x0000); quicktime_write_int32(file, 0x00000000); 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, 0x00010000); for (i = 0; i < 3; i++) { quicktime_write_int32(file, 0x00000000); } quicktime_write_int32(file, 0x40000000); for (i = 0; i < 6; i++) { quicktime_write_int32(file, 0x00000000); } quicktime_write_int32(file, mvhd->next_track_id); quicktime_atom_write_footer(file, &atom); return 0; }
void 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); 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); }