static GF_Err ShiftOffset(GF_ISOFile *file, GF_List *writers, u64 offset, u8 *converted) { u32 i, j, end; TrackWriter *writer; GF_StscEntry *ent; GF_Box *box; GF_Err result; *converted = 0; if (file->meta) ShiftMetaOffset(file->meta, offset); if (file->moov && file->moov->meta) ShiftMetaOffset(file->moov->meta, offset); i=0; while ((writer = (TrackWriter *)gf_list_enum(writers, &i))) { if (writer->mdia->mediaTrack->meta) ShiftMetaOffset(writer->mdia->mediaTrack->meta, offset); //we have to proceed entry by entry in case a part of the media is not self-contained... for (j=0; j<writer->stsc->nb_entries; j++) { ent = &writer->stsc->entries[j]; if (!Media_IsSelfContained(writer->mdia, ent->sampleDescriptionIndex)) continue; if (writer->stco->type == GF_ISOM_BOX_TYPE_STCO) end = ent->nextChunk ? ent->nextChunk : ((GF_ChunkOffsetBox *)writer->stco)->nb_entries + 1; else end = ent->nextChunk ? ent->nextChunk : ((GF_ChunkLargeOffsetBox *)writer->stco)->nb_entries + 1; box = writer->stco; if ((result = stbl_ShiftOffset(&box, offset, ent->firstChunk, end)) != GF_OK) return result; if (box != writer->stco) { writer->stco = box; *converted = 1; } } } return GF_OK; }
static GF_Err ShiftOffset(GF_ISOFile *file, GF_List *writers, u64 offset) { u32 i, j, k, l, last; TrackWriter *writer; GF_StscEntry *ent; GF_ChunkOffsetBox *stco; GF_ChunkLargeOffsetBox *co64; if (file->meta) ShiftMetaOffset(file->meta, offset); if (file->moov && file->moov->meta) ShiftMetaOffset(file->moov->meta, offset); i=0; while ((writer = (TrackWriter *)gf_list_enum(writers, &i))) { if (writer->mdia->mediaTrack->meta) ShiftMetaOffset(writer->mdia->mediaTrack->meta, offset); //we have to proceed entry by entry in case a part of the media is not self-contained... for (j=0; j<writer->stsc->nb_entries; j++) { ent = &writer->stsc->entries[j]; if (!Media_IsSelfContained(writer->mdia, ent->sampleDescriptionIndex)) continue; //OK, get the chunk(s) number(s) and "shift" its (their) offset(s). if (writer->stco->type == GF_ISOM_BOX_TYPE_STCO) { stco = (GF_ChunkOffsetBox *) writer->stco; //be carefull for the last entry, nextChunk is set to 0 in edit mode... last = ent->nextChunk ? ent->nextChunk : stco->nb_entries + 1; for (k = ent->firstChunk; k < last; k++) { if (stco->offsets[k-1] + offset > 0xFFFFFFFF) { //too bad, rewrite the table.... co64 = (GF_ChunkLargeOffsetBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_CO64); if (!co64) return GF_OUT_OF_MEM; co64->nb_entries = stco->nb_entries; co64->offsets = (u64*)gf_malloc(co64->nb_entries * sizeof(u64)); if (!co64) { gf_isom_box_del((GF_Box *)co64); return GF_OUT_OF_MEM; } //duplicate the table for (l = 0; l < co64->nb_entries; l++) { co64->offsets[l] = (u64) stco->offsets[l]; if (l + 1 == k) co64->offsets[l] += offset; } //and replace our box gf_isom_box_del(writer->stco); writer->stco = (GF_Box *)co64; } else { stco->offsets[k-1] += (u32) offset; } } } else { co64 = (GF_ChunkLargeOffsetBox *) writer->stco; //be carefull for the last entry ... last = ent->nextChunk ? ent->nextChunk : co64->nb_entries + 1; for (k = ent->firstChunk; k < last; k++) { co64->offsets[k-1] += offset; } } } } return GF_OK; }