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

📄 isom_write.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 5 页
字号:
	trak = (GF_TrackBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_TRAK);	if (!trak) {		gf_isom_set_last_error(movie, GF_OUT_OF_MEM);		return 0;	}	tkhd = (GF_TrackHeaderBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_TKHD);	if (!tkhd) {		gf_isom_set_last_error(movie, GF_OUT_OF_MEM);		gf_isom_box_del((GF_Box *)trak);		return 0;	}	now = gf_isom_get_mp4time();	tkhd->creationTime = now;	tkhd->modificationTime = now;	//OK, set up the media trak	e = NewMedia(&mdia, MediaType, TimeScale);	if (e) {		gf_isom_box_del((GF_Box *)mdia);		gf_isom_box_del((GF_Box *)trak);		gf_isom_box_del((GF_Box *)tkhd);		return 0;	}	//OK, add this media to our track	mdia->mediaTrack = trak;	e = trak_AddBox((GF_Box*)trak, (GF_Box *) tkhd); if (e) goto err_exit;	e = trak_AddBox((GF_Box*)trak, (GF_Box *) mdia); if (e) goto err_exit;	tkhd->trackID = trakID;		//some default properties for Audio, Visual or private tracks	if (MediaType == GF_ISOM_MEDIA_VISUAL) {		/*320-240 pix in 16.16*/		tkhd->width = 0x01400000;		tkhd->height = 0x00F00000;	} else if (MediaType == GF_ISOM_MEDIA_AUDIO) {		tkhd->volume = 0x0100;	}	mdia->mediaHeader->creationTime = mdia->mediaHeader->modificationTime = now;	trak->Header->creationTime = trak->Header->modificationTime = now;	//OK, add our trak	e = moov_AddBox((GF_Box*)movie->moov, (GF_Box *)trak); if (e) goto err_exit;	//set the new ID available	if (trakID+1> movie->moov->mvhd->nextTrackID) 		movie->moov->mvhd->nextTrackID = trakID+1;	//and return our track number	return gf_isom_get_track_by_id(movie, trakID);err_exit:	if (tkhd) gf_isom_box_del((GF_Box *)tkhd);	if (trak) gf_isom_box_del((GF_Box *)trak);	if (mdia) gf_isom_box_del((GF_Box *)mdia);	return 0;}//Create a new StreamDescription in the file. The URL and URN are used to describe external mediaGF_EXPORTGF_Err gf_isom_new_mpeg4_description(GF_ISOFile *movie,							   u32 trackNumber, 							   GF_ESD *esd, 							   char *URLname, 							   char *URNname, 							   u32 *outDescriptionIndex){	GF_TrackBox *trak;	GF_Err e;	u32 dataRefIndex;	GF_ESD *new_esd;	GF_TrackReferenceTypeBox *dpnd;	GF_TrackReferenceBox *tref;	e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE);	if (e) return e;		trak = gf_isom_get_track_from_file(movie, trackNumber);	if (!trak || !trak->Media || 		!esd || !esd->decoderConfig || 		!esd->slConfig) return GF_BAD_PARAM;	dpnd = NULL;	tref = NULL;	//get or create the data ref	e = Media_FindDataRef(trak->Media->information->dataInformation->dref, URLname, URNname, &dataRefIndex);	if (e) return e;	if (!dataRefIndex) {		e = Media_CreateDataRef(trak->Media->information->dataInformation->dref, URLname, URNname, &dataRefIndex);		if (e) return e;	}	//duplicate our desc	e = gf_odf_desc_copy((GF_Descriptor *)esd, (GF_Descriptor **)&new_esd);	if (e) return e;;	trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();	e = Track_SetStreamDescriptor(trak, 0, dataRefIndex, new_esd, outDescriptionIndex);	if (e) {		gf_odf_desc_del((GF_Descriptor *)new_esd);		return e;	}	if (new_esd->URLString) {	}	return e;}//Add samples to a track. Use streamDescriptionIndex to specify the desired stream (if several)GF_EXPORTGF_Err gf_isom_add_sample(GF_ISOFile *movie, u32 trackNumber, u32 StreamDescriptionIndex, GF_ISOSample *sample){	GF_Err e;	GF_TrackBox *trak;	GF_SampleEntryBox *entry;	u32 dataRefIndex;	u64 data_offset;	u32 descIndex;	GF_DataEntryURLBox *Dentry;	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;	e = FlushCaptureMode(movie);	if (e) return e;	e = unpack_track(trak);	if (e) return e;	//REWRITE ANY OD STUFF	if (trak->Media->handler->handlerType == GF_ISOM_MEDIA_OD) {		e = Media_ParseODFrame(trak->Media, sample);		if (e) return e;	}	//OK, add the sample	//1- Get the streamDescriptionIndex and dataRefIndex	//not specified, get the latest used...	descIndex = StreamDescriptionIndex;	if (!StreamDescriptionIndex) {		descIndex = trak->Media->information->sampleTable->currentEntryIndex;	}	e = Media_GetSampleDesc(trak->Media, descIndex, &entry, &dataRefIndex);	if (e) return e;	if (!entry || !dataRefIndex) return GF_BAD_PARAM;	//set the current to this one	trak->Media->information->sampleTable->currentEntryIndex = descIndex;	//get this dataRef and return false if not self contained	Dentry = (GF_DataEntryURLBox*)gf_list_get(trak->Media->information->dataInformation->dref->boxList, dataRefIndex - 1);	if (!Dentry || Dentry->flags != 1) return GF_BAD_PARAM;	//Open our data map. We are adding stuff, so use EDIT	e = gf_isom_datamap_open(trak->Media, dataRefIndex, 1);	if (e) return e;	//Get the offset...	data_offset = gf_isom_datamap_get_offset(trak->Media->information->dataHandler);	//add the meta data	e = Media_AddSample(trak->Media, data_offset, sample, descIndex, 0);	if (e) return e;	//add the media data	e = gf_isom_datamap_add_data(trak->Media->information->dataHandler, sample->data, sample->dataLength);	if (e) return e;	trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();	return SetTrackDuration(trak);}GF_Err gf_isom_add_sample_shadow(GF_ISOFile *movie, u32 trackNumber, GF_ISOSample *sample){	GF_Err e;	GF_TrackBox *trak;	GF_ISOSample *prev;	GF_SampleEntryBox *entry;	u32 dataRefIndex;	u64 data_offset;	u32 descIndex;	u32 sampleNum, prevSampleNum;	GF_DataEntryURLBox *Dentry;	Bool offset_times = 0;	e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE);	if (e) return e;	trak = gf_isom_get_track_from_file(movie, trackNumber);	if (!trak || !sample) return GF_BAD_PARAM;	e = FlushCaptureMode(movie);	if (e) return e;	e = unpack_track(trak);	if (e) return e;	/*REWRITE ANY OD STUFF*/	if (trak->Media->handler->handlerType == GF_ISOM_MEDIA_OD) {		e = Media_ParseODFrame(trak->Media, sample);		if (e) return e;	}	e = findEntryForTime(trak->Media->information->sampleTable, sample->DTS, 0, &sampleNum, &prevSampleNum);	if (e) return e;	/*we need the EXACT match*/	if (!sampleNum) return GF_BAD_PARAM;	prev = gf_isom_get_sample_info(movie, trackNumber, sampleNum, &descIndex, NULL);	if (!prev) return gf_isom_last_error(movie);	/*for conformance*/	if (sample->DTS==prev->DTS) offset_times = 1;	gf_isom_sample_del(&prev);	e = Media_GetSampleDesc(trak->Media, descIndex, &entry, &dataRefIndex);	if (e) return e;	if (!entry || !dataRefIndex) return GF_BAD_PARAM;	trak->Media->information->sampleTable->currentEntryIndex = descIndex;	//get this dataRef and return false if not self contained	Dentry = (GF_DataEntryURLBox*)gf_list_get(trak->Media->information->dataInformation->dref->boxList, dataRefIndex - 1);	if (!Dentry || Dentry->flags != 1) return GF_BAD_PARAM;	//Open our data map. We are adding stuff, so use EDIT	e = gf_isom_datamap_open(trak->Media, dataRefIndex, 1);	if (e) return e;	data_offset = gf_isom_datamap_get_offset(trak->Media->information->dataHandler);	if (offset_times) sample->DTS += 1; 	e = Media_AddSample(trak->Media, data_offset, sample, descIndex, sampleNum);	if (offset_times) sample->DTS -= 1; 	if (e) return e;	//add the media data	e = gf_isom_datamap_add_data(trak->Media->information->dataHandler, sample->data, sample->dataLength);	if (e) return e;	//OK, update duration	e = Media_SetDuration(trak);	if (e) return e;	trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();	return SetTrackDuration(trak);}GF_Err gf_isom_append_sample_data(GF_ISOFile *movie, u32 trackNumber, char *data, u32 data_size){	GF_Err e;	GF_TrackBox *trak;	GF_SampleEntryBox *entry;	u32 dataRefIndex;	u32 descIndex;	GF_DataEntryURLBox *Dentry;	if (!data_size) return GF_OK;	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->handler->handlerType == GF_ISOM_MEDIA_OD) return GF_BAD_PARAM;	//OK, add the sample	descIndex = trak->Media->information->sampleTable->currentEntryIndex;	e = Media_GetSampleDesc(trak->Media, descIndex, &entry, &dataRefIndex);	if (e) return e;	if (!entry || !dataRefIndex) return GF_BAD_PARAM;	//get this dataRef and return false if not self contained	Dentry = (GF_DataEntryURLBox*)gf_list_get(trak->Media->information->dataInformation->dref->boxList, dataRefIndex - 1);	if (!Dentry || Dentry->flags != 1) return GF_BAD_PARAM;	//Open our data map. We are adding stuff, so use EDIT	e = gf_isom_datamap_open(trak->Media, dataRefIndex, 1);	if (e) return e;	//add the media data	e = gf_isom_datamap_add_data(trak->Media->information->dataHandler, data, data_size);	if (e) return e;	//update data size	return stbl_SampleSizeAppend(trak->Media->information->sampleTable->SampleSize, data_size);}//Add sample reference to a track. The SampleOffset is the offset of the data in the referenced file//you must have created a StreamDescription with URL or URN specifying your referenced file//the data offset specifies the begining of the chunk//Use streamDescriptionIndex to specify the desired stream (if several)GF_Err gf_isom_add_sample_reference(GF_ISOFile *movie, u32 trackNumber, u32 StreamDescriptionIndex, GF_ISOSample *sample, u64 dataOffset){	GF_TrackBox *trak;	GF_SampleEntryBox *entry;	u32 dataRefIndex;	u32 descIndex;	GF_DataEntryURLBox *Dentry;	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;	e = unpack_track(trak);	if (e) return e;	//OD is not allowed as a data ref	if (trak->Media->handler->handlerType == GF_ISOM_MEDIA_OD) {		return GF_BAD_PARAM;	}	//OK, add the sample	//1- Get the streamDescriptionIndex and dataRefIndex	//not specified, get the latest used...	descIndex = StreamDescriptionIndex;	if (!StreamDescriptionIndex) {		descIndex = trak->Media->information->sampleTable->currentEntryIndex;	}	e = Media_GetSampleDesc(trak->Media, descIndex, &entry, &dataRefIndex);	if (e) return e;	if (!entry || !dataRefIndex) return GF_BAD_PARAM;	//set the current to this one	trak->Media->information->sampleTable->currentEntryIndex = descIndex;	//get this dataRef and return false if self contained	Dentry =(GF_DataEntryURLBox*) gf_list_get(trak->Media->information->dataInformation->dref->boxList, dataRefIndex - 1);	if (Dentry->flags == 1) return GF_BAD_PARAM;	//add the meta data	e = Media_AddSample(trak->Media, dataOffset, sample, descIndex, 0);	if (e) return e;	trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();	//OK, update duration	e = Media_SetDuration(trak);	if (e) return e;	return SetTrackDuration(trak);}//set the duration of the last media sample. If not set, the duration of the last sample is the//duration of the previous one if any, or 1000 (default value).GF_Err gf_isom_set_last_sample_duration(GF_ISOFile *movie, u32 trackNumber, u32 duration){	GF_TrackBox *trak;	GF_SttsEntry *ent;	u64 mdur;	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;	mdur = trak->Media->mediaHeader->duration;	//get the last entry	ent = (GF_SttsEntry*)gf_list_get(trak->Media->information->sampleTable->TimeToSample->entryList, gf_list_count(trak->Media->information->sampleTable->TimeToSample->entryList)-1);	if (!ent) return GF_BAD_PARAM;	mdur -= ent->sampleDelta;	if (duration) {		mdur += duration;		//we only have one sample		if (ent->sampleCount == 1) {			ent->sampleDelta = duration;		} else {			if (ent->sampleDelta == duration) return GF_OK;			ent->sampleCount -= 1;			ent = (GF_SttsEntry*)malloc(sizeof(GF_SttsEntry));			ent->sampleCount = 1;			ent->sampleDelta = duration;			//add this entry			gf_list_add(trak->Media->information->sampleTable->TimeToSample->entryList, ent);			//and update the write cache			trak->Media->information->sampleTable->TimeToSample->w_currentEntry = ent;			trak->Media->information->sampleTable->TimeToSample->w_currentSampleNum = trak->Media->information->sampleTable->SampleSize->sampleCount;		}	}	trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();	trak->Media->mediaHeader->duration = mdur;	return SetTrackDuration(trak);}//update a sample data in the media. Note that the sample MUST existsGF_Err gf_isom_update_sample(GF_ISOFile *movie, u32 trackNumber, u32 sampleNumber, GF_ISOSample *sample, Bool data_only){	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) return GF_BAD_PARAM;	e = unpack_track(trak);	if (e) return e;	//block for hint tracks	if (trak->Media->handler->handlerType == GF_ISOM_MEDIA_HINT) return GF_BAD_PARAM;	//REWRITE ANY OD STUFF	if (trak->Media->handler->handlerType == GF_ISOM_MEDIA_OD) {		e = Media_ParseODFrame(trak->Media, sample);		if (e) return e;	}	//OK, update it	e = Media_UpdateSample(trak->Media, sampleNumber, sample, data_only);	if (e) return e;	trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();	return GF_OK;}//update a sample data in the media. Note that the sample MUST exists,//that sample->data MUST be NULL and sample->dataLength must be NON NULL;GF_Err gf_isom_update_sample_reference(GF_ISOFile *movie, u32 trackNumber, u32 sampleNumber, GF_ISOSample *sample, u64 data_offset){	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) return GF_BAD_PARAM;	//block for hint tracks	if (trak->Media->handler->handlerType == GF_ISOM_MEDIA_HINT) return GF_BAD_PARAM;	if (!sampleNumber || !sample) return GF_BAD_PARAM;	e = unpack_track(trak);	if (e) return e;	//OD is not allowed as a data ref	if (trak->Media->handler->handlerType == GF_ISOM_MEDIA_OD) {		return GF_BAD_PARAM;	}	//OK, update it	e = Media_UpdateSampleReference(trak->Media, sampleNumber, sample, data_offset);	if (e) return e;	trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();	return GF_OK;}

⌨️ 快捷键说明

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