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

📄 media.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (a->flags & 1) return 1;	/*QT specific*/	if (a->type == GF_4CC('a', 'l', 'i', 's')) return 1;	return 0;}//look for a sync sample from a given point in media timeGF_Err Media_FindSyncSample(GF_SampleTableBox *stbl, u32 searchFromSample, u32 *sampleNumber, u8 mode){	u8 isRAP;	u32 next, prev;	if (!stbl || !stbl->SyncSample) return GF_BAD_PARAM;	//set to current sample if we don't find a RAP			*sampleNumber = searchFromSample;	//this is not the exact sample, but the prev move to next sample if enough samples....	if ( (mode == GF_ISOM_SEARCH_SYNC_FORWARD) && (searchFromSample == stbl->SampleSize->sampleCount) ) {		return GF_OK;	}	if ( (mode == GF_ISOM_SEARCH_SYNC_BACKWARD) && !searchFromSample) {		*sampleNumber = 1;		return GF_OK;	}	//get the entry	stbl_GetSampleRAP(stbl->SyncSample, searchFromSample, &isRAP, &prev, &next);	if (isRAP) {		(*sampleNumber) = searchFromSample;		return GF_OK;	}	//nothing yet, go for next time...	if (mode == GF_ISOM_SEARCH_SYNC_FORWARD) {		if (next) *sampleNumber = next;	} else {		if (prev) *sampleNumber = prev;	}	return GF_OK;}//create a DataReference if not existing (only for WRITE-edit mode)GF_Err Media_FindDataRef(GF_DataReferenceBox *dref, char *URLname, char *URNname, u32 *dataRefIndex){	u32 i;	GF_DataEntryURLBox *entry;	if (!dref) return GF_BAD_PARAM;	*dataRefIndex = 0;	i=0;	while ((entry = (GF_DataEntryURLBox*)gf_list_enum(dref->boxList, &i))) {		if (entry->type == GF_ISOM_BOX_TYPE_URL) {			//self-contained case			if (entry->flags == 1) {				//if nothing specified, get the dataRef				if (!URLname && !URNname) {					*dataRefIndex = i;					return GF_OK;				}			} else {				//OK, check if we have URL				if (URLname && !strcmp(URLname, entry->location)) {					*dataRefIndex = i;					return GF_OK;				}			}		} else {			//this is a URN one, only check the URN name (URL optional)			if (URNname && !strcmp(URNname, ((GF_DataEntryURNBox *)entry)->nameURN)) {				*dataRefIndex = i;				return GF_OK;			}		}	}	return GF_OK;}//Get the total media duration based on the TimeToSample tableGF_Err Media_SetDuration(GF_TrackBox *trak){	GF_ESD *esd;	u64 DTS;	GF_SttsEntry *ent;	u32 nbSamp = trak->Media->information->sampleTable->SampleSize->sampleCount;	//we need to check how many samples we have. 	// == 1 -> last sample duration == default duration	// > 1 -> last sample duration == prev sample duration	switch (nbSamp) {	case 0:		trak->Media->mediaHeader->duration = 0;		if (Track_IsMPEG4Stream(trak->Media->handler->handlerType)) {			Media_GetESD(trak->Media, 1, &esd, 1);			if (esd && esd->URLString) trak->Media->mediaHeader->duration = (u64) -1;		}		return GF_OK;//	case 1://		trak->Media->mediaHeader->duration = trak->Media->mediaHeader->timeScale;//		return GF_OK;	default:		//we assume a constant frame rate for the media and assume the last sample		//will be hold the same time as the prev one		stbl_GetSampleDTS(trak->Media->information->sampleTable->TimeToSample, nbSamp, &DTS);		ent = (GF_SttsEntry*)gf_list_last(trak->Media->information->sampleTable->TimeToSample->entryList);		trak->Media->mediaHeader->duration = DTS;#if 1		trak->Media->mediaHeader->duration += ent->sampleDelta;#else		if (!ent) {			u64 DTSprev;			stbl_GetSampleDTS(trak->Media->information->sampleTable->TimeToSample, nbSamp-1, &DTSprev);			trak->Media->mediaHeader->duration += (DTS - DTSprev);		} else {#ifndef GPAC_READ_ONLY			if (trak->moov->mov->editFileMap && trak->Media->information->sampleTable->CompositionOffset) {				u32 count, i;				u64 max_ts;				GF_DttsEntry *cts_ent;				GF_CompositionOffsetBox *ctts = trak->Media->information->sampleTable->CompositionOffset;				if (ctts->w_LastSampleNumber==nbSamp) {					count = gf_list_count(ctts->entryList);					max_ts = trak->Media->mediaHeader->duration;					while (count) {						count -= 1;						cts_ent = gf_list_get(ctts->entryList, count);						if (nbSamp<cts_ent->sampleCount) break;						for (i=0; i<cts_ent->sampleCount; i++) {							stbl_GetSampleDTS(trak->Media->information->sampleTable->TimeToSample, nbSamp-i, &DTS);							if ((s32) cts_ent->decodingOffset < 0) max_ts = DTS;							else max_ts = DTS + cts_ent->decodingOffset;							if (max_ts>=trak->Media->mediaHeader->duration) {								trak->Media->mediaHeader->duration = max_ts;							} else {								break;							}						}						if (max_ts<trak->Media->mediaHeader->duration) {							break;						}						nbSamp-=cts_ent->sampleCount;					}				}			}#endif			trak->Media->mediaHeader->duration += ent->sampleDelta;		}#endif		return GF_OK;	}}#ifndef GPAC_READ_ONLY	GF_Err Media_CreateDataRef(GF_DataReferenceBox *dref, char *URLname, char *URNname, u32 *dataRefIndex){		GF_Err e;	GF_DataEntryURLBox *entry;	GF_Err dref_AddDataEntry(GF_DataReferenceBox *ptr, GF_Box *entry);	if (!URLname && !URNname) {		//THIS IS SELF CONTAIN, create a regular entry if needed		entry = (GF_DataEntryURLBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_URL);		entry->location = NULL;		entry->flags = 0;		entry->flags |= 1;		e = dref_AddDataEntry(dref, (GF_Box *)entry);		if (e) return e;		*dataRefIndex = gf_list_count(dref->boxList);		return GF_OK;	} else if (!URNname && URLname) {		//THIS IS URL		entry = (GF_DataEntryURLBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_URL);		entry->flags = 0;		entry->location = (char*)malloc(strlen(URLname)+1);		if (! entry->location) {			gf_isom_box_del((GF_Box *)entry);			return GF_OUT_OF_MEM;		}		strcpy(entry->location, URLname);		e = dref_AddDataEntry(dref, (GF_Box *)entry);		if (e) return e;		*dataRefIndex = gf_list_count(dref->boxList);		return GF_OK;	} else {		//THIS IS URN		entry = (GF_DataEntryURLBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_URN);		((GF_DataEntryURNBox *)entry)->flags = 0;		((GF_DataEntryURNBox *)entry)->nameURN = (char*)malloc(strlen(URNname)+1);		if (! ((GF_DataEntryURNBox *)entry)->nameURN) {			gf_isom_box_del((GF_Box *)entry);			return GF_OUT_OF_MEM;		}		strcpy(((GF_DataEntryURNBox *)entry)->nameURN, URNname);		//check for URL		if (URLname) {			((GF_DataEntryURNBox *)entry)->location = (char*)malloc(strlen(URLname)+1);			if (! ((GF_DataEntryURNBox *)entry)->location) {				gf_isom_box_del((GF_Box *)entry);				return GF_OUT_OF_MEM;			}			strcpy(((GF_DataEntryURNBox *)entry)->location, URLname);		}		e = dref_AddDataEntry(dref, (GF_Box *)entry);		if (e) return e;		*dataRefIndex = gf_list_count(dref->boxList);		return GF_OK;	}	return GF_OK;}GF_Err Media_AddSample(GF_MediaBox *mdia, u64 data_offset, GF_ISOSample *sample, u32 StreamDescIndex, u32 syncShadowNumber){	GF_Err e;	GF_SampleTableBox *stbl;	u32 sampleNumber, i;	if (!mdia || !sample) return GF_BAD_PARAM;	stbl = mdia->information->sampleTable;	//get a valid sampleNumber for this new guy	e = stbl_AddDTS(stbl, sample->DTS, &sampleNumber, mdia->mediaHeader->timeScale);	if (e) return e;	//add size	e = stbl_AddSize(stbl->SampleSize, sampleNumber, sample->dataLength);	if (e) return e;	//adds CTS offset	if (sample->CTS_Offset) {		//if we don't have a CTS table, add it...		if (!stbl->CompositionOffset) stbl->CompositionOffset = (GF_CompositionOffsetBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_CTTS);		//then add our CTS (the prev samples with no CTS offset will be automatically added...		e = stbl_AddCTS(stbl, sampleNumber, sample->CTS_Offset);		if (e) return e;	} else if (stbl->CompositionOffset) {		e = stbl_AddCTS(stbl, sampleNumber, sample->CTS_Offset);		if (e) return e;	}	//The first non sync sample we see must create a syncTable	if (sample->IsRAP) {		//insert it only if we have a sync table		if (stbl->SyncSample) {			e = stbl_AddRAP(stbl->SyncSample, sampleNumber);			if (e) return e;		}	} else {		//non-sync sample. Create a SyncSample table if needed		if (!stbl->SyncSample) {			stbl->SyncSample = (GF_SyncSampleBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_STSS);			//all the prev samples are sync			for (i=0; i<stbl->SampleSize->sampleCount; i++) {				if (i+1 != sampleNumber) {					e = stbl_AddRAP(stbl->SyncSample, i+1);					if (e) return e;				}			}		}	}	if (sample->IsRAP==2) {		e = stbl_AddRedundant(stbl, sampleNumber);		if (e) return e;	}	//and update the chunks	e = stbl_AddChunkOffset(mdia, sampleNumber, StreamDescIndex, data_offset);	if (e) return e;	if (!syncShadowNumber) return GF_OK;	if (!stbl->ShadowSync) stbl->ShadowSync = (GF_ShadowSyncBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_STSH);	return stbl_AddShadow(mdia->information->sampleTable->ShadowSync, sampleNumber, syncShadowNumber);}GF_Err UpdateSample(GF_MediaBox *mdia, u32 sampleNumber, u32 size, u32 CTS, u64 offset, u8 isRap){	u32 i;	GF_SampleTableBox *stbl = mdia->information->sampleTable;	//set size, offset, RAP, CTS ...	stbl_SetSampleSize(stbl->SampleSize, sampleNumber, size);	stbl_SetChunkOffset(mdia, sampleNumber, offset);	//do we have a CTS?	if (stbl->CompositionOffset) {		stbl_SetSampleCTS(stbl, sampleNumber, CTS);	} else {		//do we need one ??		if (CTS) {			stbl->CompositionOffset = (GF_CompositionOffsetBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_CTTS);			stbl_AddCTS(stbl, sampleNumber, CTS);		}	}	//do we have a sync ???	if (stbl->SyncSample) {		stbl_SetSampleRAP(stbl->SyncSample, sampleNumber, isRap);	} else {		//do we need one		if (! isRap) {			stbl->SyncSample = (GF_SyncSampleBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_STSS);			//what a pain: all the sample we had have to be sync ...			for (i=0; i<stbl->SampleSize->sampleCount; i++) {				if (i+1 != sampleNumber) stbl_AddRAP(stbl->SyncSample, i+1);			}		}	}	if (isRap==2) {		stbl_SetRedundant(stbl, sampleNumber);	}	return GF_OK;}GF_Err Media_UpdateSample(GF_MediaBox *mdia, u32 sampleNumber, GF_ISOSample *sample, Bool data_only){	GF_Err e;	u32 drefIndex, chunkNum, descIndex;	u64 newOffset, DTS;	u8 isEdited;	GF_DataEntryURLBox *Dentry;	GF_SampleTableBox *stbl;	GF_Err stbl_AddBox(GF_SampleTableBox *ptr, GF_Box *a);	if (!mdia || !sample || !sampleNumber || !mdia->mediaTrack->moov->mov->editFileMap)		return GF_BAD_PARAM;		stbl = mdia->information->sampleTable;	if (!data_only) {		//check we have the sampe dts		e = stbl_GetSampleDTS(stbl->TimeToSample, sampleNumber, &DTS);		if (e) return e;		if (DTS != sample->DTS) return GF_BAD_PARAM;	}	//get our infos	stbl_GetSampleInfos(stbl, sampleNumber, &newOffset, &chunkNum, &descIndex, &isEdited);	//then check the data ref	e = Media_GetSampleDesc(mdia, descIndex, NULL, &drefIndex);	if (e) return e;	Dentry = (GF_DataEntryURLBox*)gf_list_get(mdia->information->dataInformation->dref->boxList, drefIndex - 1);	if (!Dentry) return GF_ISOM_INVALID_FILE;	if (Dentry->flags != 1) return GF_BAD_PARAM;	//MEDIA DATA EDIT: write this new sample to the edit temp file	newOffset = gf_isom_datamap_get_offset(mdia->mediaTrack->moov->mov->editFileMap);	e = gf_isom_datamap_add_data(mdia->mediaTrack->moov->mov->editFileMap, sample->data, sample->dataLength);	if (e) return e;	if (data_only) {		stbl_SetSampleSize(stbl->SampleSize, sampleNumber, sample->dataLength);		return stbl_SetChunkOffset(mdia, sampleNumber, newOffset);	}	return UpdateSample(mdia, sampleNumber, sample->dataLength, sample->CTS_Offset, newOffset, sample->IsRAP);}GF_Err Media_UpdateSampleReference(GF_MediaBox *mdia, u32 sampleNumber, GF_ISOSample *sample, u64 data_offset){	GF_Err e;	u32 drefIndex, chunkNum, descIndex;	u64 off, DTS;	u8 isEdited;	GF_DataEntryURLBox *Dentry;	GF_SampleTableBox *stbl;	GF_Err stbl_AddBox(GF_SampleTableBox *ptr, GF_Box *a);	if (!mdia) return GF_BAD_PARAM;	stbl = mdia->information->sampleTable;	//check we have the sampe dts	e = stbl_GetSampleDTS(stbl->TimeToSample, sampleNumber, &DTS);	if (e) return e;	if (DTS != sample->DTS) return GF_BAD_PARAM;	//get our infos	stbl_GetSampleInfos(stbl, sampleNumber, &off, &chunkNum, &descIndex, &isEdited);	//then check the data ref	e = Media_GetSampleDesc(mdia, descIndex, NULL, &drefIndex);	if (e) return e;	Dentry = (GF_DataEntryURLBox*)gf_list_get(mdia->information->dataInformation->dref->boxList, drefIndex - 1);	if (!Dentry) return GF_ISOM_INVALID_FILE;	//we only modify self-contained data	if (Dentry->flags == 1) return GF_ISOM_INVALID_MODE;	//and we don't modify the media data	return UpdateSample(mdia, sampleNumber, sample->dataLength, sample->CTS_Offset, data_offset, sample->IsRAP);}#endif	//GPAC_READ_ONLY

⌨️ 快捷键说明

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