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

📄 isom_intern.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *			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>#include <gpac/network.h>/**************************************************************		Some Local functions for movie creation**************************************************************/GF_Err gf_isom_parse_root_box(GF_Box **outBox, GF_BitStream *bs, u64 *bytesExpected);#ifndef	GF_ISOM_NO_FRAGMENTSGF_Err MergeFragment(GF_MovieFragmentBox *moof, GF_ISOFile *mov){	u32 i, j;	u64 MaxDur;	GF_TrackFragmentBox *traf;	GF_TrackBox *trak;	GF_Err MergeTrack(GF_TrackBox *trak, GF_TrackFragmentBox *traf, u64 *moof_offset);		MaxDur = 0;	//we shall have a MOOV and its MVEX BEFORE any MOOF	if (!mov->moov || !mov->moov->mvex) return GF_ISOM_INVALID_FILE;	//and all fragments must be continous	if (mov->NextMoofNumber + 1 != moof->mfhd->sequence_number) return GF_ISOM_INVALID_FILE;	i=0;	while ((traf = (GF_TrackFragmentBox*)gf_list_enum(moof->TrackList, &i))) {		if (!traf->tfhd) {			trak = NULL;			traf->trex = NULL;		} else {			trak = gf_isom_get_track_from_id(mov->moov, traf->tfhd->trackID);			j=0;			while ((traf->trex = (GF_TrackExtendsBox*)gf_list_enum(mov->moov->mvex->TrackExList, &j))) {				if (traf->trex->trackID == traf->tfhd->trackID) break;				traf->trex = NULL;			}		}		if (!trak || !traf->trex) return GF_ISOM_INVALID_FILE;		//NB we can modify the movie data-offset info since we are in the middle of		//parsing an box, so next box readin will reset it...		MergeTrack(trak, traf, &mov->current_top_box_start);		//update trak duration		SetTrackDuration(trak);		if (trak->Header->duration > MaxDur) 			MaxDur = trak->Header->duration;	}	mov->NextMoofNumber += 1;	//update movie duration	if (mov->moov->mvhd->duration < MaxDur) mov->moov->mvhd->duration = MaxDur;	return GF_OK;}#endifGF_Err gf_isom_parse_movie_boxes(GF_ISOFile *mov, u64 *bytesMissing){	GF_Box *a;	u64 totSize;	GF_Err e = GF_OK;	totSize = 0;#ifndef	GF_ISOM_NO_FRAGMENTS	/*restart from where we stoped last*/	totSize = mov->current_top_box_start;	gf_bs_seek(mov->movieFileMap->bs, mov->current_top_box_start);#endif	/*while we have some data, parse our boxes*/	while (gf_bs_available(mov->movieFileMap->bs)) {		*bytesMissing = 0;#ifndef	GF_ISOM_NO_FRAGMENTS		mov->current_top_box_start = gf_bs_get_position(mov->movieFileMap->bs);#endif		e = gf_isom_parse_root_box(&a, mov->movieFileMap->bs, bytesMissing);		if (e >= 0) {			e = GF_OK;		} else if (e == GF_ISOM_INCOMPLETE_FILE) {			/*our mdat is uncomplete, only valid for READ ONLY files...*/			if (mov->openMode != GF_ISOM_OPEN_READ) {				return GF_ISOM_INVALID_FILE;			}			return e;		} else {			return e;		}		switch (a->type) {		/*MOOV box*/		case GF_ISOM_BOX_TYPE_MOOV:			if (mov->moov) return GF_ISOM_INVALID_FILE;			mov->moov = (GF_MovieBox *)a;			/*set our pointer to the movie*/			mov->moov->mov = mov;			e = gf_list_add(mov->TopBoxes, a);			if (e) return e;			totSize += a->size;			break;		/*META box*/		case GF_ISOM_BOX_TYPE_META:			if (mov->meta) return GF_ISOM_INVALID_FILE;			mov->meta = (GF_MetaBox *)a;			e = gf_list_add(mov->TopBoxes, a);			if (e) return e;			totSize += a->size;			break;		/*we only keep the MDAT in READ for dump purposes*/		case GF_ISOM_BOX_TYPE_MDAT:			totSize += a->size;			if (mov->openMode == GF_ISOM_OPEN_READ) {				if (!mov->mdat) {					mov->mdat = (GF_MediaDataBox *) a;					e = gf_list_add(mov->TopBoxes, mov->mdat);					if (e) return e;				}#ifndef	GF_ISOM_NO_FRAGMENTS				else if (mov->FragmentsFlags & GF_ISOM_FRAG_READ_DEBUG) gf_list_add(mov->TopBoxes, a);#endif				else gf_isom_box_del(a);			}			/*if we don't have any MDAT yet, create one (edit-write mode)			We only work with one mdat, but we're puting it at the place			of the first mdat found when opening a file for editing*/			else if (!mov->mdat && (mov->openMode != GF_ISOM_OPEN_READ)) {				gf_isom_box_del(a);				mov->mdat = (GF_MediaDataBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_MDAT);				e = gf_list_add(mov->TopBoxes, mov->mdat);				if (e) return e;			} else {				gf_isom_box_del(a);			}			break;		case GF_ISOM_BOX_TYPE_FTYP:			/*ONE AND ONLY ONE FTYP*/			if (mov->brand) {				gf_isom_box_del(a);				return GF_ISOM_INVALID_FILE;			}			mov->brand = (GF_FileTypeBox *)a;			totSize += a->size;			e = gf_list_add(mov->TopBoxes, a);			break;		case GF_ISOM_BOX_TYPE_PDIN:			/*ONE AND ONLY ONE PDIN*/			if (mov->pdin) {				gf_isom_box_del(a);				return GF_ISOM_INVALID_FILE;			}			mov->pdin = (GF_ProgressiveDownloadBox *) a;			totSize += a->size;			e = gf_list_add(mov->TopBoxes, a);			break;#ifndef	GF_ISOM_NO_FRAGMENTS		case GF_ISOM_BOX_TYPE_MOOF:			((GF_MovieFragmentBox *)a)->mov = mov;			totSize += a->size;			/*read & debug: store at root level*/			if (mov->FragmentsFlags & GF_ISOM_FRAG_READ_DEBUG) {				gf_list_add(mov->TopBoxes, a);			} else {				/*merge all info*/				e = MergeFragment((GF_MovieFragmentBox *)a, mov);				gf_isom_box_del(a);			}			break;#endif		case GF_4CC('j','P',' ',' '):		{			GF_UnknownBox *box = (GF_UnknownBox*)a;			u8 *c = box->data;			if ((box->dataSize==4) 				&& (GF_4CC(c[0],c[1],c[2],c[3])==(u32)0x0D0A870A)) 				 mov->is_jp2 = 1;			gf_isom_box_del(a);		}			break;		default:			totSize += a->size;			e = gf_list_add(mov->TopBoxes, a);			break;		}	}	/*we need at least moov or meta*/	if (!mov->moov && !mov->meta) return GF_ISOM_INVALID_FILE;	/*we MUST have movie header*/	if (mov->moov && !mov->moov->mvhd) return GF_ISOM_INVALID_FILE;	/*we MUST have meta handler*/	if (mov->meta && !mov->meta->handler) return GF_ISOM_INVALID_FILE;#ifndef GPAC_READ_ONLY	if (mov->moov) {		/*set the default interleaving time*/		mov->interleavingTime = mov->moov->mvhd->timeScale;#ifndef	GF_ISOM_NO_FRAGMENTS		/*not in open mode and successfully loaded the entire file, destroy all fragment		FIXME: we may need to keet it when trying http streaming of fragments...*/		if (!(mov->FragmentsFlags & GF_ISOM_FRAG_READ_DEBUG) && mov->moov->mvex) {			gf_isom_box_del((GF_Box *)mov->moov->mvex);			mov->moov->mvex = NULL;		}#endif	}#endif	return GF_OK;}GF_ISOFile *gf_isom_new_movie(){	GF_ISOFile *mov = (GF_ISOFile*)malloc(sizeof(GF_ISOFile));	if (mov == NULL) {		gf_isom_set_last_error(NULL, GF_OUT_OF_MEM);		return NULL;	}	memset(mov, 0, sizeof(GF_ISOFile));	/*init the boxes*/	mov->TopBoxes = gf_list_new();	if (!mov->TopBoxes) {		gf_isom_set_last_error(NULL, GF_OUT_OF_MEM);		free(mov);		return NULL;	}		/*default storage mode is flat*/	mov->storageMode = GF_ISOM_STORE_FLAT;	return mov;}//Create and parse the movie for READ - EDIT onlyGF_ISOFile *gf_isom_open_file(const char *fileName, u32 OpenMode, const char *tmp_dir){	GF_Err e;	u64 bytes;	GF_ISOFile *mov = gf_isom_new_movie();	if (! mov) return NULL;	mov->fileName = strdup(fileName);	mov->openMode = OpenMode;	if ( (OpenMode == GF_ISOM_OPEN_READ) || (OpenMode == GF_ISOM_OPEN_READ_DUMP) ) {		//always in read ...		mov->openMode = GF_ISOM_OPEN_READ;		mov->es_id_default_sync = -1;		//for open, we do it the regular way and let the GF_DataMap assign the appropriate struct		//this can be FILE (the only one supported...) as well as remote 		//(HTTP, ...),not suported yet		//the bitstream IS PART OF the GF_DataMap		//as this is read-only, use a FileMapping. this is the only place where 		//we use file mapping		e = gf_isom_datamap_new(fileName, NULL, GF_ISOM_DATA_MAP_READ_ONLY, &mov->movieFileMap);		if (e) {			gf_isom_set_last_error(NULL, e);			gf_isom_delete_movie(mov);			return NULL;		}#ifndef	GF_ISOM_NO_FRAGMENTS		if (OpenMode == GF_ISOM_OPEN_READ_DUMP) mov->FragmentsFlags |= GF_ISOM_FRAG_READ_DEBUG;#endif	} else {#ifdef GPAC_READ_ONLY		//not allowed for READ_ONLY lib		gf_isom_delete_movie(mov);		gf_isom_set_last_error(NULL, GF_ISOM_INVALID_MODE);		return NULL;#else		//set a default output name for edited file		mov->finalName = (char*)malloc(strlen(fileName) + 5);		if (!mov->finalName) {			gf_isom_set_last_error(NULL, GF_OUT_OF_MEM);			gf_isom_delete_movie(mov);			return NULL;		}		strcpy(mov->finalName, "out_");		strcat(mov->finalName, fileName);		//open the original file with edit tag		e = gf_isom_datamap_new(fileName, NULL, GF_ISOM_DATA_MAP_EDIT, &mov->movieFileMap);		//if the file doesn't exist, we assume it's wanted and create one from scratch		if (e) {			gf_isom_set_last_error(NULL, e);			gf_isom_delete_movie(mov);			return NULL;		}		//and create a temp fileName for the edit		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;		}		mov->es_id_default_sync = -1;#endif	}	//OK, let's parse the movie...	mov->LastError = gf_isom_parse_movie_boxes(mov, &bytes);	if (mov->LastError) {		gf_isom_set_last_error(NULL, mov->LastError);		gf_isom_delete_movie(mov);

⌨️ 快捷键说明

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