PageRenderTime 2329ms CodeModel.GetById 129ms app.highlight 878ms RepoModel.GetById 118ms app.codeStats 1ms

/applications/osmo4_ios/main.c

https://github.com/svettom/gpac-1
C | 2126 lines | 1930 code | 148 blank | 48 comment | 508 complexity | 06e5b8b8222e903695c998d44615dc7b MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/*
   2 *			GPAC - Multimedia Framework C SDK
   3 *
   4 *			Copyright (c) Jean Le Feuvre 2000-2005
   5 *					All rights reserved
   6 *
   7 *  This file is part of GPAC / command-line client
   8 *
   9 *  GPAC is free software; you can redistribute it and/or modify
  10 *  it under the terms of the GNU Lesser General Public License as published by
  11 *  the Free Software Foundation; either version 2, or (at your option)
  12 *  any later version.
  13 *   
  14 *  GPAC is distributed in the hope that it will be useful,
  15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17 *  GNU Lesser General Public License for more details.
  18 *   
  19 *  You should have received a copy of the GNU Lesser General Public
  20 *  License along with this library; see the file COPYING.  If not, write to
  21 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  22 *
  23 */
  24
  25
  26#include "libgpac_symbols.h"
  27 
  28void (*gf_log_lt)(u32 ll, u32 lt);
  29int (*AVI_close)(avi_t *AVI);
  30GF_Err (*gf_term_del)(GF_Terminal *term);
  31void (*gf_sleep)(u32 ms);
  32GF_Err (*gf_sc_release_screen_buffer)(GF_Compositor *sr, GF_VideoSurface *framebuffer);
  33char (*gf_prompt_get_char)();
  34void (*gf_set_progress)(char *title, u32 done, u32 total);
  35GF_Terminal *(*gf_term_new)(GF_User *user);
  36GF_Err (*gf_term_process_step)(GF_Terminal *term);
  37GF_Err (*gf_sc_get_screen_buffer)(GF_Compositor *sr, GF_VideoSurface *framebuffer, Bool depth_buffer);
  38void (*gf_iphone_set_sdl_audio_module)(void* (*SDL_Module) (void));
  39GF_Err (*gf_term_step_clocks)(GF_Terminal * term, u32 ms_diff);
  40void (*gf_prompt_set_echo_off)(Bool echo_off);
  41u32 (*gf_log_tool_level_on)();
  42GF_Err (*gf_cfg_set_key)(GF_Config *cfgFile, const char *secName, const char *keyName, const char *keyValue);
  43u32 (*gf_cfg_get_section_count)(GF_Config *cfgFile);
  44GF_Err (*gf_term_get_service_info)(GF_Terminal *term, GF_ObjectManager *odm, NetInfoCommand *netcom);
  45GF_Err (*gf_term_set_size)(GF_Terminal *term, u32 NewWidth, u32 NewHeight);
  46Bool (*gf_sys_get_rti)(u32 refresh_time_ms, GF_SystemRTInfo *rti, u32 flags);
  47u32 (*gf_term_play_from_time)(GF_Terminal *term, u64 from_time, u32 pause_at_first_frame);
  48void *(*gf_malloc)(size_t size);
  49void (*gf_log_set_tools_levels)(const char *);
  50void (*gf_log_set_tool_level)(u32, u32);
  51void (*gf_log_modify_tools_level)(const char *);
  52void (*gf_iphone_set_sdl_video_module)(void* (*SDL_Module) (void));
  53u32 (*gf_term_get_option)(GF_Terminal *term, u32 opt_type);
  54Bool (*gf_term_user_event)(GF_Terminal *term, GF_Event *event);
  55const char *(*gf_modules_get_file_name)(GF_ModuleManager *pm, u32 index);
  56GF_Mutex *(*gf_mx_new)(const char *name);
  57u32 (*gf_list_count)(GF_List *ptr);
  58void (*gf_free)(void *ptr);
  59const char *(*gf_term_get_world_info)(GF_Terminal *term, GF_ObjectManager *scene_od, GF_List *descriptions);
  60const char *(*gf_cfg_get_section_name)(GF_Config *cfgFile, u32 secIndex);
  61void (*gf_term_navigate_to)(GF_Terminal *term, const char *toURL);
  62void (*gf_modules_del)(GF_ModuleManager *pm);
  63GF_ModuleManager *(*gf_modules_new)(const char *directory, GF_Config *cfgFile);
  64void (*gf_sys_init)(Bool enable_memory_tracker);
  65void (*gf_log)(const char *fmt, ...);
  66GF_Err (*gf_term_get_object_info)(GF_Terminal *term, GF_ObjectManager *odm, GF_MediaInfo *info);
  67u32 (*gf_mx_p)(GF_Mutex *mx);
  68u32 (*gf_mx_v)(GF_Mutex *mx);
  69void (*gf_mx_del)(GF_Mutex *mx);
  70GF_Err (*gf_term_process_flush)(GF_Terminal *term);
  71const char *(*gf_cfg_get_key_name)(GF_Config *cfgFile, const char *secName, u32 keyIndex);
  72int (*AVI_write_frame)(avi_t *AVI, char *data, long bytes, int keyframe);
  73void (*gf_cfg_del)(GF_Config *iniFile);
  74Bool (*gf_term_get_channel_net_info)(GF_Terminal *term, GF_ObjectManager *odm, u32 *d_enum, u32 *chid, NetStatCommand *netcom, GF_Err *ret_code);
  75void (*gf_term_process_shortcut)(GF_Terminal *term, GF_Event *ev);
  76GF_Config *(*gf_cfg_init)(const char *fileName, Bool *is_new);
  77Bool (*gf_term_get_download_info)(GF_Terminal *term, GF_ObjectManager *odm, u32 *d_enum, const char **server, const char **path, u32 *bytes_done, u32 *total_bytes, u32 *bytes_per_sec);
  78u32 (*gf_sys_clock)();
  79GF_ObjectManager *(*gf_term_get_object)(GF_Terminal *term, GF_ObjectManager *scene_od, u32 index);
  80GF_Err (*gf_term_set_option)(GF_Terminal *term, u32 opt_type, u32 opt_value);
  81void (*gf_sys_close)();
  82void (*gf_term_connect_from_time)(GF_Terminal *term, const char *URL, u64 time_in_ms, Bool pause_at_first_frame);
  83avi_t* (*AVI_open_output_file)(char * filename);
  84const char *(*gf_cfg_get_key)(GF_Config *cfgFile, const char *secName, const char *keyName);
  85void (*AVI_set_video)(avi_t *AVI, int width, int height, double fps, char *compressor);
  86void (*gf_term_set_speed)(GF_Terminal *term, Fixed speed);
  87u32 (*gf_cfg_get_key_count)(GF_Config *cfgFile, const char *secName);
  88u32 (*gf_term_object_subscene_type)(GF_Terminal *term, GF_ObjectManager *odm);
  89Double (*gf_term_get_framerate)(GF_Terminal *term, Bool absoluteFPS);
  90const char *(*gf_error_to_string)(GF_Err e);
  91GF_Err (*gf_stretch_bits)(GF_VideoSurface *dst, GF_VideoSurface *src, GF_Window *dst_wnd, GF_Window *src_wnd, u8 alpha, Bool flip, GF_ColorKey *colorKey, GF_ColorMatrix * cmat);
  92void (*gf_list_del)(GF_List *ptr);
  93void *(*gf_list_get)(GF_List *ptr, u32 itemNumber);
  94void (*gf_term_disconnect)(GF_Terminal *term);
  95Bool (*gf_term_is_supported_url)(GF_Terminal *term, const char *fileName, Bool use_parent_url, Bool no_mime_check);
  96GF_List *(*gf_list_new)(void);
  97const char *(*gf_modules_get_option)(GF_BaseInterface *interface_obj, const char *secName, const char *keyName);
  98GF_Err (*gf_term_dump_scene)(GF_Terminal *term, char *rad_name, char **filename, Bool xml_dump, Bool skip_proto, GF_ObjectManager *odm);
  99Bool (*gf_prompt_has_input)();
 100GF_Err (*gf_term_scene_update)(GF_Terminal *term, char *type, char *com);
 101void (*gf_term_connect)(GF_Terminal *term, const char *URL);
 102u32 (*gf_term_get_object_count)(GF_Terminal *term, GF_ObjectManager *scene_od);
 103u32 (*gf_modules_get_count)(GF_ModuleManager *pm);
 104GF_ObjectManager *(*gf_term_get_root_object)(GF_Terminal *term);
 105u32 (*gf_term_get_time_in_ms)(GF_Terminal *term);
 106void (*gf_term_connect_with_path)(GF_Terminal *term, const char *URL, const char *parent_URL);
 107gf_log_cbk (*gf_log_set_callback)(void *usr_cbk, gf_log_cbk cbk);
 108GF_Err (*gf_log_modify_tools_levels)(const char *val);
 109void (*gf_term_switch_quality)(GF_Terminal *term, Bool up);
 110GF_Err (*gf_term_release_screen_buffer)(GF_Terminal *term, GF_VideoSurface *framebuffer);
 111GF_Err (*gf_term_get_screen_buffer)(GF_Terminal *term, GF_VideoSurface *framebuffer);
 112FILE *(*gf_f64_open)(const char *file_name, const char *mode);
 113size_t (*gf_fwrite)(const void *ptr, size_t size, size_t nmemb, FILE *stream);
 114GF_Err (*gf_img_png_enc)(char *data, u32 width, u32 height, s32 stride, u32 pixel_format, char *dst, u32 *dst_size);
 115u32 (*utf8_to_ucs4)(u32 *ucs4_buf, u32 utf8_len, unsigned char *utf8_buf);
 116
 117#ifndef WIN32
 118#include <pwd.h>
 119#include <unistd.h>
 120
 121#else
 122#include <windows.h> /*for GetModuleFileName*/
 123#include <direct.h>  /*for _mkdir*/
 124#include <shlobj.h>  /*for getting user-dir*/
 125#ifndef SHGFP_TYPE_CURRENT
 126#define SHGFP_TYPE_CURRENT 0 /*needed for MinGW*/
 127#endif
 128
 129#ifdef _MSC_VER 
 130/*get rid of console*/
 131#if 0
 132#pragma comment(linker,"/SUBSYSTEM:WINDOWS")
 133#pragma comment(linker,"/ENTRY:main")
 134#else
 135#pragma comment(linker,"/SUBSYSTEM:CONSOLE") 
 136#endif
 137
 138#endif // _MSC_VER
 139
 140#endif	//WIN32
 141
 142
 143/*local prototypes*/
 144void PrintWorldInfo(GF_Terminal *term);
 145void ViewOD(GF_Terminal *term, u32 OD_ID, u32 number);
 146void PrintODList(GF_Terminal *term, GF_ObjectManager *root_odm, u32 num, u32 indent, char *root_name);
 147
 148void ViewODs(GF_Terminal *term, Bool show_timing);
 149void PrintGPACConfig();
 150
 151static Bool restart = 0;
 152#if defined(__DARWIN__) || defined(__APPLE__)
 153static Bool not_threaded = 1;
 154#else
 155static Bool not_threaded = 0;
 156#endif
 157static Bool no_audio = 0;
 158static Bool no_regulation = 0;
 159static Bool bench_mode = 0;
 160Bool is_connected = 0;
 161Bool startup_file = 0;
 162GF_User user;
 163GF_Terminal *term;
 164u64 Duration;
 165GF_Err last_error = GF_OK;
 166
 167static Fixed bench_speed = FLT2FIX(20);
 168
 169static Bool request_next_playlist_item = 0;
 170
 171static GF_Config *cfg_file;
 172static Bool display_rti = 0;
 173static Bool Run;
 174static Bool CanSeek = 0;
 175static u32 Volume=100;
 176static char the_url[GF_MAX_PATH];
 177static char pl_path[GF_MAX_PATH];
 178static Bool no_mime_check = 1;
 179static Bool be_quiet = 0;
 180static u32 log_time_start = 0;
 181
 182static u32 forced_width=0;
 183static u32 forced_height=0;
 184
 185/*windowless options*/
 186u32 align_mode = 0;
 187u32 init_w = 0;
 188u32 init_h = 0;
 189u32 last_x, last_y;
 190Bool right_down = 0;
 191
 192void dump_frame(GF_Terminal *term, char *rad_path, u32 dump_type, u32 frameNum);
 193Bool dump_file(char *the_url, u32 dump_mode, Double fps, u32 width, u32 height, Float scale, u32 *times, u32 nb_times);
 194
 195void PrintUsage()
 196{
 197	fprintf(stdout, "Usage Osmo4iOS [options] [filename]\n"
 198		"\t-c fileName:    user-defined configuration file\n"
 199		"\t-rti fileName:  logs run-time info (FPS, CPU, Mem usage) to file\n"
 200		"\t-rtix fileName: same as -rti but driven by GPAC logs\n"
 201		"\t-quiet:         removes script message, buffering and downloading status\n"
 202		"\t-opt	option:    Overrides an option in the configuration file. String format is section:key=value\n"
 203		"\t-log-file file: sets output log file.\n"
 204		"\t-log-level lev: sets log level. Possible values are:\n"
 205		"\t        \"error\"      : logs only error messages\n"
 206		"\t        \"warning\"    : logs error+warning messages\n"
 207		"\t        \"info\"       : logs error+warning+info messages\n"
 208		"\t        \"debug\"      : logs all messages\n"
 209		"\n"
 210		"\t-log-tools lt:  sets tool(s) to log. List of \':\'-separated values:\n"
 211		"\t        \"core\"       : libgpac core\n"
 212		"\t        \"coding\"     : bitstream formats (audio, video, scene)\n"
 213		"\t        \"container\"  : container formats (ISO File, MPEG-2 TS, AVI, ...)\n"
 214		"\t        \"network\"    : network data exept RTP trafic\n"
 215		"\t        \"rtp\"        : rtp trafic\n"
 216		"\t        \"author\"     : authoring tools (hint, import, export)\n"
 217		"\t        \"sync\"       : terminal sync layer\n"
 218		"\t        \"codec\"      : terminal codec messages\n"
 219		"\t        \"parser\"     : scene parsers (svg, xmt, bt) and other\n"
 220		"\t        \"media\"      : terminal media object management\n"
 221		"\t        \"scene\"      : scene graph and scene manager\n"
 222		"\t        \"script\"     : scripting engine messages\n"
 223		"\t        \"interact\"   : interaction engine (events, scripts, etc)\n"
 224		"\t        \"compose\"    : composition engine (2D, 3D, etc)\n"
 225		"\t        \"service\"    : network service management\n"
 226		"\t        \"mmio\"       : Audio/Video HW I/O management\n"
 227		"\t        \"none\"       : no tool logged\n"
 228		"\t        \"all\"        : all tools logged\n"
 229		"\n"
 230		"\t-size WxH:      specifies visual size (default: scene size)\n"
 231		"\t-scale s:      scales the visual size (default: 1)\n"
 232#if defined(__DARWIN__) || defined(__APPLE__)
 233		"\t-thread:        enables thread usage for terminal and compositor \n"
 234#else
 235		"\t-no-thread:     disables thread usage (except for audio)\n"
 236#endif
 237		"\t-no-audio:	   disables audio \n"
 238		"\t-no-wnd:        uses windowless mode (Win32 only)\n"
 239		"\t-align vh:      specifies v and h alignment for windowless mode\n"
 240		"                   possible v values: t(op), m(iddle), b(ottom)\n"
 241		"                   possible h values: l(eft), m(iddle), r(ight)\n"
 242		"                   default alignment is top-left\n"
 243		"                   default alignment is top-left\n"
 244		"\t-pause:         pauses at first frame\n"
 245		"\n"
 246		"Dumper Options:\n"
 247		"\t-bmp [times]:   dumps given frames to bmp\n"
 248		"\t-raw [times]:   dumps given frames to bmp\n"
 249		"\t-avi [times]:   dumps given file to raw avi\n"
 250		"\t-rgbds:         dumps the RGBDS pixel format texture\n"
 251		"                   with -avi [times]: dumps an rgbds-format .avi\n"
 252		"\t-rgbd:          dumps the RGBD pixel format texture\n"
 253		"					with -avi [times]: dumps an rgbd-format .avi\n"		
 254		"\t-depth:         dumps depthmap (z-buffer) frames\n"
 255		"                   with -avi [times]: dumps depthmap in grayscale .avi\n"		
 256		"                   with -bmp: dumps depthmap in grayscale .bmp\n"		
 257		"\t-fps FPS:       specifies frame rate for AVI dumping (default: 25.0)\n"
 258		"\t-2d:            uses 2D compositor\n"
 259		"\t-3d:            uses 3D compositor\n"
 260		"\t-fill:          uses fill aspect ratio for dumping (default: none)\n"
 261		"\t-show:          show window while dumping (default: no)\n"
 262		"MP4Client - GPAC command line player and dumper - version %s\n"
 263		"GPAC Written by Jean Le Feuvre (c) 2001-2005 - ENST (c) 2005-200X\n",
 264
 265		GPAC_FULL_VERSION
 266		);
 267}
 268
 269void PrintHelp()
 270{
 271	fprintf(stdout, "MP4Client command keys:\n"
 272		"\to: connect to the specified URL\n"
 273		"\tO: connect to the specified URL in playlist mode\n"
 274		"\tN: switch to the next URL in the playlist (works with return key as well)\n"
 275		"\tr: restart current presentation\n"
 276		"\tp: play/pause the presentation\n"
 277		"\ts: step one frame ahead\n"
 278		"\tz: seek into presentation\n"
 279		"\tt: print current timing\n"
 280		"\n"
 281		"\tw: view world info\n"
 282		"\tv: view Object Descriptor list\n"
 283		"\ti: view Object Descriptor info (by ID)\n"
 284		"\tj: view Object Descriptor info (by number)\n"
 285		"\tb: view media objects timing and buffering info\n"
 286		"\tm: view media objects buffering and memory info\n"
 287		"\td: dumps scene graph\n"
 288		"\n"
 289		"\tC: Enable Streaming Cache\n"
 290		"\tS: Stops Streaming Cache and save to file\n"
 291		"\tA: Aborts Streaming Cache\n"
 292		"\n"
 293		"\tk: turns stress mode on/off\n"
 294		"\tn: changes navigation mode\n"
 295		"\tx: reset to last active viewpoint\n"
 296		"\n"
 297		"\t2: restart using 2D compositor\n"
 298		"\t3: restart using 3D compositor\n"
 299		"\n"
 300		"\t4: forces 4/3 Aspect Ratio\n"
 301		"\t5: forces 16/9 Aspect Ratio\n"
 302		"\t6: forces no Aspect Ratio (always fill screen)\n"
 303		"\t7: forces original Aspect Ratio (default)\n"
 304		"\n"
 305		"\tL: changes to new log level. CF MP4Client usage for possible values\n"
 306		"\tT: select new tools to log. CF MP4Client usage for possible values\n"
 307		"\n"
 308		"\tl: list available modules\n"
 309		"\tc: prints some GPAC configuration info\n"
 310		"\tR: toggles run-time info display on/off\n"
 311		"\tq: exit the application\n"
 312		"\th: print this message\n"
 313		"\n"
 314		"MP4Client - GPAC command line player - version %s\n"
 315		"GPAC Written by Jean Le Feuvre (c) 2001-2005 - ENST (c) 2005-200X\n",
 316
 317		GPAC_FULL_VERSION
 318		);
 319}
 320
 321
 322static void PrintTime(u64 time)
 323{
 324	u32 ms, h, m, s;
 325	h = (u32) (time / 1000 / 3600);
 326	m = (u32) (time / 1000 / 60 - h*60);
 327	s = (u32) (time / 1000 - h*3600 - m*60);
 328	ms = (u32) (time - (h*3600 + m*60 + s) * 1000);
 329	fprintf(stdout, "%02d:%02d:%02d.%02d", h, m, s, ms);
 330}
 331
 332
 333static u32 rti_update_time_ms = 200;
 334static FILE *rti_logs = NULL;
 335static u64 memory_at_gpac_startup = 0;
 336
 337static void UpdateRTInfo(const char *legend)
 338{
 339	GF_SystemRTInfo rti;
 340
 341	/*refresh every second*/
 342	if (!display_rti && !rti_logs) return;
 343	if (!gf_sys_get_rti(rti_update_time_ms, &rti, 0) && !legend) 
 344		return;
 345
 346	if (display_rti) {
 347		if (!rti.process_memory) rti.process_memory = (u32) (memory_at_gpac_startup-rti.physical_memory_avail);
 348		if (!rti.gpac_memory) rti.gpac_memory = (u32) (memory_at_gpac_startup-rti.physical_memory_avail);
 349
 350		if (display_rti==2) {
 351			fprintf(stdout, "FPS %02.2f - CPU %02d (%02d) - Mem %d kB\r", 
 352				gf_term_get_framerate(term, 0), rti.total_cpu_usage, rti.process_cpu_usage, (u32) (rti.gpac_memory / 1024) );
 353		} else {
 354			char szMsg[1024];
 355			GF_Event evt;
 356
 357			sprintf(szMsg, "FPS %02.2f - CPU %02d (%02d) - Mem %d kB", 
 358				gf_term_get_framerate(term, 0), rti.total_cpu_usage, rti.process_cpu_usage, (u32) (rti.gpac_memory / 1024) );
 359			evt.type = GF_EVENT_SET_CAPTION;
 360			evt.caption.caption = szMsg;
 361			gf_term_user_event(term, &evt);
 362		}
 363	}
 364	if (rti_logs) {
 365		fprintf(rti_logs, "% 8d\t% 8d\t% 8d\t% 4d\t% 8d\t%s", 
 366			gf_sys_clock(),
 367			gf_term_get_time_in_ms(term),
 368			rti.total_cpu_usage,
 369			(u32) gf_term_get_framerate(term, 0),
 370			(u32) (rti.gpac_memory / 1024), 
 371			legend ? legend : ""
 372			);
 373		if (!legend) fprintf(rti_logs, "\n");
 374	}
 375}
 376
 377static void ResetCaption()
 378{
 379	GF_Event event;
 380	if (display_rti) return;
 381	event.type = GF_EVENT_SET_CAPTION;
 382	if (is_connected) {
 383		char szName[1024];
 384		NetInfoCommand com;
 385
 386		event.caption.caption = NULL;
 387		/*get any service info*/
 388		if (!startup_file && gf_term_get_service_info(term, gf_term_get_root_object(term), &com) == GF_OK) {
 389			strcpy(szName, "");
 390			if (com.track_info) { 
 391				char szBuf[10];
 392				sprintf(szBuf, "%02d ", (u32) (com.track_info>>16) );
 393				strcat(szName, szBuf);
 394			}
 395			if (com.artist) { strcat(szName, com.artist); strcat(szName, " "); }
 396			if (com.name) { strcat(szName, com.name); strcat(szName, " "); }
 397			if (com.album) { strcat(szName, "("); strcat(szName, com.album); strcat(szName, ")"); }
 398			
 399			if (strlen(szName)) event.caption.caption = szName;
 400		}
 401		if (!event.caption.caption) {
 402			char *str = strrchr(the_url, '\\');
 403			if (!str) str = strrchr(the_url, '/');
 404			event.caption.caption = str ? str+1 : the_url;
 405		}
 406	} else {
 407		event.caption.caption = "GPAC MP4Client " GPAC_FULL_VERSION;
 408	}
 409	gf_term_user_event(term, &event);
 410}
 411
 412#ifdef WIN32
 413u32 get_sys_col(int idx)
 414{
 415	u32 res;
 416	DWORD val = GetSysColor(idx);
 417	res = (val)&0xFF; res<<=8;
 418	res |= (val>>8)&0xFF; res<<=8;
 419	res |= (val>>16)&0xFF;
 420	return res;
 421}
 422#endif
 423
 424void switch_bench()
 425{
 426	if (is_connected) {
 427		bench_mode = !bench_mode;
 428		display_rti = !display_rti;
 429		ResetCaption();
 430		gf_term_set_speed(term, bench_mode ? bench_speed : FIX_ONE);
 431	}
 432}
 433
 434Bool GPAC_EventProc(void *ptr, GF_Event *evt)
 435{
 436	if (!term) return 0;
 437
 438	switch (evt->type) {
 439	case GF_EVENT_DURATION:
 440		Duration = 1000;
 441		Duration = (u64) (((s64) Duration) * evt->duration.duration);
 442		CanSeek = evt->duration.can_seek;
 443		break;
 444	case GF_EVENT_MESSAGE:
 445	{
 446		const char *servName;
 447		if (!evt->message.service || !strcmp(evt->message.service, the_url)) {
 448			servName = "main service";
 449		} else if (!strnicmp(evt->message.service, "data:", 5)) {
 450			servName = "";
 451		} else {
 452			servName = evt->message.service;
 453		}
 454		if (!evt->message.message) return 0;
 455		if (evt->message.error) {
 456			if (!is_connected) last_error = evt->message.error;
 457			fprintf(stderr, "%s (%s): %s\n", evt->message.message, servName, gf_error_to_string(evt->message.error));
 458		} else if (!be_quiet) 
 459			fprintf(stderr, "(%s) %s\r", servName, evt->message.message);
 460	}
 461		break;
 462	case GF_EVENT_PROGRESS:
 463	{
 464		char *szTitle = "";
 465		if (evt->progress.progress_type==0) szTitle = "Buffer ";
 466		else if (evt->progress.progress_type==1) szTitle = "Download ";
 467		else if (evt->progress.progress_type==2) szTitle = "Import ";
 468		gf_set_progress(szTitle, evt->progress.done, evt->progress.total);
 469	}
 470		break;
 471	
 472
 473	case GF_EVENT_DBLCLICK:
 474		gf_term_set_option(term, GF_OPT_FULLSCREEN, !gf_term_get_option(term, GF_OPT_FULLSCREEN));
 475		return 0;
 476
 477	case GF_EVENT_MOUSEDOWN:
 478		if (evt->mouse.button==GF_MOUSE_RIGHT) {
 479			right_down = 1;
 480			last_x = evt->mouse.x;
 481			last_y = evt->mouse.y;
 482		}
 483		return 0;
 484	case GF_EVENT_MOUSEUP:
 485		if (evt->mouse.button==GF_MOUSE_RIGHT) {
 486			right_down = 0;
 487			last_x = evt->mouse.x;
 488			last_y = evt->mouse.y;
 489		}
 490		return 0;
 491	case GF_EVENT_MOUSEMOVE:
 492		if (right_down && (user.init_flags & GF_TERM_WINDOWLESS) ) {
 493			GF_Event move;
 494			move.move.x = evt->mouse.x - last_x;
 495			move.move.y = last_y-evt->mouse.y;
 496			move.type = GF_EVENT_MOVE;
 497			move.move.relative = 1;
 498			gf_term_user_event(term, &move);
 499		}
 500		return 0;
 501
 502	case GF_EVENT_KEYUP:
 503		switch (evt->key.key_code) {
 504		case GF_KEY_SPACE:
 505			if (evt->key.flags & GF_KEY_MOD_CTRL) switch_bench();
 506			break;
 507		}
 508		break;
 509	case GF_EVENT_KEYDOWN:
 510		gf_term_process_shortcut(term, evt);
 511		switch (evt->key.key_code) {
 512		case GF_KEY_SPACE:
 513			if (evt->key.flags & GF_KEY_MOD_CTRL) {
 514				/*ignore key repeat*/
 515				if (!bench_mode) switch_bench();
 516			}
 517			break;
 518		case GF_KEY_PAGEDOWN:
 519		case GF_KEY_MEDIANEXTTRACK:
 520			request_next_playlist_item = 1;
 521			break;
 522		case GF_KEY_MEDIAPREVIOUSTRACK:
 523			break;
 524		case GF_KEY_ESCAPE:
 525			gf_term_set_option(term, GF_OPT_FULLSCREEN, !gf_term_get_option(term, GF_OPT_FULLSCREEN));
 526			break;
 527		case GF_KEY_F:
 528			if (evt->key.flags & GF_KEY_MOD_CTRL) fprintf(stderr, "Rendering rate: %f FPS\n", gf_term_get_framerate(term, 0));
 529			break;
 530		case GF_KEY_T:
 531			if (evt->key.flags & GF_KEY_MOD_CTRL) fprintf(stderr, "Scene Time: %f \n", gf_term_get_time_in_ms(term)/1000.0);
 532			break;
 533		case GF_KEY_D:
 534			if (evt->key.flags & GF_KEY_MOD_CTRL) gf_term_set_option(term, GF_OPT_DRAW_MODE, (gf_term_get_option(term, GF_OPT_DRAW_MODE)==GF_DRAW_MODE_DEFER) ? GF_DRAW_MODE_IMMEDIATE : GF_DRAW_MODE_DEFER );
 535			break;
 536		case GF_KEY_4: 
 537			if (evt->key.flags & GF_KEY_MOD_CTRL)
 538				gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_4_3); 
 539			break;
 540		case GF_KEY_5: 
 541			if (evt->key.flags & GF_KEY_MOD_CTRL)
 542				gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_16_9); 
 543			break;
 544		case GF_KEY_6: 
 545			if (evt->key.flags & GF_KEY_MOD_CTRL)
 546				gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_FILL_SCREEN); 
 547			break;
 548		case GF_KEY_7: 
 549			if (evt->key.flags & GF_KEY_MOD_CTRL)
 550				gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_KEEP); 
 551			break;
 552		case GF_KEY_P:
 553			if (evt->key.flags & GF_KEY_MOD_CTRL && is_connected) {
 554				Bool is_pause = gf_term_get_option(term, GF_OPT_PLAY_STATE);
 555				fprintf(stderr, "[Status: %s]\n", is_pause ? "Playing" : "Paused");
 556				gf_term_set_option(term, GF_OPT_PLAY_STATE, (gf_term_get_option(term, GF_OPT_PLAY_STATE)==GF_STATE_PAUSED) ? GF_STATE_PLAYING : GF_STATE_PAUSED);
 557			}
 558			break;
 559		case GF_KEY_S:
 560			if ((evt->key.flags & GF_KEY_MOD_CTRL) && is_connected) {
 561				gf_term_set_option(term, GF_OPT_PLAY_STATE, GF_STATE_STEP_PAUSE);
 562				fprintf(stderr, "Step time: ");
 563				PrintTime(gf_term_get_time_in_ms(term));
 564				fprintf(stderr, "\n");
 565			}
 566			break;
 567		case GF_KEY_B:
 568			if ((evt->key.flags & GF_KEY_MOD_CTRL) && is_connected)
 569				ViewODs(term, 1);
 570			break;
 571		case GF_KEY_M:
 572			if ((evt->key.flags & GF_KEY_MOD_CTRL) && is_connected)
 573				ViewODs(term, 0);
 574			break;
 575		case GF_KEY_H:
 576			if ((evt->key.flags & GF_KEY_MOD_CTRL) && is_connected)
 577				gf_term_switch_quality(term, 1);
 578			break;
 579		case GF_KEY_L:
 580			if ((evt->key.flags & GF_KEY_MOD_CTRL) && is_connected)
 581				gf_term_switch_quality(term, 0);
 582			break;
 583		}
 584		break;
 585
 586	case GF_EVENT_CONNECT:
 587		if (evt->connect.is_connected) {
 588			is_connected = 1;
 589			fprintf(stderr, "Service Connected\n");
 590		} else if (is_connected) {
 591			fprintf(stderr, "Service %s\n", is_connected ? "Disconnected" : "Connection Failed");
 592			is_connected = 0;
 593			Duration = 0;
 594		}
 595		if (init_w && init_h) {
 596			gf_term_set_size(term, init_w, init_h);
 597		}
 598		ResetCaption();
 599		break;
 600	case GF_EVENT_EOS:
 601		restart = 1;
 602		break;
 603	case GF_EVENT_SIZE:
 604		if (user.init_flags & GF_TERM_WINDOWLESS) {
 605			GF_Event move;
 606			move.type = GF_EVENT_MOVE;
 607			move.move.align_x = align_mode & 0xFF;
 608			move.move.align_y = (align_mode>>8) & 0xFF;
 609			move.move.relative = 2;
 610			gf_term_user_event(term, &move);
 611		} 
 612		break;
 613	case GF_EVENT_SCENE_SIZE:
 614		if (forced_width && forced_height) {
 615			GF_Event size;
 616			size.type = GF_EVENT_SIZE;
 617			size.size.width = forced_width;
 618			size.size.height = forced_height;
 619			gf_term_user_event(term, &size);
 620		}
 621		break;
 622
 623	case GF_EVENT_METADATA:
 624		ResetCaption();
 625		break;
 626
 627	case GF_EVENT_QUIT:
 628		Run = 0;
 629		break;
 630	case GF_EVENT_DISCONNECT:
 631		gf_term_disconnect(term);
 632		break;
 633	case GF_EVENT_MIGRATE:
 634	{
 635	}
 636		break;
 637	case GF_EVENT_NAVIGATE_INFO:
 638		if (evt->navigate.to_url) fprintf(stderr, "Go to URL: \"%s\"\r", evt->navigate.to_url);
 639		break;
 640	case GF_EVENT_NAVIGATE:
 641		if (gf_term_is_supported_url(term, evt->navigate.to_url, 1, no_mime_check)) {
 642			strcpy(the_url, evt->navigate.to_url);
 643			fprintf(stderr, "Navigating to URL %s\n", the_url);
 644			gf_term_navigate_to(term, evt->navigate.to_url);
 645			return 1;
 646		} else {
 647			fprintf(stderr, "Navigation destination not supported\nGo to URL: %s\n", evt->navigate.to_url);
 648		}
 649		break;
 650	case GF_EVENT_SET_CAPTION:
 651		gf_term_user_event(term, evt);
 652		break;
 653	case GF_EVENT_AUTHORIZATION:
 654		if (!strlen(evt->auth.user)) {
 655			fprintf(stderr, "Authorization required for site %s\n", evt->auth.site_url);
 656			fprintf(stderr, "login: ");
 657			scanf("%s", evt->auth.user);
 658		} else {
 659			fprintf(stderr, "Authorization required for %s@%s\n", evt->auth.user, evt->auth.site_url);
 660		}
 661		fprintf(stderr, "password: ");
 662		gf_prompt_set_echo_off(1);
 663		scanf("%s", evt->auth.password);
 664		gf_prompt_set_echo_off(0);
 665		return 1;
 666	case GF_EVENT_SYS_COLORS:
 667#ifdef WIN32
 668		evt->sys_cols.sys_colors[0] = get_sys_col(COLOR_ACTIVEBORDER);
 669		evt->sys_cols.sys_colors[1] = get_sys_col(COLOR_ACTIVECAPTION);
 670		evt->sys_cols.sys_colors[2] = get_sys_col(COLOR_APPWORKSPACE);
 671		evt->sys_cols.sys_colors[3] = get_sys_col(COLOR_BACKGROUND);
 672		evt->sys_cols.sys_colors[4] = get_sys_col(COLOR_BTNFACE);
 673		evt->sys_cols.sys_colors[5] = get_sys_col(COLOR_BTNHIGHLIGHT);
 674		evt->sys_cols.sys_colors[6] = get_sys_col(COLOR_BTNSHADOW);
 675		evt->sys_cols.sys_colors[7] = get_sys_col(COLOR_BTNTEXT);
 676		evt->sys_cols.sys_colors[8] = get_sys_col(COLOR_CAPTIONTEXT);
 677		evt->sys_cols.sys_colors[9] = get_sys_col(COLOR_GRAYTEXT);
 678		evt->sys_cols.sys_colors[10] = get_sys_col(COLOR_HIGHLIGHT);
 679		evt->sys_cols.sys_colors[11] = get_sys_col(COLOR_HIGHLIGHTTEXT);
 680		evt->sys_cols.sys_colors[12] = get_sys_col(COLOR_INACTIVEBORDER);
 681		evt->sys_cols.sys_colors[13] = get_sys_col(COLOR_INACTIVECAPTION);
 682		evt->sys_cols.sys_colors[14] = get_sys_col(COLOR_INACTIVECAPTIONTEXT);
 683		evt->sys_cols.sys_colors[15] = get_sys_col(COLOR_INFOBK);
 684		evt->sys_cols.sys_colors[16] = get_sys_col(COLOR_INFOTEXT);
 685		evt->sys_cols.sys_colors[17] = get_sys_col(COLOR_MENU);
 686		evt->sys_cols.sys_colors[18] = get_sys_col(COLOR_MENUTEXT);
 687		evt->sys_cols.sys_colors[19] = get_sys_col(COLOR_SCROLLBAR);
 688		evt->sys_cols.sys_colors[20] = get_sys_col(COLOR_3DDKSHADOW);
 689		evt->sys_cols.sys_colors[21] = get_sys_col(COLOR_3DFACE);
 690		evt->sys_cols.sys_colors[22] = get_sys_col(COLOR_3DHIGHLIGHT);
 691		evt->sys_cols.sys_colors[23] = get_sys_col(COLOR_3DLIGHT);
 692		evt->sys_cols.sys_colors[24] = get_sys_col(COLOR_3DSHADOW);
 693		evt->sys_cols.sys_colors[25] = get_sys_col(COLOR_WINDOW);
 694		evt->sys_cols.sys_colors[26] = get_sys_col(COLOR_WINDOWFRAME);
 695		evt->sys_cols.sys_colors[27] = get_sys_col(COLOR_WINDOWTEXT);
 696		return 1;
 697#else
 698		memset(evt->sys_cols.sys_colors, 0, sizeof(u32)*28);
 699		return 1;
 700#endif
 701		break;
 702	}
 703	return 0;
 704}
 705
 706
 707void list_modules(GF_ModuleManager *modules)
 708{
 709	u32 i;
 710	fprintf(stderr, "\rAvailable modules:\n");
 711	for (i=0; i<gf_modules_get_count(modules); i++) {
 712		char *str = (char *) gf_modules_get_file_name(modules, i);
 713		if (str) fprintf(stderr, "\t%s\n", str);
 714	}
 715	fprintf(stderr, "\n");
 716}
 717
 718
 719void set_navigation()
 720{
 721	GF_Err e;
 722	char navstr[20], nav;
 723	u32 type = gf_term_get_option(term, GF_OPT_NAVIGATION_TYPE);
 724	e = GF_OK;
 725	if (!type) {
 726		fprintf(stdout, "Content/compositor doesn't allow user-selectable navigation\n");
 727	} else if (type==1) {
 728		fprintf(stdout, "Select Navigation (\'N\'one, \'E\'xamine, \'S\'lide): ");
 729		scanf("%s", navstr);
 730		nav = navstr[0];
 731		if (nav=='N') e = gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_NONE);
 732		else if (nav=='E') e = gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_EXAMINE);
 733		else if (nav=='S') e = gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_SLIDE);
 734		else fprintf(stdout, "Unknown selector \'%c\' - only \'N\',\'E\',\'S\' allowed\n", nav);
 735	} else if (type==2) {
 736		fprintf(stdout, "Select Navigation (\'N\'one, \'W\'alk, \'F\'ly, \'E\'xamine, \'P\'an, \'S\'lide, \'G\'ame, \'V\'R, \'O\'rbit): ");
 737		scanf("%s", navstr);
 738		nav = navstr[0];
 739		if (nav=='N') e = gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_NONE);
 740		else if (nav=='W') e = gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_WALK);
 741		else if (nav=='F') e = gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_FLY);
 742		else if (nav=='E') e = gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_EXAMINE);
 743		else if (nav=='P') e = gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_PAN);
 744		else if (nav=='S') e = gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_SLIDE);
 745		else if (nav=='G') e = gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_GAME);
 746		else if (nav=='O') e = gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_ORBIT);
 747		else if (nav=='V') e = gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_VR);
 748		else fprintf(stdout, "Unknown selector %c - only \'N\',\'W\',\'F\',\'E\',\'P\',\'S\',\'G\', \'V\', \'O\' allowed\n", nav);
 749	}
 750	if (e) fprintf(stdout, "Error setting mode: %s\n", gf_error_to_string(e));
 751}
 752
 753
 754static Bool get_time_list(char *arg, u32 *times, u32 *nb_times)
 755{
 756	char *str;
 757	Float var;
 758	Double sec;
 759	u32 h, m, s, ms, f, fps;
 760	if (!arg || (arg[0]=='-') || !isdigit(arg[0])) return 0;
 761
 762	/*SMPTE time code*/
 763	if (strchr(arg, ':') && strchr(arg, ';') && strchr(arg, '/')) {
 764		if (sscanf(arg, "%02d:%02d:%02d;%02d/%02d", &h, &m, &s, &f, &fps)==5) {
 765			sec = 0;
 766			if (fps) sec = ((Double)f) / fps;
 767			sec += 3600*h + 60*m + s;
 768			times[*nb_times] = (u32) (1000*sec);
 769			(*nb_times) ++;
 770			return 1;
 771		}
 772	}
 773	while (arg) {
 774		str = strchr(arg, '-');
 775		if (str) str[0] = 0;
 776		/*HH:MM:SS:MS time code*/
 777		if (strchr(arg, ':') && (sscanf(arg, "%02d:%02d:%02d:%02d", &h, &m, &s, &ms)==4)) {
 778			sec = ms;
 779			sec /= 1000;
 780			sec += 3600*h + 60*m + s;
 781			times[*nb_times] = (u32) (1000*sec);
 782			(*nb_times) ++;
 783		} else if (sscanf(arg, "%f", &var)==1) {
 784			sec = atof(arg);
 785			times[*nb_times] = (u32) (1000*sec);
 786			(*nb_times) ++;
 787		}
 788		if (!str) break;
 789		str[0] = '-';
 790		arg = str+1;
 791	}
 792	return 1;
 793}
 794
 795static void on_gpac_log(void *cbk, u32 ll, u32 lm, const char *fmt, va_list list)
 796{
 797	FILE *logs = cbk;
 798
 799	if (rti_logs && (lm & GF_LOG_RTI)) {
 800		char szMsg[2048];
 801		vsprintf(szMsg, fmt, list);
 802		UpdateRTInfo(szMsg + 6 /*"[RTI] "*/);
 803	} else {
 804		if (log_time_start) fprintf(logs, "[At %d]", gf_sys_clock() - log_time_start);
 805		vfprintf(logs, fmt, list);
 806		fflush(logs);
 807	}
 808}
 809
 810static void init_rti_logs(char *rti_file, char *url, Bool use_rtix)
 811{
 812	if (rti_logs) fclose(rti_logs);
 813	rti_logs = gf_f64_open(rti_file, "wt");
 814	if (rti_logs) {
 815		fprintf(rti_logs, "!! GPAC RunTime Info ");
 816		if (url) fprintf(rti_logs, "for file %s", url);
 817		fprintf(rti_logs, " !!\n");
 818		fprintf(rti_logs, "SysTime(ms)\tSceneTime(ms)\tCPU\tFPS\tMemory(kB)\tObservation\n");
 819
 820		/*turn on RTI loging*/
 821		if (use_rtix) {
 822			gf_log_set_callback(NULL, on_gpac_log);
 823			gf_log_set_tool_level(GF_LOG_ALL, GF_LOG_ERROR);
 824			gf_log_set_tool_level(GF_LOG_RTI, GF_LOG_DEBUG);
 825
 826			GF_LOG(GF_LOG_DEBUG, GF_LOG_RTI, ("[RTI] System state when enabling log\n"));
 827		} else if (log_time_start) {
 828			log_time_start = gf_sys_clock();
 829		}
 830	}
 831}
 832
 833#ifdef GPAC_IPHONE
 834int SDL_main (int argc, char *argv[])
 835#else
 836int main (int argc, char *argv[])
 837#endif
 838{
 839	char c;
 840	const char *str;
 841	u32 i, times[100], nb_times, dump_mode;
 842	u32 simulation_time = 0;
 843	Bool auto_exit = 0;
 844	Bool start_fs = 0;
 845	Bool use_rtix = 0;
 846	Bool rgbds_dump = 0;
 847	Bool rgbd_dump = 0;
 848	Bool depth_dump = 0;
 849	Bool pause_at_first = 0;
 850	Bool enable_mem_tracker = 0;
 851	Double fps = 25.0;
 852	Bool ret, fill_ar, visible;
 853	char *url_arg, *the_cfg, *rti_file;
 854	GF_SystemRTInfo rti;
 855	FILE *playlist = NULL;
 856	FILE *logfile = NULL;
 857	Float scale = 1;
 858	int *libgpac_so = NULL;
 859	
 860	libgpac_so = dlopen("/Applications/osmo4ios.app/libgpac_dynamic.dylib", RTLD_LAZY);
 861	fprintf(stderr, "dlopen libgpac_so: %p\n", libgpac_so);
 862	fprintf(stderr, "dlsym: %p gf_log_lt\n", gf_log_lt = dlsym(libgpac_so, "gf_log_lt"));
 863	fprintf(stderr, "dlsym: %p AVI_close\n", AVI_close = dlsym(libgpac_so, "AVI_close"));
 864	fprintf(stderr, "dlsym: %p gf_sleep\n", gf_sleep = dlsym(libgpac_so, "gf_sleep"));
 865	fprintf(stderr, "dlsym: %p gf_term_del\n", gf_term_del = dlsym(libgpac_so, "gf_term_del"));
 866	fprintf(stderr, "dlsym: %p gf_sc_release_screen_buffer\n", gf_sc_release_screen_buffer = dlsym(libgpac_so, "gf_sc_release_screen_buffer"));
 867	fprintf(stderr, "dlsym: %p gf_prompt_get_char\n", gf_prompt_get_char = dlsym(libgpac_so, "gf_prompt_get_char"));
 868	fprintf(stderr, "dlsym: %p gf_set_progress\n", gf_set_progress = dlsym(libgpac_so, "gf_set_progress"));
 869	fprintf(stderr, "dlsym: %p gf_term_new\n", gf_term_new = dlsym(libgpac_so, "gf_term_new"));
 870	fprintf(stderr, "dlsym: %p gf_term_process_step\n", gf_term_process_step = dlsym(libgpac_so, "gf_term_process_step"));
 871	fprintf(stderr, "dlsym: %p gf_sc_get_screen_buffer\n", gf_sc_get_screen_buffer = dlsym(libgpac_so, "gf_sc_get_screen_buffer"));
 872	fprintf(stderr, "dlsym: %p gf_iphone_set_sdl_audio_module\n", gf_iphone_set_sdl_audio_module = dlsym(libgpac_so, "gf_iphone_set_sdl_audio_module"));
 873	fprintf(stderr, "dlsym: %p gf_term_step_clocks\n", gf_term_step_clocks = dlsym(libgpac_so, "gf_term_step_clocks"));
 874	fprintf(stderr, "dlsym: %p gf_prompt_set_echo_off\n", gf_prompt_set_echo_off = dlsym(libgpac_so, "gf_prompt_set_echo_off"));
 875	fprintf(stderr, "dlsym: %p gf_log_tool_level_on\n", gf_log_tool_level_on = dlsym(libgpac_so, "gf_log_tool_level_on"));
 876	fprintf(stderr, "dlsym: %p gf_cfg_set_key\n", gf_cfg_set_key = dlsym(libgpac_so, "gf_cfg_set_key"));
 877	fprintf(stderr, "dlsym: %p gf_cfg_get_section_count\n", gf_cfg_get_section_count = dlsym(libgpac_so, "gf_cfg_get_section_count"));
 878	fprintf(stderr, "dlsym: %p gf_term_get_service_info\n", gf_term_get_service_info = dlsym(libgpac_so, "gf_term_get_service_info"));
 879	fprintf(stderr, "dlsym: %p gf_term_set_size\n", gf_term_set_size = dlsym(libgpac_so, "gf_term_set_size"));
 880	fprintf(stderr, "dlsym: %p gf_sys_get_rti\n", gf_sys_get_rti = dlsym(libgpac_so, "gf_sys_get_rti"));
 881	fprintf(stderr, "dlsym: %p gf_term_play_from_time\n", gf_term_play_from_time = dlsym(libgpac_so, "gf_term_play_from_time"));
 882	fprintf(stderr, "dlsym: %p gf_malloc\n", gf_malloc = dlsym(libgpac_so, "gf_malloc"));
 883	fprintf(stderr, "dlsym: %p gf_log_set_tool_level\n", gf_log_set_tool_level = dlsym(libgpac_so, "gf_log_set_tool_level"));
 884	fprintf(stderr, "dlsym: %p gf_log_set_tools_levels\n", gf_log_set_tools_levels = dlsym(libgpac_so, "gf_log_set_tools_levels"));
 885	fprintf(stderr, "dlsym: %p gf_log_modify_tools_levels\n", gf_log_modify_tools_levels = dlsym(libgpac_so, "gf_log_modify_tools_levels"));
 886	fprintf(stderr, "dlsym: %p gf_iphone_set_sdl_video_module\n", gf_iphone_set_sdl_video_module = dlsym(libgpac_so, "gf_iphone_set_sdl_video_module"));
 887	fprintf(stderr, "dlsym: %p gf_term_get_option\n", gf_term_get_option = dlsym(libgpac_so, "gf_term_get_option"));
 888	fprintf(stderr, "dlsym: %p gf_term_user_event\n", gf_term_user_event = dlsym(libgpac_so, "gf_term_user_event"));
 889	fprintf(stderr, "dlsym: %p gf_modules_get_file_name\n", gf_modules_get_file_name = dlsym(libgpac_so, "gf_modules_get_file_name"));
 890	fprintf(stderr, "dlsym: %p gf_mx_new\n", gf_mx_new = dlsym(libgpac_so, "gf_mx_new"));
 891	fprintf(stderr, "dlsym: %p gf_list_count\n", gf_list_count = dlsym(libgpac_so, "gf_list_count"));
 892	fprintf(stderr, "dlsym: %p gf_free\n", gf_free = dlsym(libgpac_so, "gf_free"));
 893	fprintf(stderr, "dlsym: %p gf_term_get_world_info\n", gf_term_get_world_info = dlsym(libgpac_so, "gf_term_get_world_info"));
 894	fprintf(stderr, "dlsym: %p gf_cfg_get_section_name\n", gf_cfg_get_section_name = dlsym(libgpac_so, "gf_cfg_get_section_name"));
 895	fprintf(stderr, "dlsym: %p gf_term_navigate_to\n", gf_term_navigate_to = dlsym(libgpac_so, "gf_term_navigate_to"));
 896	fprintf(stderr, "dlsym: %p gf_modules_del\n", gf_modules_del = dlsym(libgpac_so, "gf_modules_del"));
 897	fprintf(stderr, "dlsym: %p gf_modules_new\n", gf_modules_new = dlsym(libgpac_so, "gf_modules_new"));
 898	fprintf(stderr, "dlsym: %p gf_sys_init\n", gf_sys_init = dlsym(libgpac_so, "gf_sys_init"));
 899	fprintf(stderr, "dlsym: %p gf_log\n", gf_log = dlsym(libgpac_so, "gf_log"));
 900	fprintf(stderr, "dlsym: %p gf_term_get_object_info\n", gf_term_get_object_info = dlsym(libgpac_so, "gf_term_get_object_info"));
 901	fprintf(stderr, "dlsym: %p gf_mx_p\n", gf_mx_p = dlsym(libgpac_so, "gf_mx_p"));
 902	fprintf(stderr, "dlsym: %p gf_mx_v\n", gf_mx_v = dlsym(libgpac_so, "gf_mx_v"));
 903	fprintf(stderr, "dlsym: %p gf_mx_del\n", gf_mx_del = dlsym(libgpac_so, "gf_mx_del"));
 904	fprintf(stderr, "dlsym: %p gf_term_process_flush\n", gf_term_process_flush = dlsym(libgpac_so, "gf_term_process_flush"));
 905	fprintf(stderr, "dlsym: %p gf_cfg_get_key_name\n", gf_cfg_get_key_name = dlsym(libgpac_so, "gf_cfg_get_key_name"));
 906	fprintf(stderr, "dlsym: %p AVI_write_frame\n", AVI_write_frame = dlsym(libgpac_so, "AVI_write_frame"));
 907	fprintf(stderr, "dlsym: %p gf_cfg_del\n", gf_cfg_del = dlsym(libgpac_so, "gf_cfg_del"));
 908	fprintf(stderr, "dlsym: %p gf_term_get_channel_net_info\n", gf_term_get_channel_net_info = dlsym(libgpac_so, "gf_term_get_channel_net_info"));
 909	fprintf(stderr, "dlsym: %p gf_term_process_shortcut\n", gf_term_process_shortcut = dlsym(libgpac_so, "gf_term_process_shortcut"));
 910	fprintf(stderr, "dlsym: %p gf_cfg_init\n", gf_cfg_init = dlsym(libgpac_so, "gf_cfg_init"));
 911	fprintf(stderr, "dlsym: %p gf_term_get_download_info\n", gf_term_get_download_info = dlsym(libgpac_so, "gf_term_get_download_info"));
 912	fprintf(stderr, "dlsym: %p gf_sys_clock\n", gf_sys_clock = dlsym(libgpac_so, "gf_sys_clock"));
 913	fprintf(stderr, "dlsym: %p gf_term_get_object\n", gf_term_get_object = dlsym(libgpac_so, "gf_term_get_object"));
 914	fprintf(stderr, "dlsym: %p gf_term_set_option\n", gf_term_set_option = dlsym(libgpac_so, "gf_term_set_option"));
 915	fprintf(stderr, "dlsym: %p gf_sys_close\n", gf_sys_close = dlsym(libgpac_so, "gf_sys_close"));
 916	fprintf(stderr, "dlsym: %p gf_term_connect_from_time\n", gf_term_connect_from_time = dlsym(libgpac_so, "gf_term_connect_from_time"));
 917	fprintf(stderr, "dlsym: %p AVI_open_output_file\n", AVI_open_output_file = dlsym(libgpac_so, "AVI_open_output_file"));
 918	fprintf(stderr, "dlsym: %p gf_cfg_get_key\n", gf_cfg_get_key = dlsym(libgpac_so, "gf_cfg_get_key"));
 919	fprintf(stderr, "dlsym: %p AVI_set_video\n", AVI_set_video = dlsym(libgpac_so, "AVI_set_video"));
 920	fprintf(stderr, "dlsym: %p gf_term_set_speed\n", gf_term_set_speed = dlsym(libgpac_so, "gf_term_set_speed"));
 921	fprintf(stderr, "dlsym: %p gf_cfg_get_key_count\n", gf_cfg_get_key_count = dlsym(libgpac_so, "gf_cfg_get_key_count"));
 922	fprintf(stderr, "dlsym: %p gf_term_object_subscene_type\n", gf_term_object_subscene_type = dlsym(libgpac_so, "gf_term_object_subscene_type"));
 923	fprintf(stderr, "dlsym: %p gf_term_get_framerate\n", gf_term_get_framerate = dlsym(libgpac_so, "gf_term_get_framerate"));
 924	fprintf(stderr, "dlsym: %p gf_error_to_string\n", gf_error_to_string = dlsym(libgpac_so, "gf_error_to_string"));
 925	fprintf(stderr, "dlsym: %p gf_stretch_bits\n", gf_stretch_bits = dlsym(libgpac_so, "gf_stretch_bits"));
 926	fprintf(stderr, "dlsym: %p gf_list_del\n", gf_list_del = dlsym(libgpac_so, "gf_list_del"));
 927	fprintf(stderr, "dlsym: %p gf_list_get\n", gf_list_get = dlsym(libgpac_so, "gf_list_get"));
 928	fprintf(stderr, "dlsym: %p gf_term_disconnect\n", gf_term_disconnect = dlsym(libgpac_so, "gf_term_disconnect"));
 929	fprintf(stderr, "dlsym: %p gf_term_is_supported_url\n", gf_term_is_supported_url = dlsym(libgpac_so, "gf_term_is_supported_url"));
 930	fprintf(stderr, "dlsym: %p gf_list_new\n", gf_list_new = dlsym(libgpac_so, "gf_list_new"));
 931	fprintf(stderr, "dlsym: %p gf_modules_get_option\n", gf_modules_get_option = dlsym(libgpac_so, "gf_modules_get_option"));
 932	fprintf(stderr, "dlsym: %p gf_term_dump_scene\n", gf_term_dump_scene = dlsym(libgpac_so, "gf_term_dump_scene"));
 933	fprintf(stderr, "dlsym: %p gf_prompt_has_input\n", gf_prompt_has_input = dlsym(libgpac_so, "gf_prompt_has_input"));
 934	fprintf(stderr, "dlsym: %p gf_term_scene_update\n", gf_term_scene_update = dlsym(libgpac_so, "gf_term_scene_update"));
 935	fprintf(stderr, "dlsym: %p gf_term_connect\n", gf_term_connect = dlsym(libgpac_so, "gf_term_connect"));
 936	fprintf(stderr, "dlsym: %p gf_term_get_object_count\n", gf_term_get_object_count = dlsym(libgpac_so, "gf_term_get_object_count"));
 937	fprintf(stderr, "dlsym: %p gf_modules_get_count\n", gf_modules_get_count = dlsym(libgpac_so, "gf_modules_get_count"));
 938	fprintf(stderr, "dlsym: %p gf_term_get_root_object\n", gf_term_get_root_object = dlsym(libgpac_so, "gf_term_get_root_object"));
 939	fprintf(stderr, "dlsym: %p gf_term_get_time_in_ms\n", gf_term_get_time_in_ms = dlsym(libgpac_so, "gf_term_get_time_in_ms"));
 940	fprintf(stderr, "dlsym: %p gf_term_connect_with_path\n", gf_term_connect_with_path = dlsym(libgpac_so, "gf_term_connect_with_path"));
 941	fprintf(stderr, "dlsym: %p gf_log_set_callback\n", gf_log_set_callback = dlsym(libgpac_so, "gf_log_set_callback"));
 942	fprintf(stderr, "dlsym: %p gf_term_switch_quality\n", gf_term_switch_quality = dlsym(libgpac_so, "gf_term_switch_quality"));
 943	fprintf(stderr, "dlsym: %p gf_term_release_screen_buffer\n", gf_term_release_screen_buffer = dlsym(libgpac_so, "gf_term_release_screen_buffer"));
 944	fprintf(stderr, "dlsym: %p gf_term_get_screen_buffer\n", gf_term_get_screen_buffer = dlsym(libgpac_so, "gf_term_get_screen_buffer"));
 945	fprintf(stderr, "dlsym: %p gf_f64_open\n", gf_f64_open = dlsym(libgpac_so, "gf_f64_open"));
 946	fprintf(stderr, "dlsym: %p gf_fwrite\n", gf_fwrite = dlsym(libgpac_so, "gf_fwrite"));
 947	fprintf(stderr, "dlsym: %p gf_img_png_enc\n", gf_img_png_enc = dlsym(libgpac_so, "gf_img_png_enc"));
 948	fprintf(stderr, "dlsym: %p utf8_to_ucs4\n", utf8_to_ucs4 = dlsym(libgpac_so, "utf8_to_ucs4"));
 949
 950	/*by default use current dir*/
 951	strcpy(the_url, ".");
 952
 953	memset(&user, 0, sizeof(GF_User));
 954
 955	dump_mode = 0;
 956	fill_ar = visible = 0;
 957	url_arg = the_cfg = rti_file = NULL;
 958	nb_times = 0;
 959	times[0] = 0;
 960
 961	/*first locate config file if specified*/
 962	for (i=1; i<(u32) argc; i++) {
 963		char *arg = argv[i];
 964		if (!strcmp(arg, "-c") || !strcmp(arg, "-cfg")) {
 965			the_cfg = argv[i+1];
 966			i++;
 967		}
 968		else if (!strcmp(arg, "-mem-track")) enable_mem_tracker = 1;
 969	}
 970
 971	gf_sys_init(enable_mem_tracker);
 972	gf_iphone_set_sdl_video_module(SDL_NewVideo);
 973	gf_iphone_set_sdl_audio_module(SDL_NewAudio);
 974	
 975	cfg_file = gf_cfg_init(the_cfg, NULL);
 976	if (!cfg_file) {
 977		fprintf(stdout, "Error: Configuration File \"GPAC.cfg\" not found\n");
 978		if (logfile) fclose(logfile);
 979		return 1;
 980	}
 981
 982	gf_log_set_tools_levels( gf_cfg_get_key(cfg_file, "General", "Logs") );
 983
 984	for (i=1; i<(u32) argc; i++) {
 985		char *arg = argv[i];
 986//		if (isalnum(arg[0]) || (arg[0]=='/') || (arg[0]=='.') || (arg[0]=='\\') ) {
 987		if (arg[0] != '-') {
 988			url_arg = arg;
 989		} else if (!strcmp(arg, "-c") || !strcmp(arg, "-cfg")) {
 990			the_cfg = argv[i+1];
 991			i++;
 992		} else if (!strcmp(arg, "-rti")) {
 993			rti_file = argv[i+1];
 994			i++;
 995		} else if (!strcmp(arg, "-rtix")) {
 996			rti_file = argv[i+1];
 997			i++;
 998			use_rtix = 1;
 999		} else if (!strcmp(arg, "-fill")) {
1000			fill_ar = 1;
1001		} else if (!strcmp(arg, "-show")) {
1002			visible = 1;
1003		} else if (!strcmp(arg, "-avi")) {
1004			if (rgbds_dump) dump_mode = 5;
1005			else if (depth_dump) dump_mode = 8;
1006			else if (rgbd_dump) dump_mode = 10;
1007			else dump_mode=1;
1008			if ((url_arg || (i+2<(u32)argc)) && get_time_list(argv[i+1], times, &nb_times)) i++;
1009		} else if (!strcmp(arg, "-rgbds")) { /*get dump in rgbds pixel format*/
1010			rgbds_dump = 1;
1011			dump_mode=6;                    /* rgbds texture directly*/
1012			if (dump_mode==1) dump_mode = 5;    /* .avi rgbds dump*/
1013		} else if (!strcmp(arg, "-rgbd")) { /*get dump in rgbd pixel format*/
1014			rgbd_dump = 1;
1015			dump_mode=9;  /* rgbd texture directly*/
1016			if (dump_mode==1) dump_mode = 10;    /* .avi rgbds dump*/
1017		} else if (!strcmp(arg, "-depth")) {
1018			depth_dump = 1;        
1019			if (dump_mode==2) dump_mode=7; /* grayscale .bmp depth dump*/
1020			else if (dump_mode==1) dump_mode=8; /* .avi depth dump*/
1021			else dump_mode=4;   /*depth dump*/
1022		} else if (!strcmp(arg, "-bmp")) {
1023			if(depth_dump) dump_mode=7; /*grayscale depth .bmp dump*/
1024			else dump_mode=2;
1025			if ((url_arg || (i+2<(u32)argc)) && get_time_list(argv[i+1], times, &nb_times)) i++;
1026		} else if (!strcmp(arg, "-raw")) {
1027			dump_mode = 3;
1028			if ((url_arg || (i+2<(u32)argc)) && get_time_list(argv[i+1], times, &nb_times)) i++;
1029
1030		} else if (!stricmp(arg, "-size")) {
1031			if (sscanf(argv[i+1], "%dx%d", &forced_width, &forced_height) != 2) {
1032				forced_width = forced_height = 0;
1033			}
1034			i++;
1035		} else if (!stricmp(arg, "-scale")) {
1036			sscanf(argv[i+1], "%f", &scale);
1037			i++;
1038		} else if (!stricmp(arg, "-fps")) {
1039			fps = atof(argv[i+1]);
1040			i++;
1041		} else if (!strcmp(arg, "-quiet")) {
1042			be_quiet = 1;
1043		} else if (!strcmp(arg, "-log-file") || !strcmp(arg, "-lf")) {
1044			logfile = gf_f64_open(argv[i+1], "wt");
1045			gf_log_set_callback(logfile, on_gpac_log);
1046			i++;
1047		} else if (!strcmp(arg, "-logs")) {
1048			gf_log_set_tools_levels( argv[i+1] );
1049			i++;
1050		} else if (!strcmp(arg, "-log-clock") || !strcmp(arg, "-lc")) {
1051			log_time_start = 1;
1052		} else if (!strcmp(arg, "-align")) {
1053			if (argv[i+1][0]=='m') align_mode = 1;
1054			else if (argv[i+1][0]=='b') align_mode = 2;
1055			align_mode <<= 8;
1056			if (argv[i+1][1]=='m') align_mode |= 1;
1057			else if (argv[i+1][1]=='r') align_mode |= 2;
1058			i++;
1059		}
1060		else if (!strcmp(arg, "-no-wnd")) user.init_flags |= GF_TERM_WINDOWLESS;
1061#if defined(__DARWIN__) || defined(__APPLE__)
1062		else if (!strcmp(arg, "-thread")) not_threaded = 0;
1063#else
1064		else if (!strcmp(arg, "-no-thread")) not_threaded = 1;
1065#endif
1066		else if (!strcmp(arg, "-no-audio")) no_audio = 1;
1067		else if (!strcmp(arg, "-no-regulation")) no_regulation = 1;
1068		else if (!strcmp(arg, "-fs")) start_fs = 1;
1069		else if (!strcmp(arg, "-pause")) pause_at_first = 1;
1070		else if (!strcmp(arg, "-exit")) auto_exit = 1;
1071		else if (!strcmp(arg, "-mem-track")) enable_mem_tracker = 1;
1072		else if (!strcmp(arg, "-opt")) {
1073			char *sep, *sep2, szSec[1024], szKey[1024], szVal[1024];
1074			sep = strchr(argv[i+1], ':');
1075			if (sep) {
1076				sep[0] = 0;
1077				strcpy(szSec, argv[i+1]);
1078				sep[0] = ':'; sep ++;
1079				sep2 = strchr(sep, '=');
1080				if (sep2) {
1081					sep2[0] = 0;
1082					strcpy(szKey, sep);
1083					strcpy(szVal, sep2+1);
1084					sep2[0] = '='; 
1085					if (!stricmp(szVal, "null")) szVal[0]=0;
1086					gf_cfg_set_key(cfg_file, szSec, szKey, szVal[0] ? szVal : NULL);
1087				}
1088			}
1089			i++;
1090		}
1091		else if (!strncmp(arg, "-run-for=", 9)) simulation_time = atoi(arg+9);
1092		else {
1093			PrintUsage();
1094			return 1;
1095		}
1096	}
1097	if (!logfile) {
1098		const char *opt = gf_cfg_get_key(cfg_file, "General", "LogFile");
1099		if (opt) {
1100			logfile = gf_f64_open(opt, "wt");
1101			if (logfile) 
1102				gf_log_set_callback(logfile, on_gpac_log);
1103		}
1104	}
1105		
1106	if (dump_mode && !url_arg) {
1107		fprintf(stdout, "Missing argument for dump\n");
1108		PrintUsage();
1109		if (logfile) fclose(logfile);
1110		return 1;
1111	}
1112	if (dump_mode) rti_file = NULL;
1113
1114	gf_sys_get_rti(500, &rti, GF_RTI_SYSTEM_MEMORY_ONLY);
1115	memory_at_gpac_startup = rti.physical_memory_avail;
1116	if (rti_file) init_rti_logs(rti_file, url_arg, use_rtix);
1117
1118	/*setup dumping options*/
1119	if (dump_mode) {
1120		user.init_flags |= GF_TERM_NO_AUDIO | GF_TERM_NO_COMPOSITOR_THREAD | GF_TERM_NO_REGULATION /*| GF_TERM_INIT_HIDE*/;
1121		if (visible || dump_mode==8) user.init_flags |= GF_TERM_INIT_HIDE;
1122	} else {
1123		init_w = forced_width;
1124		init_h = forced_height;
1125	}
1126
1127	fprintf(stderr, "Loading modules\n");
1128	str = gf_cfg_get_key(cfg_file, "General", "ModulesDirectory");
1129
1130	user.modules = gf_modules_new((const unsigned char *) str, cfg_file);
1131	if (user.modules) i = gf_modules_get_count(user.modules);
1132	if (!i || !user.modules) {
1133		fprintf(stdout, "Error: no modules found in %s - exiting\n", str);
1134		if (user.modules) gf_modules_del(user.modules);
1135		gf_cfg_del(cfg_file);
1136		gf_sys_close();
1137		if (logfile) fclose(logfile);
1138		return 1;
1139	}
1140	fprintf(stderr, "Modules Loaded (%d found in %s)\n", i, str);
1141	
1142	user.config = cfg_file;
1143	user.EventProc = GPAC_EventProc;
1144	/*dummy in this case (global vars) but MUST be non-NULL*/
1145	user.opaque = user.modules;
1146	if (not_threaded) user.init_flags |= GF_TERM_NO_COMPOSITOR_THREAD;
1147	if (no_audio) user.init_flags |= GF_TERM_NO_AUDIO;
1148	if (no_regulation) user.init_flags |= GF_TERM_NO_REGULATION;
1149
1150	fprintf(stderr, "Loading GPAC Terminal\n");	
1151	term = gf_term_new(&user);
1152	if (!term) {
1153		fprintf(stderr, "\nInit error - check you have at least one video out and one rasterizer...\nFound modules:\n");
1154		list_modules(user.modules);
1155		gf_modules_del(user.modules);
1156		gf_cfg_del(cfg_file);
1157		gf_sys_close();
1158		if (logfile) fclose(logfile);
1159		return 1;
1160	}
1161	fprintf(stderr, "Terminal Loaded\n");
1162
1163
1164	if (dump_mode) {
1165//		gf_term_set_option(term, GF_OPT_VISIBLE, 0);
1166		if (fill_ar) gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_FILL_SCREEN);
1167	} else {
1168		/*check video output*/
1169		str = gf_cfg_get_key(cfg_file, "Video", "DriverName");
1170		if (!strcmp(str, "Raw Video Output")) fprintf(stdout, "WARNING: using raw output video (memory only) - no display used\n");
1171		/*check audio output*/
1172		str = gf_cfg_get_key(cfg_file, "Audio", "DriverName");
1173		if (!str || !strcmp(str, "No Audio Output Available")) fprintf(stdout, "WARNING: no audio output availble - make sure no other program is locking the sound card\n");
1174
1175		str = gf_cfg_get_key(cfg_file, "General", "NoMIMETypeFetch");
1176		no_mime_check = (str && !stricmp(str, "yes")) ? 1 : 0;
1177	}
1178
1179	str = gf_cfg_get_key(cfg_file, "HTTPProxy", "Enabled");
1180	if (str && !strcmp(str, "yes")) {
1181		str = gf_cfg_get_key(cfg_file, "HTTPProxy", "Name");
1182		if (str) fprintf(stdout, "HTTP Proxy %s enabled\n", str);
1183	}
1184
1185	if (rti_file) {
1186		str = gf_cfg_get_key(cfg_file, "General", "RTIRefreshPeriod");
1187		if (str) {
1188			rti_update_time_ms = atoi(str);
1189		} else {
1190			gf_cfg_set_key(cfg_file, "General", "RTIRefreshPeriod", "200");
1191		}
1192		UpdateRTInfo("At GPAC load time\n");
1193	}
1194
1195	Run = 1;
1196	ret = 1;
1197
1198	if (dump_mode) {
1199		if (!nb_times) {
1200			times[0] = 0;
1201			nb_times++;
1202		}
1203		ret = dump_file(url_arg, dump_mode, fps, forced_width, forced_height, scale, times, nb_times);
1204		Run = 0;
1205	} else
1206
1207	/*connect if requested*/
1208	if (url_arg) {
1209		char *ext;
1210		strcpy(the_url, url_arg);
1211		ext = strrchr(the_url, '.');
1212		if (ext && (!stricmp(ext, ".m3u") || !stricmp(ext, ".pls"))) {
1213			fprintf(stdout, "Opening Playlist %s\n", the_url);
1214			playlist = gf_f64_open(the_url, "rt");
1215			if (playlist) {
1216				strcpy(pl_path, the_url);
1217				fscanf(playlist, "%s", the_url);
1218				fprintf(stdout, "Opening URL %s\

Large files files are truncated, but you can click here to view the full file