GF_Err schi_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; GF_SchemeInformationBox *ptr = (GF_SchemeInformationBox *)s; if (!s) return GF_BAD_PARAM; e = gf_isom_box_write_header(s, bs); if (e) return e; if (ptr->ikms) { e = gf_isom_box_write((GF_Box *) ptr->ikms, bs); if (e) return e; } if (ptr->isfm) { e = gf_isom_box_write((GF_Box *) ptr->isfm, bs); if (e) return e; } if (ptr->okms) { e = gf_isom_box_write((GF_Box *) ptr->okms, bs); if (e) return e; } if (ptr->tenc) { e = gf_isom_box_write((GF_Box *) ptr->tenc, bs); if (e) return e; } if (ptr->piff_tenc) { e = gf_isom_box_write((GF_Box *) ptr->piff_tenc, bs); if (e) return e; } return GF_OK; }
//replace the chunk and offset tables... static GF_Err WriteMoovAndMeta(GF_ISOFile *movie, GF_List *writers, GF_BitStream *bs) { u32 i; TrackWriter *writer; GF_Err e; GF_Box *stco; GF_SampleToChunkBox *stsc; if (movie->meta) { //write the moov box... e = gf_isom_box_size((GF_Box *)movie->meta); if (e) return e; e = gf_isom_box_write((GF_Box *)movie->meta, bs); if (e) return e; } if (movie->moov) { //switch all our tables i=0; while ((writer = (TrackWriter*)gf_list_enum(writers, &i))) { //don't delete them !!! stsc = writer->mdia->information->sampleTable->SampleToChunk; stco = writer->mdia->information->sampleTable->ChunkOffset; writer->mdia->information->sampleTable->SampleToChunk = writer->stsc; writer->mdia->information->sampleTable->ChunkOffset = writer->stco; writer->stco = stco; writer->stsc = stsc; } //write the moov box... e = gf_isom_box_size((GF_Box *)movie->moov); if (e) return e; e = gf_isom_box_write((GF_Box *)movie->moov, bs); //and re-switch our table. We have to do it that way because it is //needed when the moov is written first i=0; while ((writer = (TrackWriter*)gf_list_enum(writers, &i))) { //don't delete them !!! stsc = writer->stsc; stco = writer->stco; writer->stsc = writer->mdia->information->sampleTable->SampleToChunk; writer->stco = writer->mdia->information->sampleTable->ChunkOffset; writer->mdia->information->sampleTable->SampleToChunk = stsc; writer->mdia->information->sampleTable->ChunkOffset = stco; } if (e) return e; } return GF_OK; }
GF_Err aprm_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; GF_AdobeStdEncryptionParamsBox *ptr = (GF_AdobeStdEncryptionParamsBox *)s; if (!s) return GF_BAD_PARAM; e = gf_isom_full_box_write(s, bs); if (e) return e; //aeib e = gf_isom_box_write((GF_Box *) ptr->enc_info, bs); if (e) return e; //akey e = gf_isom_box_write((GF_Box *) ptr->key_info, bs); if (e) return e; return GF_OK; }
GF_Err adkm_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; GF_AdobeDRMKeyManagementSystemBox *ptr = (GF_AdobeDRMKeyManagementSystemBox *)s; if (!s) return GF_BAD_PARAM; e = gf_isom_full_box_write(s, bs); if (e) return e; //ahdr e = gf_isom_box_write((GF_Box *) ptr->header, bs); if (e) return e; //adaf e = gf_isom_box_write((GF_Box *) ptr->au_format, bs); if (e) return e; return GF_OK; }
GF_Err gf_isom_hint_sample_write(GF_HintSample *ptr, GF_BitStream *bs) { u32 count, i; GF_HintPacket *pck; GF_Err e; if (ptr->hint_subtype==GF_ISOM_BOX_TYPE_FDP_STSD) { e = gf_isom_box_size((GF_Box*)ptr); if (!e) e = gf_isom_box_write((GF_Box*)ptr, bs); return e; } count = gf_list_count(ptr->packetTable); gf_bs_write_u16(bs, count); gf_bs_write_u16(bs, ptr->reserved); //write the packet table for (i=0; i<count; i++) { pck = (GF_HintPacket *)gf_list_get(ptr->packetTable, i); e = gf_isom_hint_pck_write(pck, bs); if (e) return e; } //write additional data if (ptr->AdditionalData) { gf_bs_write_data(bs, ptr->AdditionalData, ptr->dataLength); } return GF_OK; }
GF_Err odkm_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; GF_OMADRMKMSBox *ptr = (GF_OMADRMKMSBox *)s; if (!s) return GF_BAD_PARAM; e = gf_isom_full_box_write(s, bs); if (e) return e; if (ptr->hdr) { e = gf_isom_box_write((GF_Box*)ptr->hdr, bs); if (e) return e; } if (ptr->fmt) { e = gf_isom_box_write((GF_Box*)ptr->fmt, bs); if (e) return e; } return GF_OK; }
static GFINLINE GF_Err gpp_write_modifier(GF_BitStream *bs, GF_Box *a) { GF_Err e; if (!a) return GF_OK; e = gf_isom_box_size(a); if (!e) e = gf_isom_box_write(a, bs); return e; }
GF_Err sinf_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; GF_ProtectionSchemeInfoBox *ptr = (GF_ProtectionSchemeInfoBox *)s; if (!s) return GF_BAD_PARAM; e = gf_isom_box_write_header(s, bs); if (e) return e; //frma e = gf_isom_box_write((GF_Box *) ptr->original_format, bs); if (e) return e; // schm e = gf_isom_box_write((GF_Box *) ptr->scheme_type, bs); if (e) return e; // schi e = gf_isom_box_write((GF_Box *) ptr->info, bs); if (e) return e; return GF_OK; }
GF_Err vtcu_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; GF_VTTCueBox *cuebox = (GF_VTTCueBox *)s; e = gf_isom_box_write_header(s, bs); if (e) return e; if (cuebox->id) { e = gf_isom_box_write((GF_Box *)cuebox->id, bs); if (e) return e; } if (cuebox->settings) { e = gf_isom_box_write((GF_Box *)cuebox->settings, bs); if (e) return e; } if (cuebox->payload) { e = gf_isom_box_write((GF_Box *)cuebox->payload, bs); } return e; }
GF_Err gppa_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; GF_3GPPAudioSampleEntryBox *ptr = (GF_3GPPAudioSampleEntryBox *)s; e = gf_isom_box_write_header(s, bs); if (e) return e; gf_isom_audio_sample_entry_write((GF_AudioSampleEntryBox*)s, bs); return gf_isom_box_write((GF_Box *)ptr->info, bs); }
GF_Err gppv_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; GF_3GPPVisualSampleEntryBox *ptr = (GF_3GPPVisualSampleEntryBox*)s; e = gf_isom_box_write_header(s, bs); if (e) return e; gf_isom_video_sample_entry_write((GF_VisualSampleEntryBox *)s, bs); e = gf_isom_box_write((GF_Box *)ptr->info, bs); if (e) return e; return GF_OK; }
GF_Err wvtt_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; GF_WebVTTSampleEntryBox *wvtt = (GF_WebVTTSampleEntryBox *)s; e = gf_isom_box_write_header(s, bs); gf_bs_write_data(bs, wvtt->reserved, 6); gf_bs_write_u16(bs, wvtt->dataReferenceIndex); if (wvtt->config) gf_isom_box_write((GF_Box *)wvtt->config, bs); return e; }
GF_Err ahdr_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; GF_AdobeDRMHeaderBox *ptr = (GF_AdobeDRMHeaderBox *)s; if (!s) return GF_BAD_PARAM; e = gf_isom_full_box_write(s, bs); if (e) return e; e = gf_isom_box_write((GF_Box *) ptr->std_enc_params, bs); if (e) return e; return GF_OK; }
GF_Err akey_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; GF_AdobeKeyInfoBox *ptr = (GF_AdobeKeyInfoBox *)s; if (!s) return GF_BAD_PARAM; e = gf_isom_full_box_write(s, bs); if (e) return e; e = gf_isom_box_write((GF_Box *) ptr->params, bs); if (e) return e; return GF_OK; }
GF_Err meta_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; GF_MetaBox *ptr = (GF_MetaBox *)s; if (!s) return GF_BAD_PARAM; e = gf_isom_full_box_write(s, bs); if (e) return e; if (ptr->handler) { e = gf_isom_box_write((GF_Box *) ptr->handler, bs); if (e) return e; } if (ptr->primary_resource) { e = gf_isom_box_write((GF_Box *) ptr->primary_resource, bs); if (e) return e; } if (ptr->file_locations) { e = gf_isom_box_write((GF_Box *) ptr->file_locations, bs); if (e) return e; } if (ptr->item_locations) { e = gf_isom_box_write((GF_Box *) ptr->item_locations, bs); if (e) return e; } if (ptr->protections) { e = gf_isom_box_write((GF_Box *) ptr->protections, bs); if (e) return e; } if (ptr->item_infos) { e = gf_isom_box_write((GF_Box *) ptr->item_infos, bs); if (e) return e; } if (ptr->IPMP_control) { e = gf_isom_box_write((GF_Box *) ptr->IPMP_control, bs); if (e) return e; } if (ptr->item_refs) { e = gf_isom_box_write((GF_Box *)ptr->item_refs, bs); if (e) return e; } if (ptr->item_props) { e = gf_isom_box_write((GF_Box *) ptr->item_props, bs); if (e) return e; } return GF_OK; }
GF_Err ListItem_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; GF_ListItemBox *ptr = (GF_ListItemBox *) s; e = gf_isom_box_write_header(s, bs); if (e) return e; /*iTune way*/ if (ptr->data->type) return gf_isom_box_write((GF_Box* )ptr->data, bs); /*QT way*/ gf_bs_write_u16(bs, ptr->data->dataSize); gf_bs_write_u16(bs, 0); gf_bs_write_data(bs, ptr->data->data, ptr->data->dataSize); return GF_OK; }
GF_Err iref_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; u32 count, i; GF_ItemReferenceBox *ptr = (GF_ItemReferenceBox *)s; if (!s) return GF_BAD_PARAM; e = gf_isom_full_box_write(s, bs); if (e) return e; count = gf_list_count(ptr->references); for (i = 0; i < count; i++) { GF_Box *a = (GF_Box *)gf_list_get(ptr->references, i); e = gf_isom_box_write(a, bs); if (e) return e; } return e; }
GF_Err ipro_Write(GF_Box *s, GF_BitStream *bs) { u32 count, i; GF_Err e; GF_ItemProtectionBox *ptr = (GF_ItemProtectionBox *)s; if (!s) return GF_BAD_PARAM; e = gf_isom_full_box_write(s, bs); if (e) return e; count = gf_list_count(ptr->protection_information); gf_bs_write_u16(bs, count); if (count) { for (i = 0; i < count; i++) { GF_Box *a = (GF_Box *)gf_list_get(ptr->protection_information, i); e = gf_isom_box_write(a, bs); if (e) return e; } } return GF_OK; }
GF_ISOSample *gf_isom_webvtt_to_sample(void *s) { GF_Err e = GF_OK; GF_ISOSample *res; GF_BitStream *bs; u32 i; GF_WebVTTCue *cue; GF_WebVTTSample *samp = (GF_WebVTTSample *)s; if (!samp) return NULL; bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); if (gf_list_count(samp->cues)) { i=0; while ((cue = (GF_WebVTTCue *)gf_list_enum(samp->cues, &i))) { e = webvtt_write_cue(bs, cue); if (e) break; } if (e) { gf_bs_del(bs); return NULL; } } else { GF_Box *cuebox = (GF_Box *)vtte_New(); e = gf_isom_box_size((GF_Box *)cuebox); if (!e) e = gf_isom_box_write((GF_Box *)cuebox, bs); gf_isom_box_del((GF_Box *)cuebox); if (e) { gf_bs_del(bs); return NULL; } } res = gf_isom_sample_new(); if (!res) { gf_bs_del(bs); return NULL; } gf_bs_get_content(bs, &res->data, &res->dataLength); gf_bs_del(bs); res->IsRAP = RAP; return res; }
static GF_Err webvtt_write_cue(GF_BitStream *bs, GF_WebVTTCue *cue) { GF_Err e; GF_VTTCueBox *cuebox; if (!cue) return GF_OK; cuebox = (GF_VTTCueBox *)vtcu_New(); if (cue->id) { cuebox->id = (GF_StringBox *)boxstring_new_with_data(GF_ISOM_BOX_TYPE_IDEN, cue->id); } if (cue->settings) { cuebox->settings = (GF_StringBox *)boxstring_new_with_data(GF_ISOM_BOX_TYPE_STTG, cue->settings); } if (cue->text) { cuebox->payload = (GF_StringBox *)boxstring_new_with_data(GF_ISOM_BOX_TYPE_PAYL, cue->text); } /* TODO: check if a time box should be written */ e = gf_isom_box_size((GF_Box *)cuebox); if (!e) e = gf_isom_box_write((GF_Box *)cuebox, bs); gf_isom_box_del((GF_Box *)cuebox); return e; }
//write the file track by track, with moov box before or after the mdat GF_Err WriteFlat(MovieWriter *mw, u8 moovFirst, GF_BitStream *bs) { GF_Err e; u32 i; u64 offset, finalOffset, totSize, begin, firstSize, finalSize; GF_Box *a; GF_List *writers = gf_list_new(); GF_ISOFile *movie = mw->movie; begin = totSize = 0; //first setup the writers e = SetupWriters(mw, writers, 0); if (e) goto exit; if (!moovFirst) { if (movie->openMode == GF_ISOM_OPEN_WRITE) { begin = 0; totSize = gf_isom_datamap_get_offset(movie->editFileMap); /*start boxes have not been written yet, do it*/ if (!totSize) { if (movie->is_jp2) { gf_bs_write_u32(movie->editFileMap->bs, 12); gf_bs_write_u32(movie->editFileMap->bs, GF_4CC('j','P',' ',' ')); gf_bs_write_u32(movie->editFileMap->bs, 0x0D0A870A); totSize += 12; begin += 12; } if (movie->brand) { e = gf_isom_box_size((GF_Box *)movie->brand); if (e) goto exit; e = gf_isom_box_write((GF_Box *)movie->brand, movie->editFileMap->bs); if (e) goto exit; totSize += movie->brand->size; begin += movie->brand->size; } if (movie->pdin) { e = gf_isom_box_size((GF_Box *)movie->pdin); if (e) goto exit; e = gf_isom_box_write((GF_Box *)movie->pdin, movie->editFileMap->bs); if (e) goto exit; totSize += movie->pdin->size; begin += movie->pdin->size; } } else { if (movie->is_jp2) begin += 12; if (movie->brand) begin += movie->brand->size; if (movie->pdin) begin += movie->pdin->size; } totSize -= begin; } else { if (movie->is_jp2) { gf_bs_write_u32(bs, 12); gf_bs_write_u32(bs, GF_4CC('j','P',' ',' ')); gf_bs_write_u32(bs, 0x0D0A870A); } if (movie->brand) { e = gf_isom_box_size((GF_Box *)movie->brand); if (e) goto exit; e = gf_isom_box_write((GF_Box *)movie->brand, bs); if (e) goto exit; } /*then progressive download*/ if (movie->pdin) { e = gf_isom_box_size((GF_Box *)movie->pdin); if (e) goto exit; e = gf_isom_box_write((GF_Box *)movie->pdin, bs); if (e) goto exit; } } //if the moov is at the end, write directly i=0; while ((a = (GF_Box*)gf_list_enum(movie->TopBoxes, &i))) { switch (a->type) { /*written by hand*/ case GF_ISOM_BOX_TYPE_MOOV: case GF_ISOM_BOX_TYPE_META: case GF_ISOM_BOX_TYPE_FTYP: case GF_ISOM_BOX_TYPE_PDIN: break; case GF_ISOM_BOX_TYPE_MDAT: //in case we're capturing if (movie->openMode == GF_ISOM_OPEN_WRITE) { //emulate a write to recreate our tables (media data already written) e = DoWrite(mw, writers, bs, 1, begin); if (e) goto exit; continue; } //to avoid computing the size each time write always 4 + 4 + 8 bytes before begin = gf_bs_get_position(bs); gf_bs_write_u64(bs, 0); gf_bs_write_u64(bs, 0); e = DoWrite(mw, writers, bs, 0, gf_bs_get_position(bs)); if (e) goto exit; totSize = gf_bs_get_position(bs) - begin; break; default: e = gf_isom_box_size(a); if (e) goto exit; e = gf_isom_box_write(a, bs); if (e) goto exit; break; } } //OK, write the movie box. e = WriteMoovAndMeta(movie, writers, bs); if (e) goto exit; /*if data has been written, update mdat size*/ if (totSize) { offset = gf_bs_get_position(bs); e = gf_bs_seek(bs, begin); if (e) goto exit; if (totSize > 0xFFFFFFFF) { gf_bs_write_u32(bs, 1); } else { gf_bs_write_u32(bs, (u32) totSize); } gf_bs_write_u32(bs, GF_ISOM_BOX_TYPE_MDAT); if (totSize > 0xFFFFFFFF) gf_bs_write_u64(bs, totSize); e = gf_bs_seek(bs, offset); } movie->mdat->size = totSize; goto exit; } //nope, we have to write the moov first. The pb is that //1 - we don't know its size till the mdat is written //2 - we don't know the ofset at which the mdat will start... //3 - once the mdat is written, the chunkOffset table can have changed... if (movie->is_jp2) { gf_bs_write_u32(bs, 12); gf_bs_write_u32(bs, GF_4CC('j','P',' ',' ')); gf_bs_write_u32(bs, 0x0D0A870A); } if (movie->brand) { e = gf_isom_box_size((GF_Box *)movie->brand); if (e) goto exit; e = gf_isom_box_write((GF_Box *)movie->brand, bs); if (e) goto exit; } /*then progressive dnload*/ if (movie->pdin) { e = gf_isom_box_size((GF_Box *)movie->pdin); if (e) goto exit; e = gf_isom_box_write((GF_Box *)movie->pdin, bs); if (e) goto exit; } //What we will do is first emulate the write from the begining... //note: this will set the size of the mdat e = DoWrite(mw, writers, bs, 1, gf_bs_get_position(bs)); if (e) goto exit; firstSize = GetMoovAndMetaSize(movie, writers); //offset = (firstSize > 0xFFFFFFFF ? firstSize + 8 : firstSize) + 8 + (movie->mdat->dataSize > 0xFFFFFFFF ? 8 : 0); offset = firstSize + 8 + (movie->mdat->dataSize > 0xFFFFFFFF ? 8 : 0); e = ShiftOffset(movie, writers, offset); if (e) goto exit; //get the size and see if it has changed (eg, we moved to 64 bit offsets) finalSize = GetMoovAndMetaSize(movie, writers); if (firstSize != finalSize) { //we need to remove our offsets ResetWriters(writers); //finalOffset = (finalSize > 0xFFFFFFFF ? finalSize + 8 : finalSize) + 8 + (movie->mdat->dataSize > 0xFFFFFFFF ? 8 : 0); finalOffset = finalSize + 8 + (movie->mdat->dataSize > 0xFFFFFFFF ? 8 : 0); //OK, now we're sure about the final size. //we don't need to re-emulate, as the only thing that changed is the offset //so just shift the offset e = ShiftOffset(movie, writers, finalOffset - offset); if (e) goto exit; } //now write our stuff e = WriteMoovAndMeta(movie, writers, bs); if (e) goto exit; e = gf_isom_box_size((GF_Box *)movie->mdat); if (e) goto exit; e = gf_isom_box_write((GF_Box *)movie->mdat, bs); if (e) goto exit; //we don't need the offset as the moov is already written... ResetWriters(writers); e = DoWrite(mw, writers, bs, 0, 0); if (e) goto exit; //then the rest i=0; while ((a = (GF_Box*)gf_list_enum(movie->TopBoxes, &i))) { switch (a->type) { case GF_ISOM_BOX_TYPE_MOOV: case GF_ISOM_BOX_TYPE_META: case GF_ISOM_BOX_TYPE_FTYP: case GF_ISOM_BOX_TYPE_PDIN: case GF_ISOM_BOX_TYPE_MDAT: break; default: e = gf_isom_box_size(a); if (e) goto exit; e = gf_isom_box_write(a, bs); if (e) goto exit; } } exit: CleanWriters(writers); gf_list_del(writers); return e; }
static GF_Err WriteInterleaved(MovieWriter *mw, GF_BitStream *bs, Bool drift_inter) { GF_Err e; u32 i; GF_Box *a; u64 firstSize, finalSize, offset, finalOffset; GF_List *writers = gf_list_new(); GF_ISOFile *movie = mw->movie; //first setup the writers e = SetupWriters(mw, writers, 1); if (e) goto exit; if (movie->is_jp2) { gf_bs_write_u32(bs, 12); gf_bs_write_u32(bs, GF_4CC('j','P',' ',' ')); gf_bs_write_u32(bs, 0x0D0A870A); } if (movie->brand) { e = gf_isom_box_size((GF_Box *)movie->brand); if (e) goto exit; e = gf_isom_box_write((GF_Box *)movie->brand, bs); if (e) goto exit; } if (movie->pdin) { e = gf_isom_box_size((GF_Box *)movie->pdin); if (e) goto exit; e = gf_isom_box_write((GF_Box *)movie->pdin, bs); if (e) goto exit; } e = DoInterleave(mw, writers, bs, 1, gf_bs_get_position(bs), drift_inter); if (e) goto exit; firstSize = GetMoovAndMetaSize(movie, writers); offset = firstSize; if (movie->mdat && movie->mdat->dataSize) offset += 8 + (movie->mdat->dataSize > 0xFFFFFFFF ? 8 : 0); e = ShiftOffset(movie, writers, offset); if (e) goto exit; //get the size and see if it has changed (eg, we moved to 64 bit offsets) finalSize = GetMoovAndMetaSize(movie, writers); if (firstSize != finalSize) { //we need to remove our offsets ResetWriters(writers); finalOffset = finalSize; if (movie->mdat->dataSize) finalOffset += 8 + (movie->mdat->dataSize > 0xFFFFFFFF ? 8 : 0); //OK, now we're sure about the final size -> shift the offsets //we don't need to re-emulate, as the only thing that changed is the offset //so just shift the offset e = ShiftOffset(movie, writers, finalOffset - offset); if (e) goto exit; firstSize = GetMoovAndMetaSize(movie, writers); } //now write our stuff e = WriteMoovAndMeta(movie, writers, bs); if (e) goto exit; /*we have 8 extra bytes for large size (not computed in gf_isom_box_size) */ if (movie->mdat && movie->mdat->dataSize) { if (movie->mdat->dataSize > 0xFFFFFFFF) movie->mdat->dataSize += 8; e = gf_isom_box_size((GF_Box *)movie->mdat); if (e) goto exit; e = gf_isom_box_write((GF_Box *)movie->mdat, bs); if (e) goto exit; } //we don't need the offset as we are writing... ResetWriters(writers); e = DoInterleave(mw, writers, bs, 0, 0, drift_inter); if (e) goto exit; //then the rest i=0; while ((a = (GF_Box*)gf_list_enum(movie->TopBoxes, &i))) { switch (a->type) { case GF_ISOM_BOX_TYPE_MOOV: case GF_ISOM_BOX_TYPE_META: case GF_ISOM_BOX_TYPE_FTYP: case GF_ISOM_BOX_TYPE_PDIN: case GF_ISOM_BOX_TYPE_MDAT: break; default: e = gf_isom_box_size(a); if (e) goto exit; e = gf_isom_box_write(a, bs); if (e) goto exit; } } exit: CleanWriters(writers); gf_list_del(writers); return e; }
static GF_Err WriteInterleaved(MovieWriter *mw, GF_BitStream *bs, Bool drift_inter) { GF_Err e; u8 converted; u32 i; GF_Box *a; u64 offset, shift_offset, prev; GF_List *writers = gf_list_new(); GF_ISOFile *movie = mw->movie; //first setup the writers e = SetupWriters(mw, writers, 1); if (e) goto exit; if (movie->is_jp2) { gf_bs_write_u32(bs, 12); gf_bs_write_u32(bs, GF_4CC('j','P',' ',' ')); gf_bs_write_u32(bs, 0x0D0A870A); } if (movie->brand) { e = gf_isom_box_size((GF_Box *)movie->brand); if (e) goto exit; e = gf_isom_box_write((GF_Box *)movie->brand, bs); if (e) goto exit; } if (movie->pdin) { e = gf_isom_box_size((GF_Box *)movie->pdin); if (e) goto exit; e = gf_isom_box_write((GF_Box *)movie->pdin, bs); if (e) goto exit; } e = DoInterleave(mw, writers, bs, 1, gf_bs_get_position(bs), drift_inter); if (e) goto exit; shift_offset = 0; prev = 0; for (;;) { offset = GetMoovAndMetaSize(movie, writers); if (offset==prev) break; prev = offset; if (movie->mdat && movie->mdat->dataSize) offset += 8 + (movie->mdat->dataSize > 0xFFFFFFFF ? 8 : 0); e = ShiftOffset(movie, writers, offset-shift_offset,&converted); if (e) goto exit; shift_offset = offset; } //now write our stuff e = WriteMoovAndMeta(movie, writers, bs); if (e) goto exit; /*we have 8 extra bytes for large size (not computed in gf_isom_box_size) */ if (movie->mdat && movie->mdat->dataSize) { if (movie->mdat->dataSize > 0xFFFFFFFF) movie->mdat->dataSize += 8; e = gf_isom_box_size((GF_Box *)movie->mdat); if (e) goto exit; e = gf_isom_box_write((GF_Box *)movie->mdat, bs); if (e) goto exit; } //we don't need the offset as we are writing... ResetWriters(writers); e = DoInterleave(mw, writers, bs, 0, 0, drift_inter); if (e) goto exit; //then the rest i=0; while ((a = (GF_Box*)gf_list_enum(movie->TopBoxes, &i))) { switch (a->type) { case GF_ISOM_BOX_TYPE_MOOV: case GF_ISOM_BOX_TYPE_META: case GF_ISOM_BOX_TYPE_FTYP: case GF_ISOM_BOX_TYPE_PDIN: case GF_ISOM_BOX_TYPE_MDAT: break; default: e = gf_isom_box_size(a); if (e) goto exit; e = gf_isom_box_write(a, bs); if (e) goto exit; } } exit: CleanWriters(writers); gf_list_del(writers); return e; }