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

📄 terminal.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 / 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.  * */#include <gpac/internal/terminal_dev.h>#include <gpac/internal/renderer_dev.h>#include <gpac/constants.h>#include <gpac/options.h>#include <gpac/network.h>/*textual command processing*/#include <gpac/scene_manager.h>u32 gf_term_get_time(GF_Terminal *term){	assert(term);	return gf_sr_get_clock(term->renderer);}void gf_term_invalidate_renderer(GF_Terminal *term){	gf_sr_invalidate(term->renderer, NULL);}static Bool check_user(GF_User *user){	if (!user->config) return 0;	if (!user->modules) return 0;	if (!user->opaque) return 0;	return 1;}static Bool term_script_action(void *opaque, u32 type, GF_Node *n, GF_JSAPIParam *param){	Bool ret;	GF_Terminal *term = (GF_Terminal *) opaque;	if (type==GF_JSAPI_OP_MESSAGE) {		gf_term_message(term, term->root_scene->root_od->net_service->url, param->info.msg, param->info.e);		return 1;	}	if (type==GF_JSAPI_OP_GET_OPT) {		param->gpac_cfg.key_val = gf_cfg_get_key(term->user->config, param->gpac_cfg.section, param->gpac_cfg.key);		return 1;	}	if (type==GF_JSAPI_OP_SET_OPT) {		gf_cfg_set_key(term->user->config, param->gpac_cfg.section, param->gpac_cfg.key, param->gpac_cfg.key_val);		return 1;	}	if (type==GF_JSAPI_OP_GET_DOWNLOAD_MANAGER) {		param->dnld_man = term->downloader;		return 1;	}	if (type==GF_JSAPI_OP_GET_SCENE_URI) {		GF_InlineScene *is = (GF_InlineScene *)gf_sg_get_private(gf_node_get_graph(n));		param->uri.url = is->root_od->net_service->url;		param->uri.nb_params = 0;		return 1;	}	ret = 0;	if (term->renderer->visual_renderer->ScriptAction)		ret = term->renderer->visual_renderer->ScriptAction(term->renderer->visual_renderer, type, n, param);	if (ret) return ret;	if (type==GF_JSAPI_OP_LOAD_URL) {		if (gf_sg_get_private(gf_node_get_graph(n)) == term->root_scene) {			GF_Event evt;			if (!term->user->EventProc) return 0;			evt.type = GF_EVENT_NAVIGATE;			evt.navigate.to_url = param->uri.url;			evt.navigate.parameters = param->uri.params;			evt.navigate.param_count = param->uri.nb_params;			return term->user->EventProc(term->user->opaque, &evt);		} else {			/*TODO*/			return 0;		}	}	return 0;}static void gf_term_reload_cfg(GF_Terminal *term){	const char *sOpt;	Double fps;	u32 mode;	s32 prio;	if (!term) return;		/*reload term part*/	sOpt = gf_cfg_get_key(term->user->config, "Systems", "AlwaysDrawBIFS");	if (sOpt && !stricmp(sOpt, "yes"))		term->flags &= ~GF_TERM_SYSDEC_RESYNC;	else		term->flags |= GF_TERM_SYSDEC_RESYNC;	sOpt = gf_cfg_get_key(term->user->config, "Systems", "ForceSingleClock");	if (sOpt && !stricmp(sOpt, "yes")) 		term->flags |= GF_TERM_SINGLE_CLOCK;	else		term->flags &= ~GF_TERM_SINGLE_CLOCK;	sOpt = gf_cfg_get_key(term->user->config, "Rendering", "FrameRate");	if (sOpt) {		fps = atof(sOpt);		term->frame_duration = (u32) (1000/fps);		gf_sr_set_fps(term->renderer, fps);	}	if (term->user->init_flags & GF_TERM_NO_VISUAL_THREAD){		//gf_term_set_threading(term->mediaman, 1);	} else {		prio = GF_THREAD_PRIORITY_NORMAL;		sOpt = gf_cfg_get_key(term->user->config, "Systems", "Priority");		if (sOpt) {			if (!stricmp(sOpt, "low")) prio = GF_THREAD_PRIORITY_LOWEST;			else if (!stricmp(sOpt, "normal")) prio = GF_THREAD_PRIORITY_NORMAL;			else if (!stricmp(sOpt, "high")) prio = GF_THREAD_PRIORITY_HIGHEST;			else if (!stricmp(sOpt, "real-time")) prio = GF_THREAD_PRIORITY_REALTIME;		} else {			gf_cfg_set_key(term->user->config, "Systems", "Priority", "normal");		}		gf_term_set_priority(term, prio);		sOpt = gf_cfg_get_key(term->user->config, "Systems", "ThreadingPolicy");		if (sOpt) {			mode = GF_TERM_THREAD_FREE;			if (!stricmp(sOpt, "Single")) mode = GF_TERM_THREAD_SINGLE;			else if (!stricmp(sOpt, "Multi")) mode = GF_TERM_THREAD_MULTI;			gf_term_set_threading(term, mode);		}	}	/*default data timeout is 20 sec*/	term->net_data_timeout = 20000;	sOpt = gf_cfg_get_key(term->user->config, "Network", "DataTimeout");	if (sOpt) term->net_data_timeout = atoi(sOpt);	if (term->root_scene) gf_is_set_duration(term->root_scene);	/*reload renderer config*/	gf_sr_set_option(term->renderer, GF_OPT_RELOAD_CONFIG, 1);}static Bool gf_term_get_user_pass(void *usr_cbk, const char *site_url, char *usr_name, char *password){	GF_Event evt;	GF_Terminal *term = (GF_Terminal *)usr_cbk;	evt.auth.site_url = site_url;	evt.auth.user = usr_name;	evt.auth.password = password;	return term->user->EventProc(term->user->opaque, &evt);}GF_EXPORTGF_Terminal *gf_term_new(GF_User *user){	GF_Terminal *tmp;	const char *cf;	if (!check_user(user)) return NULL;	GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Creating terminal\n"));	tmp = (GF_Terminal*)malloc(sizeof(GF_Terminal));	if (!tmp) return NULL;	memset(tmp, 0, sizeof(GF_Terminal));	/*just for safety*/	gf_sys_init();	tmp->user = user;	/*this is not changeable at runtime*/	if (user->init_flags & GF_TERM_NO_VISUAL_THREAD) {		tmp->flags |= GF_TERM_RENDER_FRAME;	} else {		cf = gf_cfg_get_key(user->config, "Systems", "NoVisualThread");		if (!cf || !stricmp(cf, "no")) {			tmp->flags &= ~GF_TERM_RENDER_FRAME;		} else {			tmp->flags |= GF_TERM_RENDER_FRAME;		}	}	/*setup scene renderer*/	tmp->renderer = gf_sr_new(user, !(tmp->flags & GF_TERM_RENDER_FRAME) , tmp);	if (!tmp->renderer) {		free(tmp);		return NULL;	}	GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] renderer loaded\n"));	gf_sr_set_fps(tmp->renderer, 30.0);	tmp->frame_duration = (u32) (1000/30);	tmp->downloader = gf_dm_new(user->config);	gf_dm_set_auth_callback(tmp->downloader, gf_term_get_user_pass, tmp);	GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] downloader loaded\n"));	tmp->net_services = gf_list_new();	tmp->net_services_to_remove = gf_list_new();	tmp->channels_pending = gf_list_new();	tmp->media_queue = gf_list_new();		tmp->net_mx = gf_mx_new();	tmp->input_streams = gf_list_new();	tmp->x3d_sensors = gf_list_new();	/*mode is changed when reloading cfg*/	gf_term_init_scheduler(tmp, GF_TERM_THREAD_FREE);	GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Terminal created - loading config\n"));	gf_term_reload_cfg(tmp);	return tmp;}GF_EXPORTGF_Err gf_term_del(GF_Terminal * term){	GF_Err e;	u32 timeout;	if (!term) return GF_BAD_PARAM;	GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Destroying terminal\n"));	/*close main service*/	gf_term_disconnect(term);	GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] main service disconnected\n"));	/*wait for destroy*/	e = GF_IO_ERR;	timeout = 1000;	while (term->root_scene || gf_list_count(term->net_services) || gf_list_count(term->net_services_to_remove)) {		gf_sleep(30);		/*this shouldn't be needed but unfortunately there's a bug hanging around there...*/		timeout--;		if (!timeout) break;	}	if (timeout) {		assert(!gf_list_count(term->net_services));		assert(!gf_list_count(term->net_services_to_remove));		e = GF_OK;	} 	GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] All network services deleted\n"));	/*stop the media manager */	gf_term_stop_scheduler(term);	/*delete renderer before the input sensor stacks to avoid recieving events from the renderer	when destroying these stacks*/	gf_sr_del(term->renderer);	gf_list_del(term->net_services);	gf_list_del(term->net_services_to_remove);	gf_list_del(term->input_streams);	gf_list_del(term->x3d_sensors);	assert(!gf_list_count(term->channels_pending));	gf_list_del(term->channels_pending);	assert(!gf_list_count(term->media_queue));	assert(!term->nodes_pending);	gf_list_del(term->media_queue);	if (term->downloader) gf_dm_del(term->downloader);	gf_mx_del(term->net_mx);	gf_sys_close();	free(term);	GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Terminal destroyed\n"));	return e;}void gf_term_message(GF_Terminal *term, const char *service, const char *message, GF_Err error){	if (!term || !term->user) return;	GF_USER_MESSAGE(term->user, service, message, error);}static void gf_term_set_play_state(GF_Terminal *term, u32 PlayState, Bool reset_audio, Bool pause_clocks){	u32 i, j;	GF_ClientService *ns;	/*only play/pause if connected*/	if (!term || !term->root_scene) return;	/*and if not already paused/playing*/	if (!term->play_state && !PlayState) return;	if (term->play_state && (PlayState==GF_STATE_PAUSED)) return;	/*pause renderer*/	if ((PlayState==GF_STATE_PLAYING) && reset_audio)		gf_sr_set_option(term->renderer, GF_OPT_PLAY_STATE, 0xFF);	else		gf_sr_set_option(term->renderer, GF_OPT_PLAY_STATE, PlayState);	if (PlayState==GF_STATE_STEP_PAUSE) PlayState = term->play_state ? GF_STATE_PLAYING : GF_STATE_PAUSED;	if (term->play_state == PlayState) return;	term->play_state = PlayState;	if (!pause_clocks) return;	/*pause all clocks on all services*/	i=0;	while ( (ns = (GF_ClientService*)gf_list_enum(term->net_services, &i)) ) {		GF_Clock *ck;		j=0;		while ( (ck = (GF_Clock *)gf_list_enum(ns->Clocks, &j)) ) {			if (PlayState) gf_clock_pause(ck);			else gf_clock_resume(ck);		}	}}GF_Err gf_term_step_clocks(GF_Terminal * term, u32 ms_diff){	u32 i, j;	GF_ClientService *ns;	/*only play/pause if connected*/	if (!term || !term->root_scene || !term->root_scene->root_od) return GF_BAD_PARAM;	if (!term->play_state) return GF_BAD_PARAM;	gf_sr_lock(term->renderer, 1);	i=0;	while ( (ns = (GF_ClientService*)gf_list_enum(term->net_services, &i)) ) {		GF_Clock *ck;		j=0;		while ( (ck = (GF_Clock *)gf_list_enum(ns->Clocks, &j)) ) {			ck->init_time += ms_diff;		}	}	term->renderer->step_mode = 1;	term->renderer->draw_next_frame = 1;	gf_sr_lock(term->renderer, 0);	return GF_OK;}GF_EXPORTvoid gf_term_connect_from_time(GF_Terminal * term, const char *URL, u64 startTime, Bool pause_at_first_frame){	GF_InlineScene *is;	GF_ObjectManager *odm;	const char *main_url;	if (!URL || !strlen(URL)) return;	if (term->root_scene) {		if (term->root_scene->root_od && term->root_scene->root_od->net_service) {			main_url = term->root_scene->root_od->net_service->url;			if (main_url && !strcmp(main_url, URL)) {				gf_term_play_from_time(term, 0, pause_at_first_frame);				return;			}		}		/*disconnect*/		gf_term_disconnect(term);	}	GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Connecting to %s\n", URL));	gf_term_lock_net(term, 1);	GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Creating new root scene\n", URL));	/*create a new scene*/	is = gf_is_new(NULL);	gf_sg_set_script_action(is->graph, term_script_action, term);	odm = gf_odm_new();	is->root_od = odm;	term->root_scene = is;	odm->parentscene = NULL;	odm->subscene = is;	odm->term = term;	GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] root scene created\n", URL));	gf_term_lock_net(term, 0);	odm->media_start_time = startTime;	/*render first visual frame and pause*/	if (pause_at_first_frame)		gf_term_set_play_state(term, GF_STATE_STEP_PAUSE, 0, 0);	/*connect - we don't have any parentID */	gf_term_connect_object(term, odm, (char *) URL, NULL);}GF_EXPORTvoid gf_term_connect(GF_Terminal * term, const char *URL){	gf_term_connect_from_time(term, URL, 0, 0);}GF_EXPORTvoid gf_term_disconnect(GF_Terminal *term){	if (!term->root_scene) return;	/*resume*/	if (term->play_state) gf_term_set_play_state(term, GF_STATE_PLAYING, 1, 1);	gf_odm_disconnect(term->root_scene->root_od, 1);	while (term->root_scene || gf_list_count(term->net_services_to_remove)) {		gf_term_handle_services(term);		gf_sleep(10);	}}GF_EXPORTconst char *gf_term_get_url(GF_Terminal *term){	if (!term || !term->root_scene) return NULL;	return term->root_scene->root_od->net_service->url;}static GF_Err gf_term_set_cache_state(GF_Terminal *term, u32 state){	GF_Err e;	if (!term) return GF_BAD_PARAM;	if (term->enable_cache && (state==GF_MEDIA_CACHE_ENABLED)) return GF_OK;	if (!term->enable_cache && (state!=GF_MEDIA_CACHE_ENABLED)) return GF_OK;	term->enable_cache = !term->enable_cache;	/*not connected, nothing to do*/	if (!term->root_scene) return GF_OK;	gf_term_lock_net(term, 1);	if (term->enable_cache) {		/*otherwise start cache*/		e = gf_term_service_cache_load(term->root_scene->root_od->net_service);	} else {		e = gf_term_service_cache_close(term->root_scene->root_od->net_service, (state==GF_MEDIA_CACHE_DISCARD) ? 1 : 0);	}	gf_term_lock_net(term, 0);	return e;}/*set rendering option*/GF_EXPORTGF_Err gf_term_set_option(GF_Terminal * term, u32 type, u32 value){	if (!term) return GF_BAD_PARAM;	switch (type) {	case GF_OPT_PLAY_STATE:		gf_term_set_play_state(term, value, 0, 1);		return GF_OK;	case GF_OPT_RELOAD_CONFIG:		gf_term_reload_cfg(term);		return GF_OK;	case GF_OPT_MEDIA_CACHE:		gf_term_set_cache_state(term, value);		return GF_OK;	default:		return gf_sr_set_option(term->renderer, type, value);	}}GF_EXPORTGF_Err gf_term_set_simulation_frame_rate(GF_Terminal * term, Double frame_rate){	if (!term) return GF_BAD_PARAM;	term->frame_duration = (u32) (1000.0 / frame_rate);	gf_sr_set_fps(term->renderer, frame_rate);	return GF_OK;}GF_EXPORTDouble gf_term_get_simulation_frame_rate(GF_Terminal *term){	return term ? term->renderer->frame_rate : 0.0;}/*returns 0 if any of the clock still hasn't seen EOS*/u32 Term_CheckClocks(GF_ClientService *ns, GF_InlineScene *is){	GF_Clock *ck;	u32 i;	if (is) {		GF_ObjectManager *odm;		if (is->root_od->net_service != ns) {			if (!Term_CheckClocks(is->root_od->net_service, is)) return 0;		}		i=0;		while ( (odm = (GF_ObjectManager*)gf_list_enum(is->ODlist, &i)) ) {			if (odm->net_service != ns) {				if (!Term_CheckClocks(odm->net_service, NULL)) return 0;			}		}	}	i=0;	while ( (ck = (GF_Clock *)gf_list_enum(ns->Clocks, &i) ) ) {		if (!ck->has_seen_eos) return 0;	}	return 1;}u32 Term_CheckIsOver(GF_Terminal *term){	if (!term->root_scene) return 1;	/*if input sensors consider the scene runs forever*/	if (gf_list_count(term->input_streams)) return 0;	if (gf_list_count(term->x3d_sensors)) return 0;

⌨️ 快捷键说明

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