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

📄 box_funcs.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 4 页
字号:
/* *			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>//Add this funct to handle incomplete files...//bytesExpected is 0 most of the time. If the file is incomplete, bytesExpected//is the number of bytes missing to parse the box...GF_Err gf_isom_parse_root_box(GF_Box **outBox, GF_BitStream *bs, u64 *bytesExpected){	GF_Err ret;	u64 start;	//first make sure we can at least get the box size and type...	//18 = size (int32) + type (int32)	if (gf_bs_available(bs) < 8) {		*bytesExpected = 8;		return GF_ISOM_INCOMPLETE_FILE;	}	start = gf_bs_get_position(bs);	ret = gf_isom_parse_box(outBox, bs);	if (ret == GF_ISOM_INCOMPLETE_FILE) {		*bytesExpected = (*outBox)->size;		gf_bs_seek(bs, start);		gf_isom_box_del(*outBox);		*outBox = NULL;	}	return ret;}GF_Err gf_isom_parse_box(GF_Box **outBox, GF_BitStream *bs){	u32 type, hdr_size;	u64 size, start, end;	char uuid[16];	GF_Err e;	GF_Box *newBox;	e = GF_OK;	if ((bs == NULL) || (outBox == NULL) ) return GF_BAD_PARAM;	*outBox = NULL;	start = gf_bs_get_position(bs);	size = (u64) gf_bs_read_u32(bs);	hdr_size = 4;	/*fix for some boxes found in some old hinted files*/	if ((size >= 2) && (size <= 4)) {		size = 4;		type = GF_ISOM_BOX_TYPE_VOID;	} else {		/*now here's a bad thing: some files use size 0 for void atoms, some for "till end of file" indictaion..*/		if (!size) {			type = gf_bs_peek_bits(bs, 32, 0);			if (!isalnum((type>>24)&0xFF) || !isalnum((type>>16)&0xFF) || !isalnum((type>>8)&0xFF) || !isalnum(type&0xFF)) {				size = 4;				type = GF_ISOM_BOX_TYPE_VOID;			} else {				goto proceed_box;			}		} else {proceed_box:			type = gf_bs_read_u32(bs);			hdr_size += 4;			/*no size means till end of file - EXCEPT FOR some old QuickTime boxes...*/			if (type == GF_ISOM_BOX_TYPE_TOTL)				size = 12;			if (!size) size = gf_bs_available(bs) + 8;		}	}	/*handle uuid*/	memset(uuid, 0, 16);	if (type == GF_ISOM_BOX_TYPE_UUID ) {		gf_bs_read_data(bs, uuid, 16);		hdr_size += 16;	}		//handle large box	if (size == 1) {		size = gf_bs_read_u64(bs);		hdr_size += 8;	}	GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] Read Box type %s size "LLD" start "LLD"\n", gf_4cc_to_str(type), LLD_CAST size, LLD_CAST start));	if ( size < hdr_size ) {		GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] Box size "LLD" less than box header size %d\n", LLD_CAST size, hdr_size));		return GF_ISOM_INVALID_FILE;	}	//OK, create the box based on the type	newBox = gf_isom_box_new(type);	if (!newBox) return GF_OUT_OF_MEM;	//OK, init and read this box	if (type==GF_ISOM_BOX_TYPE_UUID) memcpy(((GF_UUIDBox *)newBox)->uuid, uuid, 16);	if (!newBox->type) newBox->type = type; 	end = gf_bs_available(bs);	if (size - hdr_size > end ) {		newBox->size = size - hdr_size - end;		*outBox = newBox;		return GF_ISOM_INCOMPLETE_FILE;	}	//we need a special reading for these boxes...	if ((newBox->type == GF_ISOM_BOX_TYPE_STDP) || (newBox->type == GF_ISOM_BOX_TYPE_SDTP)) {		newBox->size = size;		*outBox = newBox;		return GF_OK;	}		newBox->size = size - hdr_size;	e = gf_isom_box_read(newBox, bs);		newBox->size = size;	end = gf_bs_get_position(bs);	if (e && (e != GF_ISOM_INCOMPLETE_FILE)) {		gf_isom_box_del(newBox);		*outBox = NULL;		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Read Box \"%s\" failed (%s)\n", gf_4cc_to_str(type), gf_error_to_string(e)));		return e;	}	if (end-start > size) {		GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Box \"%s\" size "LLU" invalid (read "LLU")\n", gf_4cc_to_str(type), LLU_CAST size, LLU_CAST (end-start) ));		/*let's still try to load the file since no error was notified*/		gf_bs_seek(bs, start+size);	} else if (end-start < size) {		u32 to_skip = (u32) (size-(end-start));		GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Box \"%s\" has %d extra bytes\n", gf_4cc_to_str(type), to_skip));		gf_bs_skip_bytes(bs, to_skip);	}	*outBox = newBox;	return e;}GF_Err gf_isom_full_box_read(GF_Box *ptr, GF_BitStream *bs){	GF_FullBox *self = (GF_FullBox *) ptr;	if (ptr->size<4) return GF_ISOM_INVALID_FILE;	self->version = gf_bs_read_u8(bs);	self->flags = gf_bs_read_u24(bs);	ptr->size -= 4;	return GF_OK;}void gf_isom_full_box_init(GF_Box *a){	GF_FullBox *ptr = (GF_FullBox *)a;	if (! ptr) return;	ptr->flags = 0;	ptr->version = 0;}void gf_isom_box_array_del(GF_List *boxList){	u32 count, i;	GF_Box *a;	if (!boxList) return;	count = gf_list_count(boxList); 	for (i = 0; i < count; i++) {		a = (GF_Box *)gf_list_get(boxList, i);		if (a) gf_isom_box_del(a);	}	gf_list_del(boxList);}GF_Err gf_isom_read_box_list(GF_Box *parent, GF_BitStream *bs, GF_Err (*add_box)(GF_Box *par, GF_Box *b)){	GF_Err e;	GF_Box *a;	while (parent->size) {		e = gf_isom_parse_box(&a, bs);		if (e) {			if (a) gf_isom_box_del(a);			return e;		}		if (parent->size < a->size) {			if (a) gf_isom_box_del(a);			return GF_OK;			//return GF_ISOM_INVALID_FILE;		}		parent->size -= a->size;		e = add_box(parent, a);		if (e) {			gf_isom_box_del(a);			return e;		}	}	return GF_OK;}//from here, for write/edit versions#ifndef GPAC_READ_ONLYGF_Err gf_isom_box_get_size(GF_Box *ptr){	ptr->size = 8;	if (ptr->type == GF_ISOM_BOX_TYPE_UUID) {		ptr->size += 16;	}	//the large size is handled during write, cause at this stage we don't know the size	return GF_OK;}GF_Err gf_isom_full_box_get_size(GF_Box *ptr){	GF_Err e;	e = gf_isom_box_get_size(ptr);	if (e) return e;	ptr->size += 4;	return GF_OK;}GF_Err gf_isom_box_write_header(GF_Box *ptr, GF_BitStream *bs){	if (! bs || !ptr) return GF_BAD_PARAM;	if (!ptr->size) return GF_ISOM_INVALID_FILE;	if (ptr->size > 0xFFFFFFFF) {		gf_bs_write_u32(bs, 1);	} else {		gf_bs_write_u32(bs, (u32) ptr->size);	}	gf_bs_write_u32(bs, ptr->type);	if (ptr->type == GF_ISOM_BOX_TYPE_UUID) 		gf_bs_write_data(bs, (char*)((GF_UUIDBox*)ptr)->uuid, 16);	if (ptr->size > 0xFFFFFFFF) 		gf_bs_write_u64(bs, ptr->size);	return GF_OK;}GF_Err gf_isom_full_box_write(GF_Box *s, GF_BitStream *bs){	GF_Err e;	GF_FullBox *ptr = (GF_FullBox *)s;	e = gf_isom_box_write_header(s, bs);	if (e) return e;	gf_bs_write_u8(bs, ptr->version);	gf_bs_write_u24(bs, ptr->flags);	return GF_OK;}GF_Err gf_isom_box_array_write(GF_Box *parent, GF_List *list, GF_BitStream *bs){	u32 count, i;	GF_Box *a;	GF_Err e;	if (!list) return GF_BAD_PARAM;	count = gf_list_count(list);	for (i = 0; i < count; i++) {		a = (GF_Box *)gf_list_get(list, i);		if (a) {			e = gf_isom_box_write(a, bs);			if (e) return e;		}	}	return GF_OK;}GF_Err gf_isom_box_array_size(GF_Box *parent, GF_List *list){	GF_Err e;	u32 count, i;	GF_Box *a;	if (! list) return GF_BAD_PARAM;	count = gf_list_count(list);	for (i = 0; i < count; i++) {		a = (GF_Box *)gf_list_get(list, i);		if (a) {			e = gf_isom_box_size(a);			if (e) return e;			parent->size += a->size;		}	}	return GF_OK;}#endif //GPAC_READ_ONLYGF_Box *gf_isom_box_new(u32 boxType){	GF_Box *a;	switch (boxType) {	case GF_ISOM_BOX_TYPE_HINT:	case GF_ISOM_BOX_TYPE_DPND:	case GF_ISOM_BOX_TYPE_MPOD:	case GF_ISOM_BOX_TYPE_SYNC:	case GF_ISOM_BOX_TYPE_IPIR:	case GF_ISOM_BOX_TYPE_CHAP:		a = reftype_New();		if (a) a->type = boxType;		return a;	case GF_ISOM_BOX_TYPE_FREE: return free_New();	case GF_ISOM_BOX_TYPE_SKIP:		a = free_New();		if (a) a->type = GF_ISOM_BOX_TYPE_SKIP;		return a;	case GF_ISOM_BOX_TYPE_MDAT: return mdat_New();	case GF_ISOM_BOX_TYPE_MOOV: return moov_New();	case GF_ISOM_BOX_TYPE_MVHD: return mvhd_New();	case GF_ISOM_BOX_TYPE_MDHD: return mdhd_New();	case GF_ISOM_BOX_TYPE_VMHD: return vmhd_New();	case GF_ISOM_BOX_TYPE_SMHD: return smhd_New();	case GF_ISOM_BOX_TYPE_HMHD: return hmhd_New();	case GF_ISOM_BOX_TYPE_ODHD:	case GF_ISOM_BOX_TYPE_CRHD:	case GF_ISOM_BOX_TYPE_SDHD:	case GF_ISOM_BOX_TYPE_NMHD:		a = nmhd_New();		if (a) a->type = boxType;		return a;	case GF_ISOM_BOX_TYPE_STBL: return stbl_New();	case GF_ISOM_BOX_TYPE_DINF: return dinf_New();

⌨️ 快捷键说明

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