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

📄 isom_intern.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
		return NULL;	}	return mov;}u64 gf_isom_get_mp4time(){	u32 calctime, msec;	u64 ret;	gf_utc_time_since_1970(&calctime, &msec);	calctime += GF_ISOM_MAC_TIME_OFFSET;	ret = calctime;	return ret;}void gf_isom_delete_movie(GF_ISOFile *mov){	//these are our two main files	if (mov->movieFileMap) gf_isom_datamap_del(mov->movieFileMap);#ifndef GPAC_READ_ONLY	if (mov->editFileMap) {		gf_isom_datamap_del(mov->editFileMap);	}	if (mov->finalName) free(mov->finalName);#endif	gf_isom_box_array_del(mov->TopBoxes);	if (mov->fileName) free(mov->fileName);	free(mov);}GF_TrackBox *gf_isom_get_track_from_id(GF_MovieBox *moov, u32 trackID) {	u32 i, count;	GF_TrackBox *trak;	if (!moov || !trackID) return NULL;	count = gf_list_count(moov->trackList);	for (i = 0; i<count; i++) {		trak = (GF_TrackBox*)gf_list_get(moov->trackList, i);		if (trak->Header->trackID == trackID) return trak;	}	return NULL;}GF_TrackBox *gf_isom_get_track_from_file(GF_ISOFile *movie, u32 trackNumber){	GF_TrackBox *trak;	if (!movie) return NULL;	trak = gf_isom_get_track(movie->moov, trackNumber);	if (!trak) movie->LastError = GF_BAD_PARAM;	return trak;}//WARNING: MOVIETIME IS EXPRESSED IN MEDIA TSGF_Err GetMediaTime(GF_TrackBox *trak, u64 movieTime, u64 *MediaTime, s64 *SegmentStartTime, s64 *MediaOffset, u8 *useEdit){	GF_Err e;	u32 i;	u64 time, lastSampleTime, m_time;	s64 mtime;	GF_EdtsEntry *ent;	Double scale_ts;	u32 sampleNumber, prevSampleNumber;	u64 firstDTS;	GF_SampleTableBox *stbl = trak->Media->information->sampleTable;	*useEdit = 1;	*MediaTime = 0;	//no segment yet...	*SegmentStartTime = -1;	*MediaOffset = -1;	if (!trak->moov->mvhd->timeScale || !trak->Media->mediaHeader->timeScale) {		return GF_ISOM_INVALID_FILE;	}	//no samples...	if (!stbl->SampleSize->sampleCount) {		lastSampleTime = 0;	} else {		lastSampleTime = trak->Media->mediaHeader->duration;	}	//No edits, 1 to 1 mapping	if (! trak->editBox || !trak->editBox->editList) {		*MediaTime = movieTime;		//check this is in our media time line		if (*MediaTime > lastSampleTime) *MediaTime = lastSampleTime;		*useEdit = 0;		return GF_OK;	}	//browse the edit list and get the time	scale_ts = trak->moov->mvhd->timeScale;	scale_ts /= trak->Media->mediaHeader->timeScale;	scale_ts *= ((s64)movieTime + 1);	m_time = (u64) (scale_ts);	time = 0;	ent = NULL;	i=0;	while ((ent = (GF_EdtsEntry *)gf_list_enum(trak->editBox->editList->entryList, &i))) {		if (time + ent->segmentDuration > m_time) {			goto ent_found;		}		time += ent->segmentDuration;	}	//we had nothing in the list (strange file but compliant...)	//return the 1 to 1 mapped vale of the last media sample	if (!ent) {		*MediaTime = movieTime;		//check this is in our media time line		if (*MediaTime > lastSampleTime) *MediaTime = lastSampleTime;		*useEdit = 0;		return GF_OK;	}	//request for a bigger time that what we can give: return the last sample (undefined behavior...)	*MediaTime = lastSampleTime;	return GF_OK;ent_found:	//OK, we found our entry, set the SegmentTime	*SegmentStartTime = time;	//we request an empty list, there's no media here...	if (ent->mediaTime < 0) {		*MediaTime = 0;		return GF_OK;	}	//we request a dwell edit	if (! ent->mediaRate) {		*MediaTime = ent->mediaTime;		//no media offset		*MediaOffset = 0;		*useEdit = 2;		return GF_OK;	}		/*WARNING: this can be "-1" when doing searchForward mode (to prevent jumping to next entry)*/	mtime = ent->mediaTime + movieTime - (time * trak->Media->mediaHeader->timeScale / trak->moov->mvhd->timeScale);	if (mtime<0) mtime = 0;	*MediaTime = (u64) mtime;#if 0	//	//Sanity check: is the requested time valid ? This is to cope with wrong EditLists	//we have the translated time, but we need to make sure we have a sample at this time ...	//we have to find a COMPOSITION time	e = findEntryForTime(stbl, (u32) *MediaTime, 1, &sampleNumber, &prevSampleNumber);	if (e) return e;		//first case: our time is after the last sample DTS (it's a broken editList somehow)	//set the media time to the last sample	if (!sampleNumber && !prevSampleNumber) {		*MediaTime = lastSampleTime;		return GF_OK;	}	//get the appropriated sample	if (!sampleNumber) sampleNumber = prevSampleNumber;	stbl_GetSampleDTS(stbl->TimeToSample, sampleNumber, &DTS);	CTS = 0;	if (stbl->CompositionOffset) stbl_GetSampleCTS(stbl->CompositionOffset, sampleNumber, &CTS);#endif	//now get the entry sample (the entry time gives the CTS, and we need the DTS	e = findEntryForTime(stbl, (u32) ent->mediaTime, 1, &sampleNumber, &prevSampleNumber);	if (e) return e;	//oops, the mediaTime indicates a sample that is not in our media !	if (!sampleNumber && !prevSampleNumber) {		*MediaTime = lastSampleTime;		return GF_ISOM_INVALID_FILE;	}	if (!sampleNumber) sampleNumber = prevSampleNumber;	stbl_GetSampleDTS(stbl->TimeToSample, sampleNumber, &firstDTS);	//and store the "time offset" of the desired sample in this segment	//this is weird, used to rebuild the timeStamp when reading from the track, not the	//media ...	*MediaOffset = firstDTS;	return GF_OK;}GF_Err GetNextMediaTime(GF_TrackBox *trak, u64 movieTime, u64 *OutMovieTime){	u32 i;	u64 time;	GF_EdtsEntry *ent;	*OutMovieTime = 0;	if (! trak->editBox || !trak->editBox->editList) return GF_BAD_PARAM;	time = 0;	ent = NULL;	i=0;	while ((ent = (GF_EdtsEntry *)gf_list_enum(trak->editBox->editList->entryList, &i))) {		if (time * trak->Media->mediaHeader->timeScale >= movieTime * trak->moov->mvhd->timeScale) {			/*skip empty edits*/			if (ent->mediaTime >= 0) {				*OutMovieTime = time * trak->Media->mediaHeader->timeScale / trak->moov->mvhd->timeScale;				if (*OutMovieTime>0) *OutMovieTime -= 1;				return GF_OK;			}		}		time += ent->segmentDuration;	}	//request for a bigger time that what we can give: return the last sample (undefined behavior...)	*OutMovieTime = trak->moov->mvhd->duration;	return GF_EOS;}GF_Err GetPrevMediaTime(GF_TrackBox *trak, u64 movieTime, u64 *OutMovieTime){	u32 i;	u64 time;	GF_EdtsEntry *ent;	*OutMovieTime = 0;	if (! trak->editBox || !trak->editBox->editList) return GF_BAD_PARAM;	time = 0;	ent = NULL;	i=0;	while ((ent = (GF_EdtsEntry *)gf_list_enum(trak->editBox->editList->entryList, &i))) {		if (ent->mediaTime == -1) {			if ( (time + ent->segmentDuration) * trak->Media->mediaHeader->timeScale >= movieTime * trak->moov->mvhd->timeScale) {				*OutMovieTime = time * trak->Media->mediaHeader->timeScale / trak->moov->mvhd->timeScale;				return GF_OK;			}			continue;		}		/*get the first entry whose end is greater than or equal to the desired time*/		time += ent->segmentDuration;		if ( time * trak->Media->mediaHeader->timeScale >= movieTime * trak->moov->mvhd->timeScale) {			*OutMovieTime = time * trak->Media->mediaHeader->timeScale / trak->moov->mvhd->timeScale;			return GF_OK;		}	}	*OutMovieTime = 0;	return GF_OK;}#ifndef GPAC_READ_ONLYvoid gf_isom_insert_moov(GF_ISOFile *file){	u64 now;	GF_MovieHeaderBox *mvhd;	if (file->moov) return;	//OK, create our boxes (mvhd, iods, ...)	file->moov = (GF_MovieBox *) moov_New();	file->moov->mov = file;	//Header SetUp	now = gf_isom_get_mp4time();	mvhd = (GF_MovieHeaderBox *) mvhd_New();	mvhd->creationTime = now;	mvhd->modificationTime = now;	mvhd->nextTrackID = 1;	//600 is our default movie TimeScale	mvhd->timeScale = 600;	file->interleavingTime = mvhd->timeScale;	moov_AddBox((GF_Box*)file->moov, (GF_Box *)mvhd);	gf_list_add(file->TopBoxes, file->moov);}//Create the movie for WRITE onlyGF_ISOFile *gf_isom_create_movie(const char *fileName, u32 OpenMode, const char *tmp_dir){	GF_Err e;	GF_ISOFile *mov = gf_isom_new_movie();	if (!mov) return NULL;	mov->openMode = OpenMode;	//then set up our movie	//in WRITE, the input dataMap is ALWAYS NULL	mov->movieFileMap = NULL;	//but we have the edit one	if (OpenMode == GF_ISOM_OPEN_WRITE) {		//THIS IS NOT A TEMP FILE, WRITE mode is used for "live capture"		//this file will be the final file...		mov->fileName = strdup(fileName);		e = gf_isom_datamap_new(fileName, NULL, GF_ISOM_DATA_MAP_WRITE, & mov->editFileMap);		if (e) goto err_exit;				/*brand is set to ISOM by default - it may be touched until sample data is added to track*/		gf_isom_set_brand_info( (GF_ISOFile *) mov, GF_ISOM_BRAND_ISOM, 1);	} else {		//we are in EDIT mode but we are creating the file -> temp file		mov->finalName = (char*)malloc(strlen(fileName) + 1);		strcpy(mov->finalName, fileName);		e = gf_isom_datamap_new("mp4_tmp_edit", tmp_dir, GF_ISOM_DATA_MAP_WRITE, & mov->editFileMap);		if (e) {			gf_isom_set_last_error(NULL, e);			gf_isom_delete_movie(mov);			return NULL;		}		//brand is set to ISOM by default		gf_isom_set_brand_info( (GF_ISOFile *) mov, GF_ISOM_BRAND_ISOM, 1);	}	//create an MDAT	mov->mdat = (GF_MediaDataBox *) mdat_New();	gf_list_add(mov->TopBoxes, mov->mdat);		//default behaviour is capture mode, no interleaving (eg, no rewrite of mdat)	mov->storageMode = GF_ISOM_STORE_FLAT;	return mov;err_exit:	gf_isom_set_last_error(NULL, e);	if (mov) gf_isom_delete_movie(mov);	return NULL;}GF_EdtsEntry *CreateEditEntry(u64 EditDuration, u64 MediaTime, u8 EditMode){	GF_EdtsEntry *ent;	ent = (GF_EdtsEntry*)malloc(sizeof(GF_EdtsEntry));	if (!ent) return NULL;	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;	}	ent->segmentDuration = EditDuration;	return ent;}#endif	//GPAC_READ_ONLY

⌨️ 快捷键说明

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