📄 isom_write.c
字号:
GF_EditBox *edts = (GF_EditBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_EDTS); if (!edts) return GF_OUT_OF_MEM; trak_AddBox((GF_Box*)trak, (GF_Box *)edts); } if (!trak->editBox->editList) { GF_EditListBox *elst = (GF_EditListBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_ELST); if (!elst) return GF_OUT_OF_MEM; edts_AddBox((GF_Box*)trak->editBox, (GF_Box *)elst); } ent = (GF_EdtsEntry *)malloc(sizeof(GF_EdtsEntry)); if (!ent) return GF_OUT_OF_MEM; ent->segmentDuration = EditDuration; switch (EditMode) { case GF_ISOM_EDIT_EMPTY: ent->mediaRate = 1; ent->mediaTime = -1; break; case GF_ISOM_EDIT_DWELL: ent->mediaRate = 0; ent->mediaTime = MediaTime; break; default: ent->mediaRate = 1; ent->mediaTime = MediaTime; break; } gf_list_add(trak->editBox->editList->entryList, ent); return SetTrackDuration(trak);}GF_Err gf_isom_modify_edit_segment(GF_ISOFile *movie, u32 trackNumber, u32 seg_index, u64 EditDuration, u64 MediaTime, u8 EditMode){ GF_Err e; GF_TrackBox *trak; GF_EdtsEntry *ent; trak = gf_isom_get_track_from_file(movie, trackNumber); if (!trak || !seg_index) return GF_BAD_PARAM; e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE); if (e) return e; if (!trak->editBox || !trak->editBox->editList) return GF_OK; if (gf_list_count(trak->editBox->editList->entryList)<seg_index) return GF_BAD_PARAM; ent = (GF_EdtsEntry*) gf_list_get(trak->editBox->editList->entryList, seg_index-1); ent->segmentDuration = EditDuration; switch (EditMode) { case GF_ISOM_EDIT_EMPTY: ent->mediaRate = 1; ent->mediaTime = -1; break; case GF_ISOM_EDIT_DWELL: ent->mediaRate = 0; ent->mediaTime = MediaTime; break; default: ent->mediaRate = 1; ent->mediaTime = MediaTime; break; } return SetTrackDuration(trak);}//removes the desired trackGF_Err gf_isom_remove_track(GF_ISOFile *movie, u32 trackNumber){ GF_Err e; GF_TrackBox *the_trak, *trak; GF_TrackReferenceTypeBox *tref; u32 i, j, k, *newRefs, descIndex; u8 found; GF_ISOSample *samp; the_trak = gf_isom_get_track_from_file(movie, trackNumber); if (!the_trak) return GF_BAD_PARAM; e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE); if (e) return e; if (movie->moov->iods && movie->moov->iods->descriptor) { GF_Descriptor *desc; GF_ES_ID_Inc *inc; GF_List *ESDs; desc = movie->moov->iods->descriptor; if (desc->tag == GF_ODF_ISOM_IOD_TAG) { ESDs = ((GF_IsomInitialObjectDescriptor *)desc)->ES_ID_IncDescriptors; } else if (desc->tag == GF_ODF_ISOM_OD_TAG) { ESDs = ((GF_IsomObjectDescriptor *)desc)->ES_ID_IncDescriptors; } else { return GF_ISOM_INVALID_FILE; } //remove the track ref from the root OD if any i=0; while ((inc = (GF_ES_ID_Inc *)gf_list_enum(ESDs, &i))) { if (inc->trackID == the_trak->Header->trackID) { gf_odf_desc_del((GF_Descriptor *)inc); i--; gf_list_rem(ESDs, i); } } } //remove the track from the movie gf_list_del_item(movie->moov->trackList, the_trak); //rewrite any OD tracks i=0; while ((trak = (GF_TrackBox *)gf_list_enum(movie->moov->trackList, &i))) { if (trak->Media->handler->handlerType != GF_ISOM_MEDIA_OD) continue; //this is an OD track... j = gf_isom_get_sample_count(movie, i); for (k=0; k < j; k++) { //getting the sample will remove the references to the deleted track in the output OD frame samp = gf_isom_get_sample(movie, i, k+1, &descIndex); if (!samp) break; //so let's update with the new OD frame ! If the sample is empty, remove it if (!samp->dataLength) { e = gf_isom_remove_sample(movie, i, k+1); if (e) return e; } else { e = gf_isom_update_sample(movie, i, k+1, samp, 1); if (e) return e; } //and don't forget to delete the sample gf_isom_sample_del(&samp); } } //remove the track ref from any "tref" box in all tracks (except the one to delete ;) i=0; while ((trak = (GF_TrackBox *)gf_list_enum(movie->moov->trackList, &i))) { if (trak == the_trak) continue; if (! trak->References || ! gf_list_count(trak->References->boxList)) continue; j=0; while ((tref = (GF_TrackReferenceTypeBox *)gf_list_enum(trak->References->boxList, &j))) { found = 0; for (k=0; k<tref->trackIDCount; k++) { if (tref->trackIDs[k] == the_trak->Header->trackID) found++; } if (!found) continue; //no more refs, remove this ref_type if (found == tref->trackIDCount) { gf_isom_box_del((GF_Box *)tref); j--; gf_list_rem(trak->References->boxList, j); } else { newRefs = (u32*)malloc(sizeof(u32) * (tref->trackIDCount - found)); found = 0; for (k = 0; k < tref->trackIDCount; k++) { if (tref->trackIDs[k] != the_trak->Header->trackID) { newRefs[k-found] = tref->trackIDs[k]; } else { found++; } } free(tref->trackIDs); tref->trackIDs = newRefs; tref->trackIDCount -= found; } } //a little opt: remove the ref box if empty... if (! gf_list_count(trak->References->boxList)) { gf_isom_box_del((GF_Box *)trak->References); trak->References = NULL; } } //delete the track gf_isom_box_del((GF_Box *)the_trak); /*update next track ID*/ movie->moov->mvhd->nextTrackID = 0; i=0; while ((trak = (GF_TrackBox *)gf_list_enum(movie->moov->trackList, &i))) { if (trak->Header->trackID>movie->moov->mvhd->nextTrackID) movie->moov->mvhd->nextTrackID = trak->Header->trackID; } return GF_OK;}GF_Err gf_isom_set_copyright(GF_ISOFile *movie, const char *threeCharCode, char *notice){ GF_Err e; GF_CopyrightBox *ptr; GF_UserDataMap *map; u32 count, i; e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE); if (e) return e; if (!notice || !threeCharCode) return GF_BAD_PARAM; gf_isom_insert_moov(movie); if (!movie->moov->udta) { e = moov_AddBox((GF_Box*)movie->moov, gf_isom_box_new(GF_ISOM_BOX_TYPE_UDTA)); if (e) return e; } map = udta_getEntry(movie->moov->udta, GF_ISOM_BOX_TYPE_CPRT, NULL); if (map) { //try to find one in our language... count = gf_list_count(map->boxList); for (i=0; i<count; i++) { ptr = (GF_CopyrightBox*)gf_list_get(map->boxList, i); if (!strcmp(threeCharCode, (const char *) ptr->packedLanguageCode)) { free(ptr->notice); ptr->notice = (char*)malloc(sizeof(char) * (strlen(notice) + 1)); strcpy(ptr->notice, notice); return GF_OK; } } } //nope, create one ptr = (GF_CopyrightBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_CPRT); memcpy(ptr->packedLanguageCode, threeCharCode, 4); ptr->notice = (char*)malloc(sizeof(char) * (strlen(notice)+1)); strcpy(ptr->notice, notice); return udta_AddBox(movie->moov->udta, (GF_Box *) ptr);}GF_Err gf_isom_add_chapter(GF_ISOFile *movie, u32 trackNumber, u64 timestamp, char *name){ GF_Err e; GF_ChapterListBox *ptr; u32 i, count; GF_ChapterEntry *ce; GF_UserDataBox *udta; GF_UserDataMap *map; e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE); if (e) return e; gf_isom_insert_moov(movie); if (trackNumber) { GF_TrackBox *trak = gf_isom_get_track_from_file(movie, trackNumber); if (!trak) return GF_BAD_PARAM; if (!trak->udta) { e = trak_AddBox((GF_Box*)trak, gf_isom_box_new(GF_ISOM_BOX_TYPE_UDTA)); if (e) return e; } udta = trak->udta; } else { if (!movie->moov->udta) { e = moov_AddBox((GF_Box*)movie->moov, gf_isom_box_new(GF_ISOM_BOX_TYPE_UDTA)); if (e) return e; } udta = movie->moov->udta; } ptr = NULL; map = udta_getEntry(udta, GF_ISOM_BOX_TYPE_CHPL, NULL); if (!map) { ptr = (GF_ChapterListBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_CHPL); e = udta_AddBox(udta, (GF_Box *) ptr); if (e) return e; } else { ptr = (GF_ChapterListBox*)gf_list_get(map->boxList, 0); } /*this may happen if original MP4 is not properly formatted*/ if (!ptr) { ptr = (GF_ChapterListBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_CHPL); gf_list_add(map->boxList, ptr); } GF_SAFEALLOC(ce, GF_ChapterEntry); ce->start_time = timestamp * 10000L; ce->name = name ? strdup(name) : NULL; /*insert in order*/ count = gf_list_count(ptr->list); for (i=0; i<count; i++) { GF_ChapterEntry *ace = (GF_ChapterEntry *)gf_list_get(ptr->list, i); if (ace->start_time == ce->start_time) { if (ace->name) free(ace->name); ace->name = ce->name; free(ce); return GF_OK; } if (ace->start_time >= ce->start_time) return gf_list_insert(ptr->list, ce, i); } return gf_list_add(ptr->list, ce);}GF_Err gf_isom_remove_chapter(GF_ISOFile *movie, u32 trackNumber, u32 index){ GF_Err e; GF_ChapterListBox *ptr; GF_ChapterEntry *ce; GF_UserDataBox *udta; GF_UserDataMap *map; e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE); if (e) return e; gf_isom_insert_moov(movie); if (trackNumber) { GF_TrackBox *trak = gf_isom_get_track_from_file(movie, trackNumber); if (!trak) return GF_BAD_PARAM; if (!trak->udta) { e = trak_AddBox((GF_Box*)trak, gf_isom_box_new(GF_ISOM_BOX_TYPE_UDTA)); if (e) return e; } udta = trak->udta; } else { if (!movie->moov->udta) { e = moov_AddBox((GF_Box*)movie->moov, gf_isom_box_new(GF_ISOM_BOX_TYPE_UDTA)); if (e) return e; } udta = movie->moov->udta; } map = udta_getEntry(udta, GF_ISOM_BOX_TYPE_CHPL, NULL); if (!map) return GF_OK; ptr = (GF_ChapterListBox*)gf_list_get(map->boxList, 0); if (!ptr) return GF_OK; if (index) { ce = (GF_ChapterEntry *)gf_list_get(ptr->list, index-1); if (!ce) return GF_BAD_PARAM; if (ce->name) free(ce->name); free(ce); gf_list_rem(ptr->list, index-1); } else { while (gf_list_count(ptr->list)) { ce = (GF_ChapterEntry *)gf_list_get(ptr->list, 0); if (ce->name) free(ce->name); free(ce); gf_list_rem(ptr->list, 0); } } if (!gf_list_count(ptr->list)) { gf_list_del_item(udta->recordList, map); gf_isom_box_array_del(map->boxList); free(map); } return GF_OK;}GF_Err gf_isom_remove_copyright(GF_ISOFile *movie, u32 index){ GF_Err e; GF_CopyrightBox *ptr; GF_UserDataMap *map; u32 count; e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE); if (e) return e; gf_isom_insert_moov(movie); if (!index) return GF_BAD_PARAM; if (!movie->moov->udta) return GF_OK; map = udta_getEntry(movie->moov->udta, GF_ISOM_BOX_TYPE_CPRT, NULL); if (!map) return GF_OK; count = gf_list_count(map->boxList); if (index>count) return GF_BAD_PARAM; ptr = (GF_CopyrightBox*)gf_list_get(map->boxList, index-1); if (ptr) { gf_list_rem(map->boxList, index-1); if (ptr->notice) free(ptr->notice); free(ptr); } /*last copyright, remove*/ if (!gf_list_count(map->boxList)) { gf_list_del_item(movie->moov->udta->recordList, map); gf_list_del(map->boxList); free(map); } return GF_OK;}GF_Err gf_isom_set_watermark(GF_ISOFile *movie, bin128 UUID, u8* data, u32 length){ GF_Err e; GF_UnknownUUIDBox *ptr; GF_UserDataMap *map; e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE); if (e) return e; gf_isom_insert_moov(movie); if (!movie->moov->udta) { e = moov_AddBox((GF_Box*)movie->moov, gf_isom_box_new(GF_ISOM_BOX_TYPE_UDTA)); if (e) return e; } map = udta_getEntry(movie->moov->udta, GF_ISOM_BOX_TYPE_UUID, (bin128 *) & UUID); if (map) { ptr = (GF_UnknownUUIDBox *)gf_list_get(map->boxList, 0); if (ptr) { free(ptr->data); ptr->data = (char*)malloc(length); memcpy(ptr->data, data, length); ptr->dataSize = length; return GF_OK; } } //nope, create one ptr = (GF_UnknownUUIDBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_UUID); memcpy(ptr->uuid, UUID, 16); ptr->data = (char*)malloc(length); memcpy(ptr->data, data, length); ptr->dataSize = length; return udta_AddBox(movie->moov->udta, (GF_Box *) ptr);}//set the interleaving time of media data (INTERLEAVED mode only)//InterleaveTime is in MovieTimeScaleGF_Err gf_isom_set_interleave_time(GF_ISOFile *movie, u32 InterleaveTime){ GF_Err e; e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE); if (e) return e; if (!InterleaveTime || !movie->moov) return GF_OK; movie->interleavingTime = InterleaveTime; return GF_OK;}u32 gf_isom_get_interleave_time(GF_ISOFile *movie){ return movie ? movie->interleavingTime : 0;}//set the storage mode of a file (FLAT, STREAMABLE, INTERLEAVED)u8 gf_isom_get_storage_mode(GF_ISOFile *movie){ return movie ? movie->storageMode : 0;}//use a compact track version for sample size. This is not usually recommended //except for speech codecs where the track has a lot of small samples//compaction is done automatically while writing based on the track's sample sizes
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -