📄 isom_write.c
字号:
GF_Err gf_isom_use_compact_size(GF_ISOFile *movie, u32 trackNumber, u8 CompactionOn){ GF_TrackBox *trak; u32 i, size; GF_SampleSizeBox *stsz; GF_Err e; e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE); if (e) return e; trak = gf_isom_get_track_from_file(movie, trackNumber); if (!trak) return GF_BAD_PARAM; if (!trak->Media || !trak->Media->information || !trak->Media->information->sampleTable || !trak->Media->information->sampleTable->SampleSize) return GF_ISOM_INVALID_FILE; stsz = trak->Media->information->sampleTable->SampleSize; //switch to regular table if (!CompactionOn) { if (stsz->type == GF_ISOM_BOX_TYPE_STSZ) return GF_OK; stsz->type = GF_ISOM_BOX_TYPE_STSZ; //invalidate the sampleSize and recompute it stsz->sampleSize = 0; if (!stsz->sampleCount) return GF_OK; //if the table is empty we can only assume the track is empty (no size indication) if (!stsz->sizes) return GF_OK; size = stsz->sizes[0]; //check whether the sizes are all the same or not for (i=1; i<stsz->sampleCount; i++) { if (size != stsz->sizes[i]) { size = 0; break; } } if (size) { free(stsz->sizes); stsz->sizes = NULL; stsz->sampleSize = size; } return GF_OK; } //switch to compact table if (stsz->type == GF_ISOM_BOX_TYPE_STZ2) return GF_OK; //fill the table. Although it seems weird , this is needed in case of edition //after the function is called. NOte however than we force regular table //at write time if all samples are of same size if (stsz->sampleSize) { //this is a weird table indeed ;) if (stsz->sizes) free(stsz->sizes); stsz->sizes = (u32*) malloc(sizeof(u32)*stsz->sampleCount); memset(stsz->sizes, stsz->sampleSize, sizeof(u32)); } //set the SampleSize to 0 while the file is open stsz->sampleSize = 0; stsz->type = GF_ISOM_BOX_TYPE_STZ2; return GF_OK;}GF_Err gf_isom_set_brand_info(GF_ISOFile *movie, u32 MajorBrand, u32 MinorVersion){ u32 i, *p; GF_Err e; if (!MajorBrand) return GF_BAD_PARAM; e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE); if (e) return e; e = CheckNoData(movie); if (e) return e; if (!movie->brand) { movie->brand = (GF_FileTypeBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_FTYP); gf_list_add(movie->TopBoxes, movie->brand); } movie->brand->majorBrand = MajorBrand; movie->brand->minorVersion = MinorVersion; if (!movie->brand->altBrand) { movie->brand->altBrand = (u32*)malloc(sizeof(u32)); movie->brand->altBrand[0] = MajorBrand; movie->brand->altCount = 1; return GF_OK; } //if brand already present don't change anything for (i=0; i<movie->brand->altCount; i++) { if (movie->brand->altBrand[i] == MajorBrand) return GF_OK; } p = (u32*)malloc(sizeof(u32)*(movie->brand->altCount + 1)); if (!p) return GF_OUT_OF_MEM; memcpy(p, movie->brand->altBrand, sizeof(u32)*movie->brand->altCount); p[movie->brand->altCount] = MajorBrand; movie->brand->altCount += 1; free(movie->brand->altBrand); movie->brand->altBrand = p; return GF_OK;}GF_Err gf_isom_modify_alternate_brand(GF_ISOFile *movie, u32 Brand, u8 AddIt){ u32 i, k, *p; GF_Err e; e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE); if (e) return e; if (!Brand) return GF_BAD_PARAM; e = CheckNoData(movie); if (e) return e; if (!movie->brand && AddIt) { movie->brand = (GF_FileTypeBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_FTYP); gf_list_add(movie->TopBoxes, movie->brand); } //do not mofify major one if (!AddIt && movie->brand->majorBrand == Brand) return GF_OK; if (!AddIt && movie->brand->altCount == 1) { //fixes it in case movie->brand->altBrand[0] = movie->brand->majorBrand; return GF_OK; } //check for the brand for (i=0; i<movie->brand->altCount; i++) { if (movie->brand->altBrand[i] == Brand) goto found; } //Not found if (!AddIt) return GF_OK; //add it p = (u32*)malloc(sizeof(u32)*(movie->brand->altCount + 1)); if (!p) return GF_OUT_OF_MEM; memcpy(p, movie->brand->altBrand, sizeof(u32)*movie->brand->altCount); p[movie->brand->altCount] = Brand; movie->brand->altCount += 1; free(movie->brand->altBrand); movie->brand->altBrand = p; return GF_OK;found: //found if (AddIt) return GF_OK; assert(movie->brand->altCount>1); //remove it p = (u32*)malloc(sizeof(u32)*(movie->brand->altCount - 1)); if (!p) return GF_OUT_OF_MEM; k = 0; for (i=0; i<movie->brand->altCount; i++) { if (movie->brand->altBrand[i] == Brand) continue; else { p[k] = movie->brand->altBrand[i]; k++; } } movie->brand->altCount -= 1; free(movie->brand->altBrand); movie->brand->altBrand = p; return GF_OK;}GF_Err gf_isom_set_sample_padding_bits(GF_ISOFile *movie, u32 trackNumber, u32 sampleNumber, u8 NbBits){ GF_TrackBox *trak; GF_Err e; e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE); if (e) return e; trak = gf_isom_get_track_from_file(movie, trackNumber); if (!trak || NbBits > 7) return GF_BAD_PARAM; //set Padding info return stbl_SetPaddingBits(trak->Media->information->sampleTable, sampleNumber, NbBits);}GF_Err gf_isom_remove_user_data_item(GF_ISOFile *movie, u32 trackNumber, u32 UserDataType, bin128 UUID, u32 UserDataIndex){ GF_UserDataMap *map; GF_Box *a; u32 i; bin128 t; GF_Err e; GF_TrackBox *trak; GF_UserDataBox *udta; e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE); if (e) return e; if (UserDataType == GF_ISOM_BOX_TYPE_UUID) UserDataType = 0; memset(t, 1, 16); if (trackNumber) { trak = gf_isom_get_track_from_file(movie, trackNumber); if (!trak) return GF_BAD_PARAM; udta = trak->udta; } else { udta = movie->moov->udta; } if (!udta) return GF_BAD_PARAM; if (!UserDataIndex) return GF_BAD_PARAM; i=0; while ((map = (GF_UserDataMap*)gf_list_enum(udta->recordList, &i))) { if ((map->boxType == GF_ISOM_BOX_TYPE_UUID) && !memcmp(map->uuid, UUID, 16)) goto found; else if (map->boxType == UserDataType) goto found; } //not found return GF_OK;found: if (UserDataIndex > gf_list_count(map->boxList) ) return GF_BAD_PARAM; //delete the box a = (GF_Box*)gf_list_get(map->boxList, UserDataIndex-1); gf_list_rem(map->boxList, UserDataIndex-1); gf_isom_box_del(a); //remove the map if empty if (!gf_list_count(map->boxList)) { gf_list_rem(udta->recordList, i-1); gf_isom_box_array_del(map->boxList); free(map); } //but we keep the UDTA no matter what return GF_OK;}GF_Err gf_isom_remove_user_data(GF_ISOFile *movie, u32 trackNumber, u32 UserDataType, bin128 UUID){ GF_UserDataMap *map; u32 i; GF_Err e; bin128 t; GF_TrackBox *trak; GF_UserDataBox *udta; e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE); if (e) return e; if (UserDataType == GF_ISOM_BOX_TYPE_UUID) UserDataType = 0; memset(t, 1, 16); if (trackNumber) { trak = gf_isom_get_track_from_file(movie, trackNumber); if (!trak) return GF_BAD_PARAM; udta = trak->udta; } else { udta = movie->moov->udta; } if (!udta) return GF_BAD_PARAM; i=0; while ((map = (GF_UserDataMap*)gf_list_enum(udta->recordList, &i))) { if ((map->boxType == GF_ISOM_BOX_TYPE_UUID) && !memcmp(map->uuid, UUID, 16)) goto found; else if (map->boxType == UserDataType) goto found; } //not found return GF_OK;found: gf_list_rem(udta->recordList, i-1); gf_isom_box_array_del(map->boxList); free(map); //but we keep the UDTA no matter what return GF_OK;}GF_Err gf_isom_add_user_data(GF_ISOFile *movie, u32 trackNumber, u32 UserDataType, bin128 UUID, char *data, u32 DataLength){ GF_UnknownBox *a; GF_Err e; GF_TrackBox *trak; GF_UserDataBox *udta; e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE); if (e) return e; if (UserDataType == GF_ISOM_BOX_TYPE_UUID) UserDataType = 0; if (trackNumber) { trak = gf_isom_get_track_from_file(movie, trackNumber); if (!trak) return GF_BAD_PARAM; if (!trak->udta) trak_AddBox((GF_Box*)trak, gf_isom_box_new(GF_ISOM_BOX_TYPE_UDTA)); udta = trak->udta; } else { if (!movie->moov->udta) moov_AddBox((GF_Box*)movie->moov, gf_isom_box_new(GF_ISOM_BOX_TYPE_UDTA)); udta = movie->moov->udta; } if (!udta) return GF_OUT_OF_MEM; //create a default box if (UserDataType) { a = (GF_UnknownBox *) gf_isom_box_new(UserDataType); } else { a = (GF_UnknownBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_UUID); memcpy( ((GF_UUIDBox*)a)->uuid, UUID, 16); } a->data = (char*)malloc(sizeof(char)*DataLength); memcpy(a->data, data, DataLength); a->dataSize = DataLength; return udta_AddBox(udta, (GF_Box *) a);}GF_Err gf_isom_add_sample_fragment(GF_ISOFile *movie, u32 trackNumber, u32 sampleNumber, u16 FragmentSize){ GF_Err e; GF_TrackBox *trak; e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE); if (e) return e; trak = gf_isom_get_track_from_file(movie, trackNumber); if (!trak || !sampleNumber || !FragmentSize) return GF_BAD_PARAM; //set Padding info return stbl_AddSampleFragment(trak->Media->information->sampleTable, sampleNumber, FragmentSize);}GF_Err gf_isom_remove_sample_fragment(GF_ISOFile *movie, u32 trackNumber, u32 sampleNumber){ GF_TrackBox *trak; GF_Err e; e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE); if (e) return e; trak = gf_isom_get_track_from_file(movie, trackNumber); if (!trak) return GF_BAD_PARAM; return stbl_RemoveSampleFragments(trak->Media->information->sampleTable, sampleNumber);}GF_Err gf_isom_remove_sample_fragments(GF_ISOFile *movie, u32 trackNumber){ GF_TrackBox *trak; GF_Err e; e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE); if (e) return e; trak = gf_isom_get_track_from_file(movie, trackNumber); if (!trak) return GF_BAD_PARAM; if (trak->Media->information->sampleTable->Fragments) { gf_isom_box_del((GF_Box *)trak->Media->information->sampleTable->Fragments); trak->Media->information->sampleTable->Fragments = NULL; } return GF_OK;}GF_Err gf_isom_clone_pl_indications(GF_ISOFile *orig, GF_ISOFile *dest){ GF_IsomInitialObjectDescriptor *iod_d; if (!orig || !dest) return GF_BAD_PARAM; if (!orig->moov->iods || !orig->moov->iods->descriptor) return GF_OK; if (orig->moov->iods->descriptor->tag != GF_ODF_ISOM_IOD_TAG) return GF_OK; AddMovieIOD(dest->moov, 1); gf_odf_desc_del((GF_Descriptor *)dest->moov->iods->descriptor); gf_odf_desc_copy((GF_Descriptor *)orig->moov->iods->descriptor, (GF_Descriptor **)&dest->moov->iods->descriptor); iod_d = (GF_IsomInitialObjectDescriptor *) dest->moov->iods->descriptor; while (gf_list_count(iod_d->ES_ID_IncDescriptors)) { GF_Descriptor *d = (GF_Descriptor *)gf_list_get(iod_d->ES_ID_IncDescriptors, 0); gf_list_rem(iod_d->ES_ID_IncDescriptors, 0); gf_odf_desc_del(d); } while (gf_list_count(iod_d->ES_ID_RefDescriptors)) { GF_Descriptor *d = (GF_Descriptor *)gf_list_get(iod_d->ES_ID_RefDescriptors, 0); gf_list_rem(iod_d->ES_ID_RefDescriptors, 0); gf_odf_desc_del(d); } return GF_OK;}GF_Err gf_isom_clone_track(GF_ISOFile *orig_file, u32 orig_track, GF_ISOFile *dest_file, Bool keep_data_ref, u32 *dest_track){ GF_TrackBox *trak, *new_tk; GF_BitStream *bs; char *data; u32 data_size; Double ts_scale; GF_Err e; GF_SampleEntryBox *entry; GF_SampleTableBox *stbl, *stbl_temp; e = CanAccessMovie(dest_file, GF_ISOM_OPEN_WRITE); if (e) return e; gf_isom_insert_moov(dest_file); /*get orig sample desc and clone it*/ trak = gf_isom_get_track_from_file(orig_file, orig_track); if (!trak || !trak->Media) return GF_BAD_PARAM; stbl = trak->Media->information->sampleTable; stbl_temp = (GF_SampleTableBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_STBL); stbl_temp->SampleDescription = stbl->SampleDescription; trak->Media->information->sampleTable = stbl_temp; bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); gf_isom_box_size( (GF_Box *) trak); gf_isom_box_write((GF_Box *) trak, bs); gf_bs_get_content(bs, &data, &data_size); gf_bs_del(bs); bs = gf_bs_new(data, data_size, GF_BITSTREAM_READ); e = gf_isom_parse_box((GF_Box **) &new_tk, bs); gf_bs_del(bs); free(data); trak->Media->information->sampleTable = stbl; stbl_temp->SampleDescription = NULL; gf_isom_box_del((GF_Box *)stbl_temp); if (e) return e; /*create default boxes*/ stbl = new_tk->Media->information->sampleTable; stbl->ChunkOffset = gf_isom_box_new(GF_ISOM_BOX_TYPE_STCO); stbl->SampleSize = (GF_SampleSizeBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_STSZ); stbl->SampleToChunk = (GF_SampleToChunkBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_STSC); stbl->TimeToSample = (GF_TimeToSampleBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_STTS); /*check trackID validity before adding track*/ if (gf_isom_get_track_by_id(dest_file, new_tk->Header->trackID)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -