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

📄 loader_xmt.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 / Scene Management 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/scene_manager.h>#include <gpac/constants.h>#include <gpac/utf.h>#include <gpac/xml.h>#include <gpac/internal/bifs_dev.h>#include <gpac/internal/scenegraph_dev.h>#include <gpac/nodes_x3d.h>/*for QP types*/#include "../bifs/quant.h"typedef struct{	GF_Node *node;	GF_FieldInfo container_field;	GF_ChildNodeItem *last;} XMTNodeStack;typedef struct{		/*1: XMT-A, 2: X3D, 3: XMT-O (not supported yet) */	u32 doc_type;	/*0: not init, 1: header, 2: body*/	u32 doc_state;	u32 current_node_tag;	GF_SceneLoader *load;	GF_Err last_error;	GF_SAXParser *sax_parser;	XMTNodeStack *x3d_root;		/* stack of nodes for SAX parsing*/	GF_List *nodes;	/* stack of descriptors for SAX parsing*/	GF_List *descriptors;	GF_List *peeked_nodes;	GF_List *def_nodes;	GF_List *inserted_routes, *unresolved_routes;	/* OD and ESD links*/	GF_List *od_links, *esd_links;	/*set when parsing proto*/	GF_Proto *parsing_proto;	GF_ProtoFieldInterface *proto_field;	GF_StreamContext *scene_es;	GF_AUContext *scene_au;	u32 base_scene_id;	/*current scene command*/	GF_Command *command;	SFCommandBuffer *command_buffer;	GF_StreamContext *od_es;	GF_AUContext *od_au;	u32 base_od_id;	/*current od command*/	GF_ODCom *od_command;	/*current stream ID, AU time and RAP flag*/	u32 stream_id;	Double au_time;	Bool au_is_rap;	GF_List *script_to_load;} GF_XMTParser;typedef struct{	char *desc_name;	u32 ID;	/*store nodes refering to this URL*/	GF_List *mf_urls;	GF_ObjectDescriptor *od;} XMT_ODLink;typedef struct{	char *desc_name;	u32 ESID;	GF_ESD *esd;	char *OCR_Name;	char *Depends_Name;} XMT_ESDLink;static GF_Err xmt_report(GF_XMTParser *parser, GF_Err e, char *format, ...){#ifndef GPAC_DISABLE_LOG	if (gf_log_get_level() && (gf_log_get_tools() & GF_LOG_PARSER)) {		char szMsg[2048];		va_list args;		va_start(args, format);		vsprintf(szMsg, format, args);		va_end(args);		GF_LOG((u32) (e ? GF_LOG_ERROR : GF_LOG_WARNING), GF_LOG_PARSER, ("[XMT Parsing] %s (line %d)\n", szMsg, gf_xml_sax_get_line(parser->sax_parser)) );	}#endif	if (e) parser->last_error = e;	return e;}static void xmt_progress(void *cbk, u32 done, u32 total){	gf_set_progress("XMT Parsing", done, total);}static Bool xmt_esid_available(GF_XMTParser *parser, u16 ESID) {	u32 i;	XMT_ESDLink *esdl;	i=0;	while ((esdl = (XMT_ESDLink *)gf_list_enum(parser->esd_links, &i))) {		if (esdl->esd->ESID == ESID) return 0;	}	return 1;}static void xmt_new_od_link(GF_XMTParser *parser, GF_ObjectDescriptor *od, char *name, u32 ID){	u32 i, j, count;	XMT_ODLink *odl;	if (!ID) {		if (!strnicmp(name, "od", 2)) ID = atoi(name + 2);		else if (!strnicmp(name, "iod", 3)) ID = atoi(name+ 3);		/*be carefull, an url like "11-regression-test.mp4" will return 1 on sscanf :)*/		else if (sscanf(name, "%d", &ID) == 1) {			char szURL[20];			sprintf(szURL, "%d", ID);			if (strcmp(szURL, name)) {				ID = 0;			} else {				name = NULL;			}		}	}	count = gf_list_count(parser->od_links);	for (i=0; i<count; i++) {		odl = (XMT_ODLink*)gf_list_get(parser->od_links, i);		if ( (ID && (odl->ID == ID))			|| (odl->od == od)			|| (odl->desc_name && name && !strcmp(odl->desc_name, name))		) {			if (!odl->od) odl->od = od;			if (!odl->desc_name && name) odl->desc_name = strdup(name);			if (!od->objectDescriptorID) {				od->objectDescriptorID = ID;			} else if (ID && (od->objectDescriptorID != ID)) {				xmt_report(parser, GF_BAD_PARAM, "Conflicting OD IDs %d vs %d\n", ID, od->objectDescriptorID);			}						for (j=i+1; j<count; j++) {				XMT_ODLink *l2 = (XMT_ODLink*)gf_list_get(parser->od_links, j);				if (l2->od == od) {					odl->ID = od->objectDescriptorID = odl->od->objectDescriptorID;					gf_list_rem(parser->od_links, j);					if (l2->desc_name) free(l2->desc_name);					gf_list_del(l2->mf_urls);					free(l2);					break;				}			}			return;		}	}	GF_SAFEALLOC(odl, XMT_ODLink);	odl->mf_urls = gf_list_new();	odl->od = od;	if (ID) od->objectDescriptorID = ID;	if (name) odl->desc_name = strdup(name);	gf_list_add(parser->od_links, odl);}static void xmt_new_od_link_from_node(GF_XMTParser *parser, char *name, MFURL *url){	u32 i, ID;	XMT_ODLink *odl;	ID = 0;	if (!strnicmp(name, "od", 2)) ID = atoi(name + 2);	else if (!strnicmp(name, "iod", 3)) ID = atoi(name + 3);	/*be carefull, an url like "11-regression-test.mp4" will return 1 on sscanf :)*/	else if (sscanf(name, "%d", &ID) == 1) {		char szURL[20];		sprintf(szURL, "%d", ID);		if (strcmp(szURL, name)) {			ID = 0;		} else {			name = NULL;		}	}	else ID = 0;		i=0;	while ((odl = (XMT_ODLink*)gf_list_enum(parser->od_links, &i))) {		if ( (name && odl->desc_name && !strcmp(odl->desc_name, name))			|| (ID && odl->od && odl->od->objectDescriptorID==ID)			|| (ID && (odl->ID==ID))			) {			if (url && (gf_list_find(odl->mf_urls, url)<0) ) gf_list_add(odl->mf_urls, url);			return;		}	}	GF_SAFEALLOC(odl, XMT_ODLink);	odl->mf_urls = gf_list_new();	if (url) gf_list_add(odl->mf_urls, url);	if (ID) odl->ID = ID;	else odl->desc_name = strdup(name);	gf_list_add(parser->od_links, odl);}static void xmt_new_esd_link(GF_XMTParser *parser, GF_ESD *esd, char *desc_name, u32 binID){	u32 i, j;	XMT_ESDLink *esdl;	i=0;	while ((esdl = (XMT_ESDLink *)gf_list_enum(parser->esd_links, &i))) {		if (esdl->esd  && (esd!=esdl->esd)) continue;		if (!esdl->esd) {			if (!esdl->ESID || !desc_name || strcmp(esdl->desc_name, desc_name)) continue;			esdl->esd = esd;		}		if (binID) {			/*remove temp links*/			if (esdl->ESID == (u16) ( ( ((u32) esdl) >> 16) | ( ((u32)esdl) & 0x0000FFFF) ) ) {				GF_StreamContext *sc;				j=0;				while ((sc = (GF_StreamContext *)gf_list_enum(parser->load->ctx->streams, &j))) {					if (sc->ESID!=esdl->ESID) continue;					/*reassign*/					sc->ESID = binID;					break;				}			}			esdl->ESID = esdl->esd->ESID = binID;		}		if (desc_name && !esdl->desc_name) {			esdl->desc_name = strdup(desc_name);			if (!esdl->ESID && !strnicmp(desc_name, "es", 2)) esdl->ESID = atoi(&desc_name[2]);		}		return;	}	GF_SAFEALLOC(esdl, XMT_ESDLink);	esdl->esd = esd;	esd->ESID = esdl->ESID = binID;	if (desc_name) {		if (!esdl->ESID && !strnicmp(desc_name, "es", 2)) esdl->ESID = atoi(&desc_name[2]);		esdl->desc_name = strdup(desc_name);	}	if (!esd->ESID) {		esd->ESID = 1;		while (!xmt_esid_available(parser, esd->ESID)) esd->ESID++;		esdl->ESID = esd->ESID;	}	gf_list_add(parser->esd_links, esdl);}static Bool xmt_set_depend_id(GF_XMTParser *parser, GF_ESD *desc, char *es_name, Bool is_ocr_dep){	u32 i;	XMT_ESDLink *esdl;	if (!desc || !es_name) return 0;	i=0;	while ((esdl = (XMT_ESDLink *)gf_list_enum(parser->esd_links, &i))) {		if (esdl->esd == desc) {			if (is_ocr_dep)				esdl->OCR_Name = strdup(es_name);			else				esdl->Depends_Name = strdup(es_name);			return 1;		}	}	return 0;}static u32 xmt_get_od_id(GF_XMTParser *parser, char *od_name){	u32 i, ID;	XMT_ODLink *l;	if (sscanf(od_name, "%d", &ID)==1) return ID;	i=0;	while ((l = (XMT_ODLink*)gf_list_enum(parser->od_links, &i))) {		if (!l->od) continue;		if (l->desc_name && !strcmp(l->desc_name, od_name)) return l->od->objectDescriptorID;	}	return 0;}static u32 xmt_get_esd_id(GF_XMTParser *parser, char *esd_name){	u32 i, ID;	XMT_ESDLink *l;	if (sscanf(esd_name, "%d", &ID)==1) return ID;	i=0;	while ((l = (XMT_ESDLink *)gf_list_enum(parser->esd_links, &i))) {		if (!l->esd) continue;		if (l->desc_name && !strcmp(l->desc_name, esd_name)) return l->esd->ESID;	}	return 0;}static u32 xmt_locate_stream(GF_XMTParser *parser, char *stream_name){	XMT_ESDLink *esdl;	u32 i;	char szN[200];	i=0;	while ((esdl = (XMT_ESDLink *)gf_list_enum(parser->esd_links, &i))) {		if (esdl->desc_name && !strcmp(esdl->desc_name, stream_name)) return esdl->ESID;		if (esdl->ESID) {			sprintf(szN, "es%d", esdl->ESID);			if (!strcmp(szN, stream_name)) return esdl->ESID;			sprintf(szN, "%d", esdl->ESID);			if (!strcmp(szN, stream_name)) return esdl->ESID;		}	}	/*create a temp one*/	esdl = (XMT_ESDLink *)malloc(sizeof(XMT_ESDLink));	memset(esdl, 0, sizeof(XMT_ESDLink));	esdl->ESID = (u16) ( ((u32) esdl) >> 16) | ( ((u32)esdl) & 0x0000FFFF);	if (!strnicmp(stream_name, "es", 2)) esdl->ESID = atoi(&stream_name[2]);	esdl->desc_name = strdup(stream_name);	gf_list_add(parser->esd_links, esdl);	return esdl->ESID;}static Bool xmt_odid_available(GF_XMTParser *parser, u16 ODID) {	u32 i;	XMT_ODLink *l;	i=0;	while ((l = (XMT_ODLink*)gf_list_enum(parser->od_links, &i))) {		if (l->ID == ODID) return 0;		if (l->od && l->od->objectDescriptorID == ODID) return 0;	}	return 1;}static void xmt_resolve_od_links(GF_XMTParser *parser){	u32 i, j;	XMT_ESDLink *esdl, *esdl2;	XMT_ODLink *l;	char szURL[5000];	/*fix ESD IDs*/	i=0;	while ((esdl = (XMT_ESDLink *)gf_list_enum(parser->esd_links, &i))) {		if (!esdl->esd) {			xmt_report(parser, GF_BAD_PARAM, "Stream %s ID %d has no associated ES descriptor\n", esdl->desc_name ? esdl->desc_name : "", esdl->ESID);			i--;			gf_list_rem(parser->esd_links, i);			if (esdl->desc_name) free(esdl->desc_name);			free(esdl);			continue;		}		if (esdl->ESID) esdl->esd->ESID = esdl->ESID;		else if (!esdl->esd->ESID) {			u16 ESID = 1;			while (!xmt_esid_available(parser, ESID)) ESID++;			esdl->esd->ESID = ESID;		}	}	/*set OCR es ids*/	i=0;	while ((esdl = (XMT_ESDLink *)gf_list_enum(parser->esd_links, &i))) {		Bool use_old_fmt;		u16 ocr_id;		char szTest[50];		esdl->esd->OCRESID = 0;		if (!esdl->OCR_Name) continue;				use_old_fmt = 0;

⌨️ 快捷键说明

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