⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 isom_write.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 5 页
字号:
//Remove a given sampleGF_Err gf_isom_remove_sample(GF_ISOFile *movie, u32 trackNumber, u32 sampleNumber){	GF_Err e;	GF_TrackBox *trak;	e = CanAccessMovie(movie, GF_ISOM_OPEN_EDIT);	if (e) return e;	trak = gf_isom_get_track_from_file(movie, trackNumber);	if (!trak || !sampleNumber || (sampleNumber > trak->Media->information->sampleTable->SampleSize->sampleCount) )		return GF_BAD_PARAM;	//block for hint tracks	if (trak->Media->handler->handlerType == GF_ISOM_MEDIA_HINT) return GF_BAD_PARAM;	//remove DTS	e = stbl_RemoveDTS(trak->Media->information->sampleTable, sampleNumber, trak->Media->mediaHeader->timeScale);	if (e) return e;	//remove CTS if any	if (trak->Media->information->sampleTable->CompositionOffset) {		e = stbl_RemoveCTS(trak->Media->information->sampleTable, sampleNumber);		if (e) return e;	}	//remove size	e = stbl_RemoveSize(trak->Media->information->sampleTable->SampleSize, sampleNumber);	if (e) return e;	//remove sampleToChunk and chunk	e = stbl_RemoveChunk(trak->Media->information->sampleTable, sampleNumber);	if (e) return e;	//remove sync	if (trak->Media->information->sampleTable->SyncSample) {		e = stbl_RemoveRAP(trak->Media->information->sampleTable, sampleNumber);		if (e) return e;	}	//remove sample dep	if (trak->Media->information->sampleTable->SampleDep) {		e = stbl_RemoveRedundant(trak->Media->information->sampleTable, sampleNumber);		if (e) return e;	}	//remove shadow	if (trak->Media->information->sampleTable->ShadowSync) {		e = stbl_RemoveShadow(trak->Media->information->sampleTable->ShadowSync, sampleNumber);		if (e) return e;	}	//remove padding	e = stbl_RemovePaddingBits(trak->Media->information->sampleTable, sampleNumber);	if (e) return e;		return SetTrackDuration(trak);}GF_Err gf_isom_set_final_name(GF_ISOFile *movie, char *filename){	GF_Err e;	if (!movie ) return GF_BAD_PARAM;	//if mode is not OPEN_EDIT file was created under the right name	e = CanAccessMovie(movie, GF_ISOM_OPEN_EDIT);	if (e) return e;	if (filename) {		//we don't allow file overwriting		if ( (movie->openMode == GF_ISOM_OPEN_EDIT) 			&& movie->fileName && !strcmp(filename, movie->fileName))			return GF_BAD_PARAM;		if (movie->finalName) free(movie->finalName);		movie->finalName = strdup(filename);		if (!movie->finalName) return GF_OUT_OF_MEM;	}	return GF_OK;}//Add a system descriptor to the ESD of a stream(EDIT or WRITE mode only)GF_Err gf_isom_add_desc_to_description(GF_ISOFile *movie, u32 trackNumber, u32 StreamDescriptionIndex, GF_Descriptor *theDesc){	GF_IPIPtr *ipiD;	GF_Err e;	u16 tmpRef;	GF_TrackBox *trak;	GF_Descriptor *desc;	GF_ESD *esd;	GF_TrackReferenceBox *tref;	GF_TrackReferenceTypeBox *dpnd;		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;	/*GETS NATIVE DESCRIPTOR ONLY*/	e = Media_GetESD(trak->Media, StreamDescriptionIndex, &esd, 1);	if (e) return e;	//duplicate the desc	e = gf_odf_desc_copy(theDesc, &desc);	if (e) return e;	//and add it to the ESD EXCEPT IPI PTR (we need to translate from ES_ID to TrackID!!!	trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();	switch (desc->tag) {	case GF_ODF_IPI_PTR_TAG:		goto insertIPI;		default:		return gf_odf_desc_add_desc((GF_Descriptor *)esd, desc);	}	insertIPI:	if (esd->ipiPtr) {		gf_odf_desc_del((GF_Descriptor *) esd->ipiPtr);		esd->ipiPtr = NULL;	}	ipiD = (GF_IPIPtr *) desc;		//find a tref	if (!trak->References) {		tref = (GF_TrackReferenceBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_TREF);		e = trak_AddBox((GF_Box*)trak, (GF_Box *)tref);		if (e) return e;	}	tref = trak->References;	e = Track_FindRef(trak, GF_ISOM_REF_IPI, &dpnd);	if (e) return e;	if (!dpnd) {		tmpRef = 0;		dpnd = (GF_TrackReferenceTypeBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_IPIR);		e = tref_AddBox((GF_Box*)tref, (GF_Box *) dpnd);		if (e) return e;		e = reftype_AddRefTrack(dpnd, ipiD->IPI_ES_Id, &tmpRef);		if (e) return e;		//and replace the tag and value...		ipiD->IPI_ES_Id = tmpRef;		ipiD->tag = GF_ODF_ISOM_IPI_PTR_TAG;	} else {		//Watch out! ONLY ONE IPI dependancy is allowed per stream		dpnd->trackIDCount = 1;		dpnd->trackIDs[0] = ipiD->IPI_ES_Id;		//and replace the tag and value...		ipiD->IPI_ES_Id = 1;		ipiD->tag = GF_ODF_ISOM_IPI_PTR_TAG;	}	//and add the desc to the esd...	return gf_odf_desc_add_desc((GF_Descriptor *)esd, desc);}//use carefully. Very usefull when you made a lot of changes (IPMP, IPI, OCI, ...)//THIS WILL REPLACE THE WHOLE DESCRIPTOR ...GF_Err gf_isom_change_mpeg4_description(GF_ISOFile *movie, u32 trackNumber, u32 StreamDescriptionIndex, GF_ESD *newESD){	GF_Err e;	GF_ESD *esd;	GF_TrackBox *trak;	GF_SampleEntryBox *entry;	GF_SampleDescriptionBox *stsd;	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;	stsd = trak->Media->information->sampleTable->SampleDescription;	if (!stsd) return movie->LastError = GF_ISOM_INVALID_FILE;	if (!StreamDescriptionIndex || StreamDescriptionIndex > gf_list_count(stsd->boxList)) {		return movie->LastError = GF_BAD_PARAM;	}	entry = (GF_SampleEntryBox *)gf_list_get(stsd->boxList, StreamDescriptionIndex - 1);	//no support for generic sample entries (eg, no MPEG4 descriptor)	if (entry == NULL) return GF_BAD_PARAM;	trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();	//duplicate our desc	e = gf_odf_desc_copy((GF_Descriptor *)newESD, (GF_Descriptor **)&esd);	if (e) return e;	return Track_SetStreamDescriptor(trak, StreamDescriptionIndex, entry->dataReferenceIndex, esd, NULL);}GF_Err gf_isom_set_visual_info(GF_ISOFile *movie, u32 trackNumber, u32 StreamDescriptionIndex, u32 Width, u32 Height){	GF_Err e;	GF_TrackBox *trak;	GF_SampleEntryBox *entry;	GF_SampleDescriptionBox *stsd;	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;	stsd = trak->Media->information->sampleTable->SampleDescription;	if (!stsd) {		return movie->LastError = GF_ISOM_INVALID_FILE;	}	if (!StreamDescriptionIndex || StreamDescriptionIndex > gf_list_count(stsd->boxList)) {		return movie->LastError = GF_BAD_PARAM;	}	entry = (GF_SampleEntryBox *)gf_list_get(stsd->boxList, StreamDescriptionIndex - 1);	//no support for generic sample entries (eg, no MPEG4 descriptor)	if (entry == NULL) return GF_BAD_PARAM;	trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();	//valid for MPEG visual, JPG and 3GPP H263	switch (entry->type) {	case GF_ISOM_BOX_TYPE_MP4V:	case GF_ISOM_SUBTYPE_3GP_H263:	case GF_ISOM_BOX_TYPE_AVC1:		((GF_VisualSampleEntryBox*)entry)->Width = Width;		((GF_VisualSampleEntryBox*)entry)->Height = Height;		trak->Header->width = Width<<16;		trak->Header->height = Height<<16;		return GF_OK;	/*check BIFS*/	default:		if (trak->Media->handler->handlerType==GF_ISOM_MEDIA_SCENE) {			trak->Header->width = Width<<16;			trak->Header->height = Height<<16;			return GF_OK;		}		return GF_BAD_PARAM;	}}GF_Err gf_isom_set_audio_info(GF_ISOFile *movie, u32 trackNumber, u32 StreamDescriptionIndex, u32 sampleRate, u32 nbChannels, u8 bitsPerSample){	GF_Err e;	GF_TrackBox *trak;	GF_SampleEntryBox *entry;	GF_SampleDescriptionBox *stsd;	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;	stsd = trak->Media->information->sampleTable->SampleDescription;	if (!stsd) {		return movie->LastError = GF_ISOM_INVALID_FILE;	}	if (!StreamDescriptionIndex || StreamDescriptionIndex > gf_list_count(stsd->boxList)) {		return movie->LastError = GF_BAD_PARAM;	}	entry = (GF_SampleEntryBox *)gf_list_get(stsd->boxList, StreamDescriptionIndex - 1);	//no support for generic sample entries (eg, no MPEG4 descriptor)	if (entry == NULL) return GF_BAD_PARAM;	trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();	switch (entry->type) {	case GF_ISOM_BOX_TYPE_MP4A:	case GF_ISOM_SUBTYPE_3GP_AMR:	case GF_ISOM_SUBTYPE_3GP_AMR_WB:	case GF_ISOM_SUBTYPE_3GP_EVRC:	case GF_ISOM_SUBTYPE_3GP_QCELP:	case GF_ISOM_SUBTYPE_3GP_SMV:		((GF_AudioSampleEntryBox*)entry)->samplerate_hi = sampleRate;		((GF_AudioSampleEntryBox*)entry)->samplerate_lo = 0;		((GF_AudioSampleEntryBox*)entry)->channel_count = nbChannels;		((GF_AudioSampleEntryBox*)entry)->bitspersample = bitsPerSample;		return GF_OK;	/*check BIFS*/	default:		return GF_BAD_PARAM;	}}//set the storage mode of a file (FLAT, STREAMABLE, INTERLEAVED)GF_Err gf_isom_set_storage_mode(GF_ISOFile *movie, u8 storageMode){	GF_Err e;	e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE);	if (e) return e;	switch (storageMode) {	case GF_ISOM_STORE_FLAT:	case GF_ISOM_STORE_STREAMABLE:	case GF_ISOM_STORE_INTERLEAVED:	case GF_ISOM_STORE_DRIFT_INTERLEAVED:	case GF_ISOM_STORE_TIGHT:		movie->storageMode = storageMode;		return GF_OK;	default:		return GF_BAD_PARAM;	}}//update or insert a new edit segment in the track time line. Edits are used to modify//the media normal timing. EditTime and EditDuration are expressed in Movie TimeScale//If a segment with EditTime already exists, IT IS ERASEDGF_Err gf_isom_set_edit_segment(GF_ISOFile *movie, u32 trackNumber, u64 EditTime, u64 EditDuration, u64 MediaTime, u8 EditMode){	GF_TrackBox *trak;	GF_EditBox *edts;	GF_EditListBox *elst;	GF_EdtsEntry *ent, *newEnt;	u32 i;	GF_Err e;	u64 startTime;	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;	edts = trak->editBox;	if (! edts) {		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);	}	elst = edts->editList;	if (!elst) {		elst = (GF_EditListBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_ELST);		if (!elst) return GF_OUT_OF_MEM;		edts_AddBox((GF_Box*)edts, (GF_Box *)elst);	}	startTime = 0;	ent = NULL;	//get the prev entry to this startTime if any	i=0;	while ((ent = (GF_EdtsEntry *)gf_list_enum(elst->entryList, &i))) {		if ( (startTime <= EditTime) && (startTime + ent->segmentDuration > EditTime) ) 			goto found;		startTime += ent->segmentDuration;	}	//not found, add a new entry and adjust the prev one if any	if (!ent) {		newEnt = CreateEditEntry(EditDuration, MediaTime, EditMode);		if (!newEnt) return GF_OUT_OF_MEM;		gf_list_add(elst->entryList, newEnt);		return SetTrackDuration(trak);	}		startTime -= ent->segmentDuration;found:		//if same time, we erase the current one...	if (startTime == EditTime) {		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);	}	//adjust so that the prev ent leads to EntryTime	//Note: we don't change the next one as it is unknown to us in	//a lot of case (the author's changes)	ent->segmentDuration = EditTime - startTime;	newEnt = CreateEditEntry(EditDuration, MediaTime, EditMode);	if (!newEnt) return GF_OUT_OF_MEM;	//is it the last entry ???	if (i >= gf_list_count(elst->entryList) - 1) {		//add the new entry at the end		gf_list_add(elst->entryList, newEnt);		return SetTrackDuration(trak);	} else {		//insert after the current entry (which is i)		gf_list_insert(elst->entryList, newEnt, i+1);		return SetTrackDuration(trak);	}}//remove the edit segments for the whole trackGF_Err gf_isom_remove_edit_segments(GF_ISOFile *movie, u32 trackNumber){	GF_Err e;	GF_TrackBox *trak;	GF_EdtsEntry *ent;	trak = gf_isom_get_track_from_file(movie, trackNumber);	if (!trak) return GF_BAD_PARAM;	e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE);	if (e) return e;	if (!trak->editBox || !trak->editBox->editList) return GF_OK;	while (gf_list_count(trak->editBox->editList->entryList)) {		ent = (GF_EdtsEntry*)gf_list_get(trak->editBox->editList->entryList, 0);		free(ent);		e = gf_list_rem(trak->editBox->editList->entryList, 0);		if (e) return e;	}	//then delete the GF_EditBox...	gf_isom_box_del((GF_Box *)trak->editBox);	trak->editBox = NULL;	return SetTrackDuration(trak);}//remove the edit segments for the whole trackGF_Err gf_isom_remove_edit_segment(GF_ISOFile *movie, u32 trackNumber, u32 seg_index){	GF_Err e;	GF_TrackBox *trak;	GF_EdtsEntry *ent, *next_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)<=1) return gf_isom_remove_edit_segments(movie, trackNumber);	ent = (GF_EdtsEntry*) gf_list_get(trak->editBox->editList->entryList, seg_index-1);	gf_list_rem(trak->editBox->editList->entryList, seg_index-1);	next_ent = (GF_EdtsEntry *)gf_list_get(trak->editBox->editList->entryList, seg_index-1);	if (next_ent) next_ent->segmentDuration += ent->segmentDuration;	free(ent);	return SetTrackDuration(trak);}GF_Err gf_isom_append_edit_segment(GF_ISOFile *movie, u32 trackNumber, 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) return GF_BAD_PARAM;	e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE);	if (e) return e;	if (!trak->editBox) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -