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

📄 inline.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Jean Le Feuvre 2000-2005  *					All rights reserved * *  This file is part of GPAC / Media terminal 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.  * *//*for OD service types*/#include <gpac/constants.h>#include <gpac/internal/terminal_dev.h>#include "media_control.h"/*for inline scene rendering*/#include <gpac/renderer.h>void MO_UpdateCaps(GF_MediaObject *mo);/*extern proto fetcher*/typedef struct{	MFURL *url;	GF_MediaObject *mo;} ProtoLink;GF_EXPORTDouble gf_is_get_time(void *_is){	u32 ret;	GF_Clock *ck;	GF_InlineScene *is = (GF_InlineScene *)_is;	assert(is);	ck = is->scene_codec ? is->scene_codec->ck : is->dyn_ck;	if (!ck) return 0.0;	ret = gf_clock_time(ck);	if (is->root_od->media_stop_time && (is->root_od->media_stop_time<ret)) ret = (u32) is->root_od->media_stop_time;	return ret/1000.0;}GF_InlineScene *gf_is_new(GF_InlineScene *parentScene){	GF_InlineScene *tmp;	GF_SAFEALLOC(tmp, GF_InlineScene);	if (! tmp) return NULL;	tmp->ODlist = gf_list_new();	tmp->media_objects = gf_list_new();	tmp->extern_protos = gf_list_new();	tmp->inline_nodes = gf_list_new();	tmp->extra_scenes = gf_list_new();	/*init inline scene*/	if (parentScene) {		tmp->graph = gf_sg_new_subscene(parentScene->graph);	} else {		tmp->graph = gf_sg_new();	}	gf_sg_set_private(tmp->graph, tmp);	gf_sg_set_node_callback(tmp->graph, gf_term_node_callback);	gf_sg_set_scene_time_callback(tmp->graph, gf_is_get_time);	gf_sg_set_proto_loader(tmp->graph, gf_is_get_proto_lib);	return tmp;}void gf_is_del(GF_InlineScene *is){	gf_list_del(is->ODlist);	gf_list_del(is->inline_nodes);	assert(!gf_list_count(is->extra_scenes) );	gf_list_del(is->extra_scenes);	while (gf_list_count(is->extern_protos)) {		ProtoLink *pl = (ProtoLink *)gf_list_get(is->extern_protos, 0);		gf_list_rem(is->extern_protos, 0);		free(pl);	}	gf_list_del(is->extern_protos);	/*delete scene decoder */	if (is->scene_codec) {		GF_SceneDecoder *dec = (GF_SceneDecoder *)is->scene_codec->decio;		/*make sure the scene codec doesn't have anything left in the scene graph*/		if (dec->ReleaseScene) dec->ReleaseScene(dec);		gf_term_remove_codec(is->root_od->term, is->scene_codec);		gf_codec_del(is->scene_codec);		/*reset pointer to NULL in case nodes try to access scene time*/		is->scene_codec = NULL;	}	/*delete the scene graph*/	gf_sg_del(is->graph);	if (is->od_codec) {		gf_term_remove_codec(is->root_od->term, is->od_codec);		gf_codec_del(is->od_codec);		is->od_codec = NULL;	}	/*don't touch the root_od, will be deleted by the parent scene*/	/*clean all remaining associations*/	while (gf_list_count(is->media_objects)) {		GF_MediaObject *obj = (GF_MediaObject *)gf_list_get(is->media_objects, 0);		if (obj->odm) obj->odm->mo = NULL;		gf_list_rem(is->media_objects, 0);		gf_sg_vrml_mf_reset(&obj->URLs, GF_SG_VRML_MFURL);		free(obj);	}	gf_list_del(is->media_objects);	if (is->audio_url.url) free(is->audio_url.url);	if (is->visual_url.url) free(is->visual_url.url);	if (is->text_url.url) free(is->text_url.url);	free(is);}GF_EXPORTGF_ObjectManager *gf_is_find_odm(GF_InlineScene *is, u16 OD_ID){	GF_ObjectManager *odm;	u32 i=0;	while ((odm = (GF_ObjectManager *)gf_list_enum(is->ODlist, &i))) {		if (odm->OD->objectDescriptorID == OD_ID) return odm;	}	return NULL;}void gf_is_disconnect(GF_InlineScene *is, Bool for_shutdown){	GF_MediaObject *obj;	GF_Node *root_node;	GF_ObjectManager *odm;	GF_SceneDecoder *dec = NULL;	if (is->scene_codec) dec = (GF_SceneDecoder *)is->scene_codec->decio;	gf_term_lock_renderer(is->root_od->term, 1);		/*disconnect / kill all objects BEFORE reseting the scene graph since we have 	potentially registered Inline nodes of the graph with the sub-scene*/	if (!for_shutdown && is->static_media_ressources) {		u32 i=0;		/*stop all objects but DON'T DESTROY THEM*/		while ((odm = (GF_ObjectManager *)gf_list_enum(is->ODlist, &i))) {			if (odm->state) gf_odm_disconnect(odm, 0);		}		/*reset all stream associations*/		i=0;		while ((obj = (GF_MediaObject*)gf_list_enum(is->media_objects, &i))) {			gf_sg_vrml_mf_reset(&obj->URLs, GF_SG_VRML_MFURL);		}	} else {		while (gf_list_count(is->ODlist)) {			odm = (GF_ObjectManager *)gf_list_get(is->ODlist, 0);			gf_odm_disconnect(odm, (for_shutdown || !is->static_media_ressources) ? 1 : 0);		}	}		root_node = gf_sg_get_root_node(is->graph);	while (gf_list_count(is->inline_nodes)) {		GF_Node *n = (GF_Node *)gf_list_get(is->inline_nodes, 0);		gf_list_rem(is->inline_nodes, 0);		gf_node_set_private(n, NULL);	}	if (is->graph_attached && (is->root_od->term->root_scene == is)) {		gf_sr_set_scene(is->root_od->term->renderer, NULL);	}	/*release the scene*/	if (dec && dec->ReleaseScene) dec->ReleaseScene(dec);	gf_sg_reset(is->graph);	is->graph_attached = 0;		gf_term_lock_renderer(is->root_od->term, 0);	assert(!gf_list_count(is->extra_scenes) );	/*reset statc ressource flag since we destroyed scene objects*/	is->static_media_ressources = 0;	/*remove stream associations*/	while (gf_list_count(is->media_objects)) {		obj = (GF_MediaObject*)gf_list_get(is->media_objects, 0);		gf_list_rem(is->media_objects, 0);		if (obj->odm) obj->odm->mo = NULL;		gf_sg_vrml_mf_reset(&obj->URLs, GF_SG_VRML_MFURL);		free(obj);	}}static void IS_InsertObject(GF_InlineScene *is, GF_MediaObject *mo, Bool lock_timelines, GF_MediaObject *sync_ref){	GF_ObjectManager *root_od;	GF_ObjectManager *odm;	char *url;	if (!mo || !is) return;	odm = gf_odm_new();	/*remember OD*/	odm->mo = mo;	mo->odm = odm;	odm->parentscene = is;	odm->OD = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG);	odm->OD->objectDescriptorID = GF_ESM_DYNAMIC_OD_ID;	odm->parentscene = is;	odm->term = is->root_od->term;	root_od = is->root_od;	url = mo->URLs.vals[0].url;	if (!stricmp(url, "KeySensor")) {		GF_ESD *esd = gf_odf_desc_esd_new(0);		esd->decoderConfig->streamType = GF_STREAM_INTERACT;		esd->decoderConfig->objectTypeIndication = 1;		free(esd->decoderConfig->decoderSpecificInfo->data);		esd->decoderConfig->decoderSpecificInfo->data = strdup(" KeySensor");		esd->decoderConfig->decoderSpecificInfo->data[0] = 9;		esd->decoderConfig->decoderSpecificInfo->dataLength = 10;		esd->ESID = esd->OCRESID = 65534;		gf_list_add(odm->OD->ESDescriptors, esd);	} else if (!stricmp(url, "StringSensor")) {		GF_ESD *esd = gf_odf_desc_esd_new(0);		esd->decoderConfig->streamType = GF_STREAM_INTERACT;		esd->decoderConfig->objectTypeIndication = 1;		free(esd->decoderConfig->decoderSpecificInfo->data);		esd->decoderConfig->decoderSpecificInfo->data = strdup(" StringSensor");		esd->decoderConfig->decoderSpecificInfo->data[0] = 12;		esd->decoderConfig->decoderSpecificInfo->dataLength = 13;		esd->ESID = esd->OCRESID = 65534;		gf_list_add(odm->OD->ESDescriptors, esd);	} else if (!stricmp(url, "Mouse")) {		GF_ESD *esd = gf_odf_desc_esd_new(0);		esd->decoderConfig->streamType = GF_STREAM_INTERACT;		esd->decoderConfig->objectTypeIndication = 1;		free(esd->decoderConfig->decoderSpecificInfo->data);		esd->decoderConfig->decoderSpecificInfo->data = strdup(" Mouse");		esd->decoderConfig->decoderSpecificInfo->data[0] = 5;		esd->decoderConfig->decoderSpecificInfo->dataLength = 6;		esd->ESID = esd->OCRESID = 65534;		gf_list_add(odm->OD->ESDescriptors, esd);	} else {		if (mo->type==GF_MEDIA_OBJECT_SCENE) {			char *frag = strrchr(mo->URLs.vals[0].url, '#');			if (frag) frag[0] = 0;			odm->OD->URLString = strdup(mo->URLs.vals[0].url);			if (frag) frag[0] = '#';		} else {			odm->OD->URLString = strdup(mo->URLs.vals[0].url);		}		if (lock_timelines) odm->flags |= GF_ODM_INHERIT_TIMELINE;	}	/*HACK - temp storage of sync ref*/	if (sync_ref) odm->ocr_codec = (struct _generic_codec *)sync_ref;	gf_list_add(is->ODlist, odm);	gf_odm_setup_object(odm, root_od->net_service);}static void IS_ReinsertObject(GF_InlineScene *is, GF_MediaObject *mo){	u32 i;	free(mo->URLs.vals[0].url);	mo->URLs.vals[0].url = NULL;	for (i=0; i<mo->URLs.count-1; i++) mo->URLs.vals[i].url = mo->URLs.vals[i+1].url;	mo->URLs.vals[mo->URLs.count-1].url = NULL;	mo->URLs.count-=1;	IS_InsertObject(is, mo, 0, NULL);}void gf_is_remove_object(GF_InlineScene *is, GF_ObjectManager *odm, Bool for_shutdown){	u32 i;	GF_MediaObject *obj;	gf_list_del_item(is->ODlist, odm);	i=0;	while ((obj = (GF_MediaObject*)gf_list_enum(is->media_objects, &i))) {		if (			/*assigned object*/			(obj->odm==odm) || 			/*remote OD*/			((obj->OD_ID!=GF_ESM_DYNAMIC_OD_ID) && odm->OD && (obj->OD_ID == odm->OD->objectDescriptorID) ) ||			/*dynamic OD*/			(obj->URLs.count && odm->OD && odm->OD->URLString && !stricmp(obj->URLs.vals[0].url, odm->OD->URLString)) 		) {			gf_odm_lock(odm, 1);			obj->flags = 0;			if (obj->odm) obj->odm->mo = NULL;			odm->mo = NULL;			obj->odm = NULL;			obj->frame = NULL;			obj->framesize = obj->timestamp = 0;			gf_odm_lock(odm, 0);			/*if graph not attached we can remove the link (this is likely scene shutdown for some error)*/			if (!is->graph_attached) {				ProtoLink *pl;				u32 j=0;				while ((pl = (ProtoLink *)gf_list_enum(is->extern_protos, &j))) {					if (pl->mo==obj) {						pl->mo = NULL;						break;					}				}				gf_list_rem(is->media_objects, i-1);				gf_sg_vrml_mf_reset(&obj->URLs, GF_SG_VRML_MFURL);				free(obj);			} else if (!for_shutdown) {				/*if dynamic OD and more than 1 URLs resetup*/				if ((obj->OD_ID==GF_ESM_DYNAMIC_OD_ID) && (obj->URLs.count>1)) IS_ReinsertObject(is, obj);			}			return;		}	}}u32 URL_GetODID(MFURL *url){	u32 i, j, tmpid;	char *str, *s_url;	u32 id = 0;	if (!url) return 0;		for (i=0; i<url->count; i++) {		if (url->vals[i].OD_ID) {			/*works because OD ID 0 is forbidden in MPEG4*/			if (!id) {				id = url->vals[i].OD_ID;			}			/*bad url, only one object can be described in MPEG4 urls*/			else if (id != url->vals[i].OD_ID) return 0;		} else if (url->vals[i].url && strlen(url->vals[i].url)) {			/*format: od:ID or od:ID#segment - also check for "ID" in case...*/			str = url->vals[i].url;			if (!strnicmp(str, "od:", 3)) str += 3;			/*remove segment info*/			s_url = strdup(str);			j = 0;			while (j<strlen(s_url)) {				if (s_url[j]=='#') {					s_url[j] = 0;					break;				}				j++;			}			j = sscanf(s_url, "%d", &tmpid);			/*be carefull, an url like "11-regression-test.mp4" will return 1 on sscanf :)*/			if (j==1) {				char szURL[20];				sprintf(szURL, "%d", tmpid);				if (stricmp(szURL, s_url)) j = 0;			}			free(s_url);			if (j!= 1) {				/*dynamic OD if only one URL specified*/				if (!i) return GF_ESM_DYNAMIC_OD_ID;				/*otherwise ignore*/				continue;			}			if (!id) {				id = tmpid;				continue;			}			/*bad url, only one object can be described in MPEG4 urls*/			else if (id != tmpid) return 0;		}	}	return id;}//browse all channels and update buffering infovoid gf_is_buffering_info(GF_InlineScene *is){	u32 i, j, max_buffer, cur_buffer;	GF_Channel *ch;	GF_Event evt;	GF_ObjectManager *odm;	if (!is) return;	max_buffer = cur_buffer = 0;	/*get buffering on root OD*/	j=0;	while ((ch = (GF_Channel*)gf_list_enum(is->root_od->channels, &j))) {		/*count only re-buffering channels*/		if (!ch->BufferOn) continue;		max_buffer += ch->MaxBuffer;		cur_buffer += (ch->BufferTime>0) ? ch->BufferTime : 1;	}	/*get buffering on all ODs*/	i=0;	while ((odm = (GF_ObjectManager*)gf_list_enum(is->ODlist, &i))) {		if (!odm->codec) continue;		j=0;		while ((ch = (GF_Channel*)gf_list_enum(odm->channels, &j))) {			/*count only re-buffering channels*/			if (!ch->BufferOn) continue;			max_buffer += ch->MaxBuffer;			cur_buffer += (ch->BufferTime>0) ? ch->BufferTime : 1;		}	}	evt.type = GF_EVENT_PROGRESS;	evt.progress.progress_type = 0;	evt.progress.service = is->root_od->net_service->url;	if (!max_buffer || !cur_buffer || (max_buffer <= cur_buffer)) {		evt.progress.done = evt.progress.total = max_buffer;	} else {		evt.progress.done = cur_buffer;		evt.progress.total = max_buffer;	}	GF_USER_SENDEVENT(is->root_od->term->user, &evt);}static Bool Inline_SetScene(M_Inline *root){	GF_MediaObject *mo;	GF_InlineScene *parent;	GF_SceneGraph *graph = gf_node_get_graph((GF_Node *) root);	parent = (GF_InlineScene *)gf_sg_get_private(graph);	if (!parent) return 0;	mo = gf_is_get_media_object(parent, &root->url, GF_MEDIA_OBJECT_SCENE, 0);	if (!mo || !mo->odm) return 0;	if (!mo->odm->subscene) {		gf_term_invalidate_renderer(parent->root_od->term);		return 0;	}	/*assign inline scene as private stack of inline node, and remember inline node for event propagation*/	gf_node_set_private((GF_Node *)root, mo->odm->subscene);	gf_list_add(mo->odm->subscene->inline_nodes, root);	/*play*/	gf_mo_play(mo, 0, -1, 0);	return 1;}Bool gf_mo_is_same_url(GF_MediaObject *obj, MFURL *an_url){	Bool include_sub_url = 0;	u32 i;	char szURL1[GF_MAX_PATH], szURL2[GF_MAX_PATH], *ext;	/*don't analyse audio/video to locate segments or viewports*/	if (obj->type==GF_MEDIA_OBJECT_AUDIO) include_sub_url = 1;	if (obj->type==GF_MEDIA_OBJECT_VIDEO) include_sub_url = 1;	if (obj->OD_ID==GF_ESM_DYNAMIC_OD_ID) {		if (!obj->URLs.count) {			if (!obj->odm) return 0;			strcpy(szURL1, obj->odm->net_service->url);		} else {			strcpy(szURL1, obj->URLs.vals[0].url);		}	} else {		if (!obj->URLs.count) return 0;		strcpy(szURL1, obj->URLs.vals[0].url);

⌨️ 快捷键说明

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