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

📄 ctx_load.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 / GPAC Scene Context loader module * *  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/terminal_dev.h>#include <gpac/scene_manager.h>#include <gpac/constants.h>#include <gpac/network.h>#include <gpac/nodes_mpeg4.h>typedef struct {	GF_InlineScene *inline_scene;	GF_Terminal *app;	GF_SceneManager *ctx;	GF_SceneLoader load;	char *file_name;	u32 file_size;	u32 load_flags;	u32 nb_streams;	u32 base_stream_id;	u32 last_check_time, last_check_size;	/*mp3 import from flash*/	GF_List *files_to_delete;	/*progressive loading support for XMT X3D*/	FILE *src;	u32 file_pos, sax_max_duration;	Bool progressive_support;} CTXLoadPriv;static GF_Err CTXLoad_GetCapabilities(GF_BaseDecoder *plug, GF_CodecCapability *cap){	cap->cap.valueInt = 0;	return GF_NOT_SUPPORTED;}static GF_Err CTXLoad_SetCapabilities(GF_BaseDecoder *plug, const GF_CodecCapability capability){	return GF_OK;}static void ODS_SetupOD(GF_InlineScene *is, GF_ObjectDescriptor *od){	GF_ObjectManager *odm;	odm = gf_is_find_odm(is, od->objectDescriptorID);	/*remove the old OD*/	if (odm) gf_odm_disconnect(odm, 1);	odm = gf_odm_new();	odm->OD = od;	odm->term = is->root_od->term;	odm->parentscene = is;	gf_list_add(is->ODlist, odm);	/*locate service owner*/	gf_odm_setup_object(odm, is->root_od->net_service);}static void CTXLoad_Reset(CTXLoadPriv *priv){	if (priv->ctx) gf_sm_del(priv->ctx);	priv->ctx = NULL;	gf_sg_reset(priv->inline_scene->graph);	if (priv->load_flags != 3) priv->load_flags = 0;	while (gf_list_count(priv->files_to_delete)) {		char *fileName = (char*)gf_list_get(priv->files_to_delete, 0);		gf_list_rem(priv->files_to_delete, 0);		gf_delete_file(fileName);		free(fileName);	}}void CTXLoad_OnActivate(GF_Node *node){	GF_InlineScene *is = (GF_InlineScene *) gf_node_get_private(node);	M_Conditional*c = (M_Conditional*)node;	/*always apply in parent graph to handle protos correctly*/	if (c->activate) gf_sg_command_apply_list(gf_node_get_graph(node), c->buffer.commandList, gf_is_get_time(is));}void CTXLoad_OnReverseActivate(GF_Node *node){	GF_InlineScene *is = (GF_InlineScene *) gf_node_get_private(node);	M_Conditional*c = (M_Conditional*)node;	/*always apply in parent graph to handle protos correctly*/	if (!c->reverseActivate) 		gf_sg_command_apply_list(gf_node_get_graph(node), c->buffer.commandList, gf_is_get_time(is));}void CTXLoad_NodeCallback(void *cbk, u32 type, GF_Node *node, void *param){	if ((type==GF_SG_CALLBACK_INIT) && (gf_node_get_tag(node) == TAG_MPEG4_Conditional) ) {		M_Conditional*c = (M_Conditional*)node;		c->on_activate = CTXLoad_OnActivate;		c->on_reverseActivate = CTXLoad_OnReverseActivate;		gf_node_set_private(node, cbk);	} else {		gf_term_node_callback(cbk, type, node, param);	}}static Bool CTXLoad_CheckDownload(CTXLoadPriv *priv){	u32 size;	FILE *f;	u32 now = gf_sys_clock();	if (!priv->file_size && (now - priv->last_check_time < 1000) ) return 0;	f = fopen(priv->file_name, "rt");	fseek(f, 0, SEEK_END);	size = ftell(f);	fclose(f);	/*we MUST have a complete file for now ...*/	if (!priv->file_size) {		if (priv->last_check_size == size) return 1;		priv->last_check_size = size;		priv->last_check_time = now;	} else {		if (size==priv->file_size) return 1;	}	return 0;}static GF_Err CTXLoad_Setup(GF_BaseDecoder *plug){	CTXLoadPriv *priv = (CTXLoadPriv *)plug->privateStack;	if (!priv->file_name) return GF_BAD_PARAM;	priv->ctx = gf_sm_new(priv->inline_scene->graph);	memset(&priv->load, 0, sizeof(GF_SceneLoader));	priv->load.ctx = priv->ctx;	priv->load.scene_graph = priv->inline_scene->graph;	priv->load.fileName = priv->file_name;	priv->load.flags = GF_SM_LOAD_FOR_PLAYBACK;	priv->load.localPath = gf_modules_get_option((GF_BaseInterface *)plug, "General", "CacheDirectory");	priv->load.swf_import_flags = GF_SM_SWF_STATIC_DICT | GF_SM_SWF_QUAD_CURVE | GF_SM_SWF_SCALABLE_LINE;	return GF_OK;}static GF_Err CTXLoad_AttachStream(GF_BaseDecoder *plug, 									 u16 ES_ID, 									 char *decSpecInfo, 									 u32 decSpecInfoSize, 									 u16 DependsOnES_ID,									 u32 objectTypeIndication, 									 Bool Upstream){	const char *ext;	GF_BitStream *bs;	u32 size;	CTXLoadPriv *priv = (CTXLoadPriv *)plug->privateStack;	if (Upstream) return GF_NOT_SUPPORTED;	/*animation stream like*/	if (priv->ctx) {		GF_StreamContext *sc;		u32 i = 0;		while ((sc = (GF_StreamContext *)gf_list_enum(priv->ctx->streams, &i))) {			if (ES_ID == sc->ESID) {				priv->nb_streams++;				return GF_OK;			}		}		return GF_NON_COMPLIANT_BITSTREAM;	}	/*main dummy stream we need a dsi*/	if (!decSpecInfo) 		return GF_NON_COMPLIANT_BITSTREAM;	bs = gf_bs_new(decSpecInfo, decSpecInfoSize, GF_BITSTREAM_READ);	priv->file_size = gf_bs_read_u32(bs);	gf_bs_del(bs);	size = decSpecInfoSize - sizeof(u32);	priv->file_name = (char *) malloc(sizeof(char)*(1 + size) );	memcpy(priv->file_name, decSpecInfo + sizeof(u32),  sizeof(char)*(decSpecInfoSize - sizeof(u32)) );	priv->file_name[size] = 0;	priv->nb_streams = 1;	priv->load_flags = 0;	priv->base_stream_id = ES_ID;		CTXLoad_Setup(plug);	priv->progressive_support = 0;	priv->sax_max_duration = 0;	ext = strrchr(priv->file_name, '.');	if (!ext) return GF_OK;	ext++;	if (!stricmp(ext, "xmt") || !stricmp(ext, "xmtz") || !stricmp(ext, "xmta") 		|| !stricmp(ext, "x3d") || !stricmp(ext, "x3dz")	) {		ext = gf_modules_get_option((GF_BaseInterface *)plug, "SAXLoader", "Progressive");		priv->progressive_support = (ext && !stricmp(ext, "yes")) ? 1 : 0;	}	if (priv->progressive_support) {		ext = gf_modules_get_option((GF_BaseInterface *)plug, "SAXLoader", "MaxDuration");		if (ext) priv->sax_max_duration = atoi(ext);	}	return GF_OK;}static GF_Err CTXLoad_DetachStream(GF_BaseDecoder *plug, u16 ES_ID){	CTXLoadPriv *priv = (CTXLoadPriv *)plug->privateStack;	priv->nb_streams --;	return GF_OK;}static GF_Err CTXLoad_AttachScene(GF_SceneDecoder *plug, GF_InlineScene *scene, Bool is_scene_decoder){	CTXLoadPriv *priv = (CTXLoadPriv *)plug->privateStack;	if (priv->ctx) return GF_BAD_PARAM;	priv->inline_scene = scene;	priv->app = scene->root_od->term;	gf_sg_set_node_callback(scene->graph, CTXLoad_NodeCallback);	return GF_OK;}static GF_Err CTXLoad_ReleaseScene(GF_SceneDecoder *plug){	CTXLoad_Reset((CTXLoadPriv *) plug->privateStack);	return GF_OK;}static Bool CTXLoad_StreamInRootOD(GF_ObjectDescriptor *od, u32 ESID){	u32 i, count;	/*no root, only one stream possible*/	if (!od) return 1;	count = gf_list_count(od->ESDescriptors);	/*idem*/	if (!count) return 1;	for (i=0; i<count; i++) {		GF_ESD *esd = (GF_ESD *)gf_list_get(od->ESDescriptors, i);		if (esd->ESID==ESID) return 1;	}	return 0;}static GF_SceneGraph *CTXLoad_GetProtoLib(void *cbk, MFURL *lib_url){	CTXLoadPriv *priv = (CTXLoadPriv *)cbk;	return gf_is_get_proto_lib(priv->inline_scene, lib_url);}Double CTXLoad_GetVRMLTime(void *cbk){	u32 secs, msecs;	Double res;	gf_utc_time_since_1970(&secs, &msecs);	res = msecs;	res /= 1000;	res += secs;	return res;}static void CTXLoad_CheckStreams(CTXLoadPriv *priv ){	u32 i, j, max_dur;	GF_AUContext *au;	GF_StreamContext *sc;	max_dur = 0;	i=0;	while ((sc = (GF_StreamContext *)gf_list_enum(priv->ctx->streams, &i))) {		/*all streams in root OD are handled with ESID 0 to differentiate with any animation streams*/		if (CTXLoad_StreamInRootOD(priv->ctx->root_od, sc->ESID)) sc->ESID = 0;		if (!sc->timeScale) sc->timeScale = 1000;		j=0;		while ((au = (GF_AUContext *)gf_list_enum(sc->AUs, &j))) {			if (!au->timing) au->timing = (u64) (sc->timeScale*au->timing_sec);		}		if (au && !sc->ESID && (au->timing>max_dur)) max_dur = (u32) (au->timing * 1000 / sc->timeScale);	}	if (max_dur) {		priv->inline_scene->root_od->duration = max_dur;		gf_is_set_duration(priv->inline_scene);	}}static GF_Err CTXLoad_ProcessData(GF_SceneDecoder *plug, char *inBuffer, u32 inBufferLength, 								u16 ES_ID, u32 stream_time, u32 mmlevel){	GF_Err e = GF_OK;	u32 i, j, k, nb_updates;	GF_AUContext *au;	Bool can_delete_com;	GF_StreamContext *sc;	CTXLoadPriv *priv = (CTXLoadPriv *)plug->privateStack;	/*something failed*/	if (priv->load_flags==3) return GF_EOS;	/*this signals main scene deconnection, destroy the context if needed*/	assert(ES_ID);	if (!priv->ctx) {		e = CTXLoad_Setup((GF_BaseDecoder *)plug);		if (e) return e;	}	if (priv->load_flags != 2) {		if (priv->progressive_support) {			u32 entry_time;			char file_buf[4096+1];			if (!priv->src) {				priv->src = fopen(priv->file_name, "rb");				if (!priv->src) return GF_URL_ERROR;				priv->file_pos = 0;			}			priv->load.type = GF_SM_LOAD_XMTA;			e = GF_OK;			entry_time = gf_sys_clock();			fseek(priv->src, priv->file_pos, SEEK_SET);			while (1) {				u32 diff, nb_read;				nb_read = fread(file_buf, 1, 4096, priv->src);				file_buf[nb_read] = 0;				if (!nb_read) {					if (priv->file_pos==priv->file_size) {						fclose(priv->src);						priv->src = NULL;						priv->load_flags = 2;						gf_sm_load_done(&priv->load);						break;					}					break;				}

⌨️ 快捷键说明

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