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

📄 ctx_load.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
				e = gf_sm_load_string(&priv->load, file_buf, 0);				priv->file_pos += nb_read;				if (e) break;				diff = gf_sys_clock() - entry_time;				if (diff > priv->sax_max_duration) break;			}			if (!priv->inline_scene->graph_attached) {				gf_sg_set_scene_size_info(priv->inline_scene->graph, priv->ctx->scene_width, priv->ctx->scene_height, priv->ctx->is_pixel_metrics);				gf_is_attach_to_renderer(priv->inline_scene);				CTXLoad_CheckStreams(priv);			}		}		/*load first frame only*/		else if (!priv->load_flags) {			/*we need the whole file*/			if (!CTXLoad_CheckDownload(priv)) return GF_OK;			priv->load_flags = 1;			e = gf_sm_load_init(&priv->load);			if (!e) {				gf_sg_set_scene_size_info(priv->inline_scene->graph, priv->ctx->scene_width, priv->ctx->scene_height, priv->ctx->is_pixel_metrics);				/*VRML, override base clock*/				if ((priv->load.type==GF_SM_LOAD_VRML) || (priv->load.type==GF_SM_LOAD_X3DV) || (priv->load.type==GF_SM_LOAD_X3D)) {					gf_sg_set_scene_time_callback(priv->inline_scene->graph, CTXLoad_GetVRMLTime);					gf_sg_set_proto_loader(priv->inline_scene->graph, CTXLoad_GetProtoLib);				}			}		} 		/*load the rest*/		else {			priv->load_flags = 2;			e = gf_sm_load_run(&priv->load);			gf_sm_load_done(&priv->load);		}		if (e) {			gf_sm_load_done(&priv->load);			gf_sm_del(priv->ctx);			priv->ctx = NULL;			priv->load_flags = 3;			return e;		}		/*and figure out duration of root scene, and take care of XMT timing*/		if (priv->load_flags==2) {			CTXLoad_CheckStreams(priv);			if (!gf_list_count(priv->ctx->streams)) {				gf_is_attach_to_renderer(priv->inline_scene);			}		}	}	nb_updates = 0;	i=0;	while ((sc = (GF_StreamContext *)gf_list_enum(priv->ctx->streams, &i))) {		/*not our stream*/		if (sc->ESID && (sc->ESID != ES_ID)) continue;		/*not the base stream*/		if (!sc->ESID && (priv->base_stream_id != ES_ID)) continue;		/*handle SWF media extraction*/		if ((sc->streamType == GF_STREAM_OD) && (priv->load_flags==1)) continue;		/*check for seek*/		if (sc->last_au_time > 1 + stream_time) {			/*root streams shall not seek this way*/			if (!sc->ESID) assert(0);			/*on other streams, we assume the stream is 100% RAP wrt to the base stream*/			else {				sc->last_au_time = 0;			}		}		can_delete_com = 0;		if (!sc->ESID && (priv->load_flags==2)) can_delete_com = 1;		/*we're in the right stream, apply update*/		j=0;		while ((au = (GF_AUContext *)gf_list_enum(sc->AUs, &j))) {			u32 au_time = (u32) (au->timing*1000/sc->timeScale);			if (au_time + 1 <= sc->last_au_time) {				/*remove first replace command*/				if (can_delete_com && (sc->streamType==GF_STREAM_SCENE)) {					while (gf_list_count(au->commands)) {						GF_Command *com = (GF_Command *)gf_list_get(au->commands, 0);						gf_list_rem(au->commands, 0);						gf_sg_command_del(com);					}					j--;					gf_list_rem(sc->AUs, j);					gf_list_del(au->commands);					free(au);				}				continue;			}			if (au_time > stream_time) {				nb_updates++;				break;			}			if (sc->streamType == GF_STREAM_SCENE) {				GF_Command *com;				/*apply the commands*/				k=0;				while ((com = (GF_Command *)gf_list_enum(au->commands, &k))) {					e = gf_sg_command_apply(priv->inline_scene->graph, com, 0);					if (e) break;					/*remove commands on base layer*/					if (can_delete_com) {						k--;						gf_list_rem(au->commands, k);						gf_sg_command_del(com);					}				}			} 			else if (sc->streamType == GF_STREAM_OD) {				/*apply the commands*/				while (gf_list_count(au->commands)) {					Bool keep_com = 0;					GF_ODCom *com = (GF_ODCom *)gf_list_get(au->commands, 0);					gf_list_rem(au->commands, 0);					switch (com->tag) {					case GF_ODF_OD_UPDATE_TAG:					{						GF_ODUpdate *odU = (GF_ODUpdate *)com;						while (gf_list_count(odU->objectDescriptors)) {							GF_ESD *esd;							char *remote;							GF_MuxInfo *mux = NULL;							GF_ObjectDescriptor *od = (GF_ObjectDescriptor *)gf_list_get(odU->objectDescriptors, 0);							gf_list_rem(odU->objectDescriptors, 0);							/*we can only work with single-stream ods*/							esd = (GF_ESD*)gf_list_get(od->ESDescriptors, 0);							if (!esd) {								if (od->URLString) {									ODS_SetupOD(priv->inline_scene, od);								} else {									gf_odf_desc_del((GF_Descriptor *) od);								}								continue;							}							/*fix OCR dependencies*/							if (CTXLoad_StreamInRootOD(priv->ctx->root_od, esd->OCRESID)) esd->OCRESID = priv->base_stream_id;							/*forbidden if ESD*/							if (od->URLString) {								gf_odf_desc_del((GF_Descriptor *) od);								continue;							}							/*look for MUX info*/							k=0;							while ((mux = (GF_MuxInfo*)gf_list_enum(esd->extensionDescriptors, &k))) {								if (mux->tag == GF_ODF_MUXINFO_TAG) break;								mux = NULL;							}							/*we need a mux if not animation stream*/							if (!mux || !mux->file_name) {								/*only animation streams are handled*/								if (!esd->decoderConfig) {									gf_odf_desc_del((GF_Descriptor *) od);								} else if (esd->decoderConfig->streamType==GF_STREAM_SCENE) {									/*set ST to private scene to get sure the stream will be redirected to us*/									esd->decoderConfig->streamType = GF_STREAM_PRIVATE_SCENE;									esd->dependsOnESID = priv->base_stream_id;									ODS_SetupOD(priv->inline_scene, od);								} else if (esd->decoderConfig->streamType==GF_STREAM_INTERACT) {									GF_UIConfig *cfg = (GF_UIConfig *) esd->decoderConfig->decoderSpecificInfo;									gf_odf_encode_ui_config(cfg, &esd->decoderConfig->decoderSpecificInfo);									gf_odf_desc_del((GF_Descriptor *) cfg);									ODS_SetupOD(priv->inline_scene, od);								} else {									gf_odf_desc_del((GF_Descriptor *) od);								}								continue;							}							/*text import*/							if (mux->textNode) {#ifdef GPAC_READ_ONLY								gf_odf_desc_del((GF_Descriptor *) od);								continue;#else								e = gf_sm_import_bifs_subtitle(priv->ctx, esd, mux);								if (e) {									e = GF_OK;									gf_odf_desc_del((GF_Descriptor *) od);									continue;								}								/*set ST to private scene and dependency to base to get sure the stream will be redirected to us*/								esd->decoderConfig->streamType = GF_STREAM_PRIVATE_SCENE;								esd->dependsOnESID = priv->base_stream_id;								ODS_SetupOD(priv->inline_scene, od);								continue;#endif							}							/*soundstreams are a bit of a pain, they may be declared before any data gets written*/							if (mux->delete_file) {								FILE *t = fopen(mux->file_name, "rb");								if (!t) {									keep_com = 1;									gf_list_insert(odU->objectDescriptors, od, 0);									break;								}								fclose(t);							}							/*remap to remote URL*/							remote = strdup(mux->file_name);							k = od->objectDescriptorID;							/*if files were created we'll have to clean up (swf import)*/							if (mux->delete_file) gf_list_add(priv->files_to_delete, strdup(remote));							gf_odf_desc_del((GF_Descriptor *) od);							od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG);							od->URLString = remote;							od->objectDescriptorID = k;							ODS_SetupOD(priv->inline_scene, od);						}						if (keep_com) break;					}						break;					case GF_ODF_OD_REMOVE_TAG:					{						GF_ODRemove *odR = (GF_ODRemove*)com;						for (k=0; k<odR->NbODs; k++) {							GF_ObjectManager *odm = gf_is_find_odm(priv->inline_scene, odR->OD_ID[k]);							if (odm) gf_odm_disconnect(odm, 1);						}					}						break;					default:						break;					}					if (keep_com) {						gf_list_insert(au->commands, com, 0);						break;					} else {						gf_odf_com_del(&com);					}					if (e) break;				}			}			sc->last_au_time = au_time + 1;			/*attach graph to renderer*/			gf_is_attach_to_renderer(priv->inline_scene);			if (e) return e;			/*for root streams remove completed AUs (no longer needed)*/			if (!sc->ESID && !gf_list_count(au->commands) ) {				j--;				gf_list_rem(sc->AUs, j);				gf_list_del(au->commands);				free(au);			}		}	}	if (e) return e;	if ((priv->load_flags==2) && !nb_updates) return GF_EOS;	return GF_OK;}const char *CTXLoad_GetName(struct _basedecoder *plug){	CTXLoadPriv *priv = (CTXLoadPriv *)plug->privateStack;	switch (priv->load.type) {	case GF_SM_LOAD_BT: return "MPEG-4 BT Parser";	case GF_SM_LOAD_VRML: return "VRML 97 Parser";	case GF_SM_LOAD_X3DV: return "X3D (VRML Syntax) Parser";	case GF_SM_LOAD_XMTA: return "XMT-A Parser";	case GF_SM_LOAD_X3D: return "X3D (XML Syntax) Parser";	case GF_SM_LOAD_SWF: return "Flash (SWF) Emulator";	case GF_SM_LOAD_XSR: return "LASeRML Loader";	case GF_SM_LOAD_MP4: return "MP4 Memory Loader";	default: return "Undetermined";	}}Bool CTXLoad_CanHandleStream(GF_BaseDecoder *ifce, u32 StreamType, u32 ObjectType, char *decSpecInfo, u32 decSpecInfoSize, u32 PL){	if (StreamType==GF_STREAM_PRIVATE_SCENE) {		if (ObjectType==1) return 1;		/*LASeR ML: we use this plugin since it has command handling*/		if (ObjectType==3) return 1;	}	/*SVG*/	//if ((StreamType==GF_STREAM_PRIVATE_SCENE) && (ObjectType==2)) return 1;	return 0;}void DeleteContextLoader(GF_BaseDecoder *plug){	CTXLoadPriv *priv = (CTXLoadPriv *)plug->privateStack;	if (priv->file_name) free(priv->file_name);	assert(!priv->ctx);	gf_list_del(priv->files_to_delete);	free(priv);	free(plug);}GF_BaseDecoder *NewContextLoader(){	CTXLoadPriv *priv;	GF_SceneDecoder *tmp;		GF_SAFEALLOC(tmp, GF_SceneDecoder);	GF_SAFEALLOC(priv, CTXLoadPriv);	priv->files_to_delete = gf_list_new();	tmp->privateStack = priv;	tmp->AttachStream = CTXLoad_AttachStream;	tmp->DetachStream = CTXLoad_DetachStream;	tmp->GetCapabilities = CTXLoad_GetCapabilities;	tmp->SetCapabilities = CTXLoad_SetCapabilities;	tmp->ProcessData = CTXLoad_ProcessData;	tmp->AttachScene = CTXLoad_AttachScene;	tmp->ReleaseScene = CTXLoad_ReleaseScene;	tmp->GetName = CTXLoad_GetName;	tmp->CanHandleStream = CTXLoad_CanHandleStream;	GF_REGISTER_MODULE_INTERFACE(tmp, GF_SCENE_DECODER_INTERFACE, "GPAC Context Loader", "gpac distribution")	return (GF_BaseDecoder*)tmp;}GF_EXPORTBool QueryInterface(u32 InterfaceType){	switch (InterfaceType) {	case GF_SCENE_DECODER_INTERFACE:		return 1;	default:		return 0;	}}GF_EXPORTGF_BaseInterface *LoadInterface(u32 InterfaceType){	switch (InterfaceType) {	case GF_SCENE_DECODER_INTERFACE: return (GF_BaseInterface *)NewContextLoader();	default:		return NULL;	}}GF_EXPORTvoid ShutdownInterface(GF_BaseInterface *ifce){	switch (ifce->InterfaceType) {	case GF_SCENE_DECODER_INTERFACE:		DeleteContextLoader((GF_BaseDecoder *)ifce);		break;	}}

⌨️ 快捷键说明

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