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

📄 isom_read.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Jean Le Feuvre 2000-2005  *					All rights reserved * *  This file is part of GPAC / ISO Media File Format sub-project * *  GPAC is free software; you can redistribute it and/or modify *  it under the terms of the GNU Lesser General Public License as published by *  the Free Software Foundation; either version 2, or (at your option) *  any later version. *    *  GPAC is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU Lesser General Public License for more details. *    *  You should have received a copy of the GNU Lesser General Public *  License along with this library; see the file COPYING.  If not, write to *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  * */#include <gpac/internal/isomedia_dev.h>//the only static var. Used to store any error happening while opening a moviestatic GF_Err MP4_API_IO_Err;void gf_isom_set_last_error(GF_ISOFile *movie, GF_Err error){	if (!movie) {		MP4_API_IO_Err = error;	} else {		movie->LastError = error;	}}GF_EXPORTGF_Err gf_isom_last_error(GF_ISOFile *the_file){	if (!the_file) return MP4_API_IO_Err;	return the_file->LastError;}GF_EXPORTu8 gf_isom_get_mode(GF_ISOFile *the_file){	if (!the_file) return 0;	return the_file->openMode;}/**************************************************************					Sample Manip**************************************************************///creates a new empty sampleGF_EXPORTGF_ISOSample *gf_isom_sample_new(){	GF_ISOSample *tmp;	GF_SAFEALLOC(tmp, GF_ISOSample);	return tmp;}//delete a sampleGF_EXPORTvoid gf_isom_sample_del(GF_ISOSample **samp){	if (! *samp) return;	if ((*samp)->data && (*samp)->dataLength) free((*samp)->data);	free(*samp);	*samp = NULL;}GF_EXPORTBool gf_isom_probe_file(const char *fileName){	unsigned char data[4];	u32 type;	FILE *f = fopen(fileName, "rb");	if (!f) return 0;	type = 0;	if (fread(data, 1, 4, f) == 4) {		if (fread(data, 1, 4, f) == 4) {			type = GF_4CC(data[0], data[1], data[2], data[3]);		}	}	fclose(f);	switch (type) {	case GF_ISOM_BOX_TYPE_MOOV:	case GF_ISOM_BOX_TYPE_MDAT:	case GF_ISOM_BOX_TYPE_FTYP:	case GF_ISOM_BOX_TYPE_FREE:	case GF_ISOM_BOX_TYPE_SKIP:	case GF_ISOM_BOX_TYPE_UDTA:	case GF_ISOM_BOX_TYPE_META:	case GF_ISOM_BOX_TYPE_VOID:	case GF_4CC('j','P',' ',' '):	case GF_4CC('w','i','d','e'):		return 1;	default:		return 0;	}}/**************************************************************					File Opening in streaming mode			the file map is regular (through FILE handles)**************************************************************/GF_EXPORTGF_Err gf_isom_open_progressive(const char *fileName, GF_ISOFile **the_file, u64 *BytesMissing){	GF_Err e;	GF_ISOFile *movie;	*BytesMissing = 0;	*the_file = NULL;	movie = gf_isom_new_movie();	if (!movie) return GF_OUT_OF_MEM;	movie->fileName = strdup(fileName);	movie->openMode = GF_ISOM_OPEN_READ;	//do NOT use FileMapping on incomplete files	e = gf_isom_datamap_new(fileName, NULL, GF_ISOM_DATA_MAP_READ, &movie->movieFileMap);	if (e) {		gf_isom_delete_movie(movie);		return e;	}#ifndef GPAC_READ_ONLY	movie->editFileMap = NULL;	movie->finalName = NULL;#endif	//GPAC_READ_ONLY	e = gf_isom_parse_movie_boxes(movie, BytesMissing);	if (e == GF_ISOM_INCOMPLETE_FILE) {		//if we have a moov, we're fine		if (movie->moov) {			*the_file = (GF_ISOFile *)movie;			return GF_OK;		}		//if not, delete the movie		gf_isom_delete_movie(movie);		return e;	} else if (e) {		//if not, delete the movie		gf_isom_delete_movie(movie);		return e;	}	//OK, let's return	*the_file = (GF_ISOFile *)movie;	return GF_OK;}/**************************************************************					File Reading**************************************************************/GF_EXPORTGF_ISOFile *gf_isom_open(const char *fileName, u32 OpenMode, const char *tmp_dir){	GF_ISOFile *movie;	MP4_API_IO_Err = GF_OK;		switch (OpenMode & 0xFF) {	case GF_ISOM_OPEN_READ_DUMP:	case GF_ISOM_OPEN_READ:		movie = gf_isom_open_file(fileName, OpenMode, NULL);		break;#ifndef GPAC_READ_ONLY		case GF_ISOM_OPEN_WRITE:		movie = gf_isom_create_movie(fileName, OpenMode, tmp_dir);		break;	case GF_ISOM_OPEN_EDIT:		movie = gf_isom_open_file(fileName, OpenMode, tmp_dir);		break;	case GF_ISOM_WRITE_EDIT:		movie = gf_isom_create_movie(fileName, OpenMode, tmp_dir);		break;#endif	//GPAC_READ_ONLY			default:		return NULL;	}	return (GF_ISOFile *) movie;}GF_EXPORTGF_Err gf_isom_close(GF_ISOFile *movie){	GF_Err e;	if (movie == NULL) return GF_ISOM_INVALID_FILE;	e = GF_OK;#ifndef GPAC_READ_ONLY		//write our movie to the file	if (movie->openMode != GF_ISOM_OPEN_READ) {		gf_isom_get_duration(movie);#ifndef	GF_ISOM_NO_FRAGMENTS		//movie fragment mode, just store the fragment		if ( (movie->openMode == GF_ISOM_OPEN_WRITE) && (movie->FragmentsFlags & GF_ISOM_FRAG_WRITE_READY) ) {			e = StoreFragment(movie);		} else #endif			e = WriteToFile(movie);	}	#endif	//GPAC_READ_ONLY	//free and return;	gf_isom_delete_movie(movie);	return e;}GF_EXPORTBool gf_isom_has_root_od(GF_ISOFile *movie){	if (!movie || !movie->moov || !movie->moov->iods || !movie->moov->iods->descriptor) return 0;	return 1;}//this funct is used for exchange files, where the iods contains an ODGF_EXPORTGF_Descriptor *gf_isom_get_root_od(GF_ISOFile *movie){	GF_Descriptor *desc;	GF_ObjectDescriptor *od;	GF_InitialObjectDescriptor *iod;	GF_IsomObjectDescriptor *isom_od;	GF_IsomInitialObjectDescriptor *isom_iod;	GF_ESD *esd;	GF_ES_ID_Inc *inc;	u32 i;	u8 useIOD;	if (!movie || !movie->moov) return NULL;	if (!movie->moov->iods) return NULL;	od = NULL;	iod = NULL;	switch (movie->moov->iods->descriptor->tag) {	case GF_ODF_ISOM_OD_TAG:		od = (GF_ObjectDescriptor*)malloc(sizeof(GF_ObjectDescriptor));		memset(od, 0, sizeof(GF_ObjectDescriptor));		od->ESDescriptors = gf_list_new();		useIOD = 0;		break;	case GF_ODF_ISOM_IOD_TAG:		iod = (GF_InitialObjectDescriptor*)malloc(sizeof(GF_InitialObjectDescriptor));		memset(iod, 0, sizeof(GF_InitialObjectDescriptor));		iod->ESDescriptors = gf_list_new();		useIOD = 1;		break;	default:		return NULL;	}		//duplicate our descriptor	movie->LastError = gf_odf_desc_copy((GF_Descriptor *) movie->moov->iods->descriptor, &desc);	if (movie->LastError) return NULL;	if (!useIOD) {		isom_od = (GF_IsomObjectDescriptor *)desc;		od->objectDescriptorID = isom_od->objectDescriptorID;		od->extensionDescriptors = isom_od->extensionDescriptors;		isom_od->extensionDescriptors = NULL;		od->IPMP_Descriptors = isom_od->IPMP_Descriptors;		isom_od->IPMP_Descriptors = NULL;		od->OCIDescriptors = isom_od->OCIDescriptors;		isom_od->OCIDescriptors = NULL;		od->URLString = isom_od->URLString;		isom_od->URLString = NULL;		od->tag = GF_ODF_OD_TAG;		//then recreate the desc in Inc		i=0;		while ((inc = (GF_ES_ID_Inc*)gf_list_enum(isom_od->ES_ID_IncDescriptors, &i))) {			movie->LastError = GetESDForTime(movie->moov, inc->trackID, 0, &esd);			if (!movie->LastError) movie->LastError = gf_list_add(od->ESDescriptors, esd);			if (movie->LastError) {				gf_odf_desc_del(desc);				gf_odf_desc_del((GF_Descriptor *) od);				return NULL;			}		}		gf_odf_desc_del(desc);		return (GF_Descriptor *)od;	} else {		isom_iod = (GF_IsomInitialObjectDescriptor *)desc;		iod->objectDescriptorID = isom_iod->objectDescriptorID;		iod->extensionDescriptors = isom_iod->extensionDescriptors;		isom_iod->extensionDescriptors = NULL;		iod->IPMP_Descriptors = isom_iod->IPMP_Descriptors;		isom_iod->IPMP_Descriptors = NULL;		iod->OCIDescriptors = isom_iod->OCIDescriptors;		isom_iod->OCIDescriptors = NULL;		iod->URLString = isom_iod->URLString;		isom_iod->URLString = NULL;		iod->tag = GF_ODF_IOD_TAG;		iod->audio_profileAndLevel = isom_iod->audio_profileAndLevel;		iod->graphics_profileAndLevel = isom_iod->graphics_profileAndLevel;		iod->inlineProfileFlag = isom_iod->inlineProfileFlag;		iod->OD_profileAndLevel = isom_iod->OD_profileAndLevel;		iod->scene_profileAndLevel = isom_iod->scene_profileAndLevel;		iod->visual_profileAndLevel = isom_iod->visual_profileAndLevel;		iod->IPMPToolList = isom_iod->IPMPToolList;		isom_iod->IPMPToolList = NULL;		//then recreate the desc in Inc		i=0;		while ((inc = (GF_ES_ID_Inc*)gf_list_enum(isom_iod->ES_ID_IncDescriptors, &i))) {			movie->LastError = GetESDForTime(movie->moov, inc->trackID, 0, &esd);			if (!movie->LastError) movie->LastError = gf_list_add(iod->ESDescriptors, esd);			if (movie->LastError) {				gf_odf_desc_del(desc);				gf_odf_desc_del((GF_Descriptor *) &iod);				return NULL;			}		}		gf_odf_desc_del(desc);		return (GF_Descriptor *)iod;	}}GF_EXPORTu32 gf_isom_get_track_count(GF_ISOFile *movie){	if (!movie || !movie->moov) return 0;	if (! movie->moov->trackList) {		movie->LastError = GF_ISOM_INVALID_FILE;		return 0;	}	return gf_list_count(movie->moov->trackList);}GF_EXPORTu32 gf_isom_get_track_id(GF_ISOFile *movie, u32 trackNumber){	GF_TrackBox *trak;	if (!movie) return 0;	trak = gf_isom_get_track_from_file(movie, trackNumber);	if (!trak) return 0;	return trak->Header->trackID;}GF_EXPORTu32 gf_isom_get_track_by_id(GF_ISOFile *the_file, u32 trackID){	GF_TrackBox *trak;	u32 count;	u32 i;	if (the_file == NULL) return 0;		count = gf_isom_get_track_count(the_file);	if (!count) return 0;	for (i = 0; i < count; i++) {		trak = gf_isom_get_track_from_file(the_file, i+1);		if (!trak) return 0;		if (trak->Header->trackID == trackID) return i+1;	}	return 0;}//return the timescale of the movie, 0 if errorGF_EXPORTBool gf_isom_has_movie(GF_ISOFile *file){	if (file && file->moov) return 1;	return 0;}//return the timescale of the movie, 0 if errorGF_EXPORTu32 gf_isom_get_timescale(GF_ISOFile *movie){	if (!movie || !movie->moov) return 0;	return movie->moov->mvhd->timeScale;}//return the duration of the movie, 0 if errorGF_EXPORTu64 gf_isom_get_duration(GF_ISOFile *movie){#ifndef GPAC_READ_ONLY	u32 i;	u64 maxDur;	GF_TrackBox *trak;#endif	if (!movie || !movie->moov) return 0;	//if file was open in Write or Edit mode, recompute the duration	//the duration of a movie is the MaxDuration of all the tracks...#ifndef GPAC_READ_ONLY	if (movie->openMode != GF_ISOM_OPEN_READ) {		maxDur = 0;		i=0;		while ((trak = (GF_TrackBox *)gf_list_enum(movie->moov->trackList, &i))) {			if( (movie->LastError = SetTrackDuration(trak))	) return 0;			if (trak->Header->duration > maxDur)				maxDur = trak->Header->duration;		}		movie->moov->mvhd->duration = maxDur;	}#endif	//GPAC_READ_ONLY	return movie->moov->mvhd->duration;}//return the creation info of the movieGF_EXPORTGF_Err gf_isom_get_creation_time(GF_ISOFile *movie, u64 *creationTime, u64 *modificationTime){	if (!movie || !movie->moov) return GF_BAD_PARAM;		if (creationTime) *creationTime = movie->moov->mvhd->creationTime;	if (creationTime) *modificationTime = movie->moov->mvhd->modificationTime;	return GF_OK;}//check the presence of a track in IOD. 0: NO, 1: YES, 2: ERROR

⌨️ 快捷键说明

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