PageRenderTime 61ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/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
Possible License(s): LGPL-2.1, GPL-2.0
  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. #include "libgpac_symbols.h"
  25. void (*gf_log_lt)(u32 ll, u32 lt);
  26. int (*AVI_close)(avi_t *AVI);
  27. GF_Err (*gf_term_del)(GF_Terminal *term);
  28. void (*gf_sleep)(u32 ms);
  29. GF_Err (*gf_sc_release_screen_buffer)(GF_Compositor *sr, GF_VideoSurface *framebuffer);
  30. char (*gf_prompt_get_char)();
  31. void (*gf_set_progress)(char *title, u32 done, u32 total);
  32. GF_Terminal *(*gf_term_new)(GF_User *user);
  33. GF_Err (*gf_term_process_step)(GF_Terminal *term);
  34. GF_Err (*gf_sc_get_screen_buffer)(GF_Compositor *sr, GF_VideoSurface *framebuffer, Bool depth_buffer);
  35. void (*gf_iphone_set_sdl_audio_module)(void* (*SDL_Module) (void));
  36. GF_Err (*gf_term_step_clocks)(GF_Terminal * term, u32 ms_diff);
  37. void (*gf_prompt_set_echo_off)(Bool echo_off);
  38. u32 (*gf_log_tool_level_on)();
  39. GF_Err (*gf_cfg_set_key)(GF_Config *cfgFile, const char *secName, const char *keyName, const char *keyValue);
  40. u32 (*gf_cfg_get_section_count)(GF_Config *cfgFile);
  41. GF_Err (*gf_term_get_service_info)(GF_Terminal *term, GF_ObjectManager *odm, NetInfoCommand *netcom);
  42. GF_Err (*gf_term_set_size)(GF_Terminal *term, u32 NewWidth, u32 NewHeight);
  43. Bool (*gf_sys_get_rti)(u32 refresh_time_ms, GF_SystemRTInfo *rti, u32 flags);
  44. u32 (*gf_term_play_from_time)(GF_Terminal *term, u64 from_time, u32 pause_at_first_frame);
  45. void *(*gf_malloc)(size_t size);
  46. void (*gf_log_set_tools_levels)(const char *);
  47. void (*gf_log_set_tool_level)(u32, u32);
  48. void (*gf_log_modify_tools_level)(const char *);
  49. void (*gf_iphone_set_sdl_video_module)(void* (*SDL_Module) (void));
  50. u32 (*gf_term_get_option)(GF_Terminal *term, u32 opt_type);
  51. Bool (*gf_term_user_event)(GF_Terminal *term, GF_Event *event);
  52. const char *(*gf_modules_get_file_name)(GF_ModuleManager *pm, u32 index);
  53. GF_Mutex *(*gf_mx_new)(const char *name);
  54. u32 (*gf_list_count)(GF_List *ptr);
  55. void (*gf_free)(void *ptr);
  56. const char *(*gf_term_get_world_info)(GF_Terminal *term, GF_ObjectManager *scene_od, GF_List *descriptions);
  57. const char *(*gf_cfg_get_section_name)(GF_Config *cfgFile, u32 secIndex);
  58. void (*gf_term_navigate_to)(GF_Terminal *term, const char *toURL);
  59. void (*gf_modules_del)(GF_ModuleManager *pm);
  60. GF_ModuleManager *(*gf_modules_new)(const char *directory, GF_Config *cfgFile);
  61. void (*gf_sys_init)(Bool enable_memory_tracker);
  62. void (*gf_log)(const char *fmt, ...);
  63. GF_Err (*gf_term_get_object_info)(GF_Terminal *term, GF_ObjectManager *odm, GF_MediaInfo *info);
  64. u32 (*gf_mx_p)(GF_Mutex *mx);
  65. u32 (*gf_mx_v)(GF_Mutex *mx);
  66. void (*gf_mx_del)(GF_Mutex *mx);
  67. GF_Err (*gf_term_process_flush)(GF_Terminal *term);
  68. const char *(*gf_cfg_get_key_name)(GF_Config *cfgFile, const char *secName, u32 keyIndex);
  69. int (*AVI_write_frame)(avi_t *AVI, char *data, long bytes, int keyframe);
  70. void (*gf_cfg_del)(GF_Config *iniFile);
  71. Bool (*gf_term_get_channel_net_info)(GF_Terminal *term, GF_ObjectManager *odm, u32 *d_enum, u32 *chid, NetStatCommand *netcom, GF_Err *ret_code);
  72. void (*gf_term_process_shortcut)(GF_Terminal *term, GF_Event *ev);
  73. GF_Config *(*gf_cfg_init)(const char *fileName, Bool *is_new);
  74. Bool (*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);
  75. u32 (*gf_sys_clock)();
  76. GF_ObjectManager *(*gf_term_get_object)(GF_Terminal *term, GF_ObjectManager *scene_od, u32 index);
  77. GF_Err (*gf_term_set_option)(GF_Terminal *term, u32 opt_type, u32 opt_value);
  78. void (*gf_sys_close)();
  79. void (*gf_term_connect_from_time)(GF_Terminal *term, const char *URL, u64 time_in_ms, Bool pause_at_first_frame);
  80. avi_t* (*AVI_open_output_file)(char * filename);
  81. const char *(*gf_cfg_get_key)(GF_Config *cfgFile, const char *secName, const char *keyName);
  82. void (*AVI_set_video)(avi_t *AVI, int width, int height, double fps, char *compressor);
  83. void (*gf_term_set_speed)(GF_Terminal *term, Fixed speed);
  84. u32 (*gf_cfg_get_key_count)(GF_Config *cfgFile, const char *secName);
  85. u32 (*gf_term_object_subscene_type)(GF_Terminal *term, GF_ObjectManager *odm);
  86. Double (*gf_term_get_framerate)(GF_Terminal *term, Bool absoluteFPS);
  87. const char *(*gf_error_to_string)(GF_Err e);
  88. GF_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);
  89. void (*gf_list_del)(GF_List *ptr);
  90. void *(*gf_list_get)(GF_List *ptr, u32 itemNumber);
  91. void (*gf_term_disconnect)(GF_Terminal *term);
  92. Bool (*gf_term_is_supported_url)(GF_Terminal *term, const char *fileName, Bool use_parent_url, Bool no_mime_check);
  93. GF_List *(*gf_list_new)(void);
  94. const char *(*gf_modules_get_option)(GF_BaseInterface *interface_obj, const char *secName, const char *keyName);
  95. GF_Err (*gf_term_dump_scene)(GF_Terminal *term, char *rad_name, char **filename, Bool xml_dump, Bool skip_proto, GF_ObjectManager *odm);
  96. Bool (*gf_prompt_has_input)();
  97. GF_Err (*gf_term_scene_update)(GF_Terminal *term, char *type, char *com);
  98. void (*gf_term_connect)(GF_Terminal *term, const char *URL);
  99. u32 (*gf_term_get_object_count)(GF_Terminal *term, GF_ObjectManager *scene_od);
  100. u32 (*gf_modules_get_count)(GF_ModuleManager *pm);
  101. GF_ObjectManager *(*gf_term_get_root_object)(GF_Terminal *term);
  102. u32 (*gf_term_get_time_in_ms)(GF_Terminal *term);
  103. void (*gf_term_connect_with_path)(GF_Terminal *term, const char *URL, const char *parent_URL);
  104. gf_log_cbk (*gf_log_set_callback)(void *usr_cbk, gf_log_cbk cbk);
  105. GF_Err (*gf_log_modify_tools_levels)(const char *val);
  106. void (*gf_term_switch_quality)(GF_Terminal *term, Bool up);
  107. GF_Err (*gf_term_release_screen_buffer)(GF_Terminal *term, GF_VideoSurface *framebuffer);
  108. GF_Err (*gf_term_get_screen_buffer)(GF_Terminal *term, GF_VideoSurface *framebuffer);
  109. FILE *(*gf_f64_open)(const char *file_name, const char *mode);
  110. size_t (*gf_fwrite)(const void *ptr, size_t size, size_t nmemb, FILE *stream);
  111. GF_Err (*gf_img_png_enc)(char *data, u32 width, u32 height, s32 stride, u32 pixel_format, char *dst, u32 *dst_size);
  112. u32 (*utf8_to_ucs4)(u32 *ucs4_buf, u32 utf8_len, unsigned char *utf8_buf);
  113. #ifndef WIN32
  114. #include <pwd.h>
  115. #include <unistd.h>
  116. #else
  117. #include <windows.h> /*for GetModuleFileName*/
  118. #include <direct.h> /*for _mkdir*/
  119. #include <shlobj.h> /*for getting user-dir*/
  120. #ifndef SHGFP_TYPE_CURRENT
  121. #define SHGFP_TYPE_CURRENT 0 /*needed for MinGW*/
  122. #endif
  123. #ifdef _MSC_VER
  124. /*get rid of console*/
  125. #if 0
  126. #pragma comment(linker,"/SUBSYSTEM:WINDOWS")
  127. #pragma comment(linker,"/ENTRY:main")
  128. #else
  129. #pragma comment(linker,"/SUBSYSTEM:CONSOLE")
  130. #endif
  131. #endif // _MSC_VER
  132. #endif //WIN32
  133. /*local prototypes*/
  134. void PrintWorldInfo(GF_Terminal *term);
  135. void ViewOD(GF_Terminal *term, u32 OD_ID, u32 number);
  136. void PrintODList(GF_Terminal *term, GF_ObjectManager *root_odm, u32 num, u32 indent, char *root_name);
  137. void ViewODs(GF_Terminal *term, Bool show_timing);
  138. void PrintGPACConfig();
  139. static Bool restart = 0;
  140. #if defined(__DARWIN__) || defined(__APPLE__)
  141. static Bool not_threaded = 1;
  142. #else
  143. static Bool not_threaded = 0;
  144. #endif
  145. static Bool no_audio = 0;
  146. static Bool no_regulation = 0;
  147. static Bool bench_mode = 0;
  148. Bool is_connected = 0;
  149. Bool startup_file = 0;
  150. GF_User user;
  151. GF_Terminal *term;
  152. u64 Duration;
  153. GF_Err last_error = GF_OK;
  154. static Fixed bench_speed = FLT2FIX(20);
  155. static Bool request_next_playlist_item = 0;
  156. static GF_Config *cfg_file;
  157. static Bool display_rti = 0;
  158. static Bool Run;
  159. static Bool CanSeek = 0;
  160. static u32 Volume=100;
  161. static char the_url[GF_MAX_PATH];
  162. static char pl_path[GF_MAX_PATH];
  163. static Bool no_mime_check = 1;
  164. static Bool be_quiet = 0;
  165. static u32 log_time_start = 0;
  166. static u32 forced_width=0;
  167. static u32 forced_height=0;
  168. /*windowless options*/
  169. u32 align_mode = 0;
  170. u32 init_w = 0;
  171. u32 init_h = 0;
  172. u32 last_x, last_y;
  173. Bool right_down = 0;
  174. void dump_frame(GF_Terminal *term, char *rad_path, u32 dump_type, u32 frameNum);
  175. Bool dump_file(char *the_url, u32 dump_mode, Double fps, u32 width, u32 height, Float scale, u32 *times, u32 nb_times);
  176. void PrintUsage()
  177. {
  178. fprintf(stdout, "Usage Osmo4iOS [options] [filename]\n"
  179. "\t-c fileName: user-defined configuration file\n"
  180. "\t-rti fileName: logs run-time info (FPS, CPU, Mem usage) to file\n"
  181. "\t-rtix fileName: same as -rti but driven by GPAC logs\n"
  182. "\t-quiet: removes script message, buffering and downloading status\n"
  183. "\t-opt option: Overrides an option in the configuration file. String format is section:key=value\n"
  184. "\t-log-file file: sets output log file.\n"
  185. "\t-log-level lev: sets log level. Possible values are:\n"
  186. "\t \"error\" : logs only error messages\n"
  187. "\t \"warning\" : logs error+warning messages\n"
  188. "\t \"info\" : logs error+warning+info messages\n"
  189. "\t \"debug\" : logs all messages\n"
  190. "\n"
  191. "\t-log-tools lt: sets tool(s) to log. List of \':\'-separated values:\n"
  192. "\t \"core\" : libgpac core\n"
  193. "\t \"coding\" : bitstream formats (audio, video, scene)\n"
  194. "\t \"container\" : container formats (ISO File, MPEG-2 TS, AVI, ...)\n"
  195. "\t \"network\" : network data exept RTP trafic\n"
  196. "\t \"rtp\" : rtp trafic\n"
  197. "\t \"author\" : authoring tools (hint, import, export)\n"
  198. "\t \"sync\" : terminal sync layer\n"
  199. "\t \"codec\" : terminal codec messages\n"
  200. "\t \"parser\" : scene parsers (svg, xmt, bt) and other\n"
  201. "\t \"media\" : terminal media object management\n"
  202. "\t \"scene\" : scene graph and scene manager\n"
  203. "\t \"script\" : scripting engine messages\n"
  204. "\t \"interact\" : interaction engine (events, scripts, etc)\n"
  205. "\t \"compose\" : composition engine (2D, 3D, etc)\n"
  206. "\t \"service\" : network service management\n"
  207. "\t \"mmio\" : Audio/Video HW I/O management\n"
  208. "\t \"none\" : no tool logged\n"
  209. "\t \"all\" : all tools logged\n"
  210. "\n"
  211. "\t-size WxH: specifies visual size (default: scene size)\n"
  212. "\t-scale s: scales the visual size (default: 1)\n"
  213. #if defined(__DARWIN__) || defined(__APPLE__)
  214. "\t-thread: enables thread usage for terminal and compositor \n"
  215. #else
  216. "\t-no-thread: disables thread usage (except for audio)\n"
  217. #endif
  218. "\t-no-audio: disables audio \n"
  219. "\t-no-wnd: uses windowless mode (Win32 only)\n"
  220. "\t-align vh: specifies v and h alignment for windowless mode\n"
  221. " possible v values: t(op), m(iddle), b(ottom)\n"
  222. " possible h values: l(eft), m(iddle), r(ight)\n"
  223. " default alignment is top-left\n"
  224. " default alignment is top-left\n"
  225. "\t-pause: pauses at first frame\n"
  226. "\n"
  227. "Dumper Options:\n"
  228. "\t-bmp [times]: dumps given frames to bmp\n"
  229. "\t-raw [times]: dumps given frames to bmp\n"
  230. "\t-avi [times]: dumps given file to raw avi\n"
  231. "\t-rgbds: dumps the RGBDS pixel format texture\n"
  232. " with -avi [times]: dumps an rgbds-format .avi\n"
  233. "\t-rgbd: dumps the RGBD pixel format texture\n"
  234. " with -avi [times]: dumps an rgbd-format .avi\n"
  235. "\t-depth: dumps depthmap (z-buffer) frames\n"
  236. " with -avi [times]: dumps depthmap in grayscale .avi\n"
  237. " with -bmp: dumps depthmap in grayscale .bmp\n"
  238. "\t-fps FPS: specifies frame rate for AVI dumping (default: 25.0)\n"
  239. "\t-2d: uses 2D compositor\n"
  240. "\t-3d: uses 3D compositor\n"
  241. "\t-fill: uses fill aspect ratio for dumping (default: none)\n"
  242. "\t-show: show window while dumping (default: no)\n"
  243. "MP4Client - GPAC command line player and dumper - version %s\n"
  244. "GPAC Written by Jean Le Feuvre (c) 2001-2005 - ENST (c) 2005-200X\n",
  245. GPAC_FULL_VERSION
  246. );
  247. }
  248. void PrintHelp()
  249. {
  250. fprintf(stdout, "MP4Client command keys:\n"
  251. "\to: connect to the specified URL\n"
  252. "\tO: connect to the specified URL in playlist mode\n"
  253. "\tN: switch to the next URL in the playlist (works with return key as well)\n"
  254. "\tr: restart current presentation\n"
  255. "\tp: play/pause the presentation\n"
  256. "\ts: step one frame ahead\n"
  257. "\tz: seek into presentation\n"
  258. "\tt: print current timing\n"
  259. "\n"
  260. "\tw: view world info\n"
  261. "\tv: view Object Descriptor list\n"
  262. "\ti: view Object Descriptor info (by ID)\n"
  263. "\tj: view Object Descriptor info (by number)\n"
  264. "\tb: view media objects timing and buffering info\n"
  265. "\tm: view media objects buffering and memory info\n"
  266. "\td: dumps scene graph\n"
  267. "\n"
  268. "\tC: Enable Streaming Cache\n"
  269. "\tS: Stops Streaming Cache and save to file\n"
  270. "\tA: Aborts Streaming Cache\n"
  271. "\n"
  272. "\tk: turns stress mode on/off\n"
  273. "\tn: changes navigation mode\n"
  274. "\tx: reset to last active viewpoint\n"
  275. "\n"
  276. "\t2: restart using 2D compositor\n"
  277. "\t3: restart using 3D compositor\n"
  278. "\n"
  279. "\t4: forces 4/3 Aspect Ratio\n"
  280. "\t5: forces 16/9 Aspect Ratio\n"
  281. "\t6: forces no Aspect Ratio (always fill screen)\n"
  282. "\t7: forces original Aspect Ratio (default)\n"
  283. "\n"
  284. "\tL: changes to new log level. CF MP4Client usage for possible values\n"
  285. "\tT: select new tools to log. CF MP4Client usage for possible values\n"
  286. "\n"
  287. "\tl: list available modules\n"
  288. "\tc: prints some GPAC configuration info\n"
  289. "\tR: toggles run-time info display on/off\n"
  290. "\tq: exit the application\n"
  291. "\th: print this message\n"
  292. "\n"
  293. "MP4Client - GPAC command line player - version %s\n"
  294. "GPAC Written by Jean Le Feuvre (c) 2001-2005 - ENST (c) 2005-200X\n",
  295. GPAC_FULL_VERSION
  296. );
  297. }
  298. static void PrintTime(u64 time)
  299. {
  300. u32 ms, h, m, s;
  301. h = (u32) (time / 1000 / 3600);
  302. m = (u32) (time / 1000 / 60 - h*60);
  303. s = (u32) (time / 1000 - h*3600 - m*60);
  304. ms = (u32) (time - (h*3600 + m*60 + s) * 1000);
  305. fprintf(stdout, "%02d:%02d:%02d.%02d", h, m, s, ms);
  306. }
  307. static u32 rti_update_time_ms = 200;
  308. static FILE *rti_logs = NULL;
  309. static u64 memory_at_gpac_startup = 0;
  310. static void UpdateRTInfo(const char *legend)
  311. {
  312. GF_SystemRTInfo rti;
  313. /*refresh every second*/
  314. if (!display_rti && !rti_logs) return;
  315. if (!gf_sys_get_rti(rti_update_time_ms, &rti, 0) && !legend)
  316. return;
  317. if (display_rti) {
  318. if (!rti.process_memory) rti.process_memory = (u32) (memory_at_gpac_startup-rti.physical_memory_avail);
  319. if (!rti.gpac_memory) rti.gpac_memory = (u32) (memory_at_gpac_startup-rti.physical_memory_avail);
  320. if (display_rti==2) {
  321. fprintf(stdout, "FPS %02.2f - CPU %02d (%02d) - Mem %d kB\r",
  322. gf_term_get_framerate(term, 0), rti.total_cpu_usage, rti.process_cpu_usage, (u32) (rti.gpac_memory / 1024) );
  323. } else {
  324. char szMsg[1024];
  325. GF_Event evt;
  326. sprintf(szMsg, "FPS %02.2f - CPU %02d (%02d) - Mem %d kB",
  327. gf_term_get_framerate(term, 0), rti.total_cpu_usage, rti.process_cpu_usage, (u32) (rti.gpac_memory / 1024) );
  328. evt.type = GF_EVENT_SET_CAPTION;
  329. evt.caption.caption = szMsg;
  330. gf_term_user_event(term, &evt);
  331. }
  332. }
  333. if (rti_logs) {
  334. fprintf(rti_logs, "% 8d\t% 8d\t% 8d\t% 4d\t% 8d\t%s",
  335. gf_sys_clock(),
  336. gf_term_get_time_in_ms(term),
  337. rti.total_cpu_usage,
  338. (u32) gf_term_get_framerate(term, 0),
  339. (u32) (rti.gpac_memory / 1024),
  340. legend ? legend : ""
  341. );
  342. if (!legend) fprintf(rti_logs, "\n");
  343. }
  344. }
  345. static void ResetCaption()
  346. {
  347. GF_Event event;
  348. if (display_rti) return;
  349. event.type = GF_EVENT_SET_CAPTION;
  350. if (is_connected) {
  351. char szName[1024];
  352. NetInfoCommand com;
  353. event.caption.caption = NULL;
  354. /*get any service info*/
  355. if (!startup_file && gf_term_get_service_info(term, gf_term_get_root_object(term), &com) == GF_OK) {
  356. strcpy(szName, "");
  357. if (com.track_info) {
  358. char szBuf[10];
  359. sprintf(szBuf, "%02d ", (u32) (com.track_info>>16) );
  360. strcat(szName, szBuf);
  361. }
  362. if (com.artist) { strcat(szName, com.artist); strcat(szName, " "); }
  363. if (com.name) { strcat(szName, com.name); strcat(szName, " "); }
  364. if (com.album) { strcat(szName, "("); strcat(szName, com.album); strcat(szName, ")"); }
  365. if (strlen(szName)) event.caption.caption = szName;
  366. }
  367. if (!event.caption.caption) {
  368. char *str = strrchr(the_url, '\\');
  369. if (!str) str = strrchr(the_url, '/');
  370. event.caption.caption = str ? str+1 : the_url;
  371. }
  372. } else {
  373. event.caption.caption = "GPAC MP4Client " GPAC_FULL_VERSION;
  374. }
  375. gf_term_user_event(term, &event);
  376. }
  377. #ifdef WIN32
  378. u32 get_sys_col(int idx)
  379. {
  380. u32 res;
  381. DWORD val = GetSysColor(idx);
  382. res = (val)&0xFF; res<<=8;
  383. res |= (val>>8)&0xFF; res<<=8;
  384. res |= (val>>16)&0xFF;
  385. return res;
  386. }
  387. #endif
  388. void switch_bench()
  389. {
  390. if (is_connected) {
  391. bench_mode = !bench_mode;
  392. display_rti = !display_rti;
  393. ResetCaption();
  394. gf_term_set_speed(term, bench_mode ? bench_speed : FIX_ONE);
  395. }
  396. }
  397. Bool GPAC_EventProc(void *ptr, GF_Event *evt)
  398. {
  399. if (!term) return 0;
  400. switch (evt->type) {
  401. case GF_EVENT_DURATION:
  402. Duration = 1000;
  403. Duration = (u64) (((s64) Duration) * evt->duration.duration);
  404. CanSeek = evt->duration.can_seek;
  405. break;
  406. case GF_EVENT_MESSAGE:
  407. {
  408. const char *servName;
  409. if (!evt->message.service || !strcmp(evt->message.service, the_url)) {
  410. servName = "main service";
  411. } else if (!strnicmp(evt->message.service, "data:", 5)) {
  412. servName = "";
  413. } else {
  414. servName = evt->message.service;
  415. }
  416. if (!evt->message.message) return 0;
  417. if (evt->message.error) {
  418. if (!is_connected) last_error = evt->message.error;
  419. fprintf(stderr, "%s (%s): %s\n", evt->message.message, servName, gf_error_to_string(evt->message.error));
  420. } else if (!be_quiet)
  421. fprintf(stderr, "(%s) %s\r", servName, evt->message.message);
  422. }
  423. break;
  424. case GF_EVENT_PROGRESS:
  425. {
  426. char *szTitle = "";
  427. if (evt->progress.progress_type==0) szTitle = "Buffer ";
  428. else if (evt->progress.progress_type==1) szTitle = "Download ";
  429. else if (evt->progress.progress_type==2) szTitle = "Import ";
  430. gf_set_progress(szTitle, evt->progress.done, evt->progress.total);
  431. }
  432. break;
  433. case GF_EVENT_DBLCLICK:
  434. gf_term_set_option(term, GF_OPT_FULLSCREEN, !gf_term_get_option(term, GF_OPT_FULLSCREEN));
  435. return 0;
  436. case GF_EVENT_MOUSEDOWN:
  437. if (evt->mouse.button==GF_MOUSE_RIGHT) {
  438. right_down = 1;
  439. last_x = evt->mouse.x;
  440. last_y = evt->mouse.y;
  441. }
  442. return 0;
  443. case GF_EVENT_MOUSEUP:
  444. if (evt->mouse.button==GF_MOUSE_RIGHT) {
  445. right_down = 0;
  446. last_x = evt->mouse.x;
  447. last_y = evt->mouse.y;
  448. }
  449. return 0;
  450. case GF_EVENT_MOUSEMOVE:
  451. if (right_down && (user.init_flags & GF_TERM_WINDOWLESS) ) {
  452. GF_Event move;
  453. move.move.x = evt->mouse.x - last_x;
  454. move.move.y = last_y-evt->mouse.y;
  455. move.type = GF_EVENT_MOVE;
  456. move.move.relative = 1;
  457. gf_term_user_event(term, &move);
  458. }
  459. return 0;
  460. case GF_EVENT_KEYUP:
  461. switch (evt->key.key_code) {
  462. case GF_KEY_SPACE:
  463. if (evt->key.flags & GF_KEY_MOD_CTRL) switch_bench();
  464. break;
  465. }
  466. break;
  467. case GF_EVENT_KEYDOWN:
  468. gf_term_process_shortcut(term, evt);
  469. switch (evt->key.key_code) {
  470. case GF_KEY_SPACE:
  471. if (evt->key.flags & GF_KEY_MOD_CTRL) {
  472. /*ignore key repeat*/
  473. if (!bench_mode) switch_bench();
  474. }
  475. break;
  476. case GF_KEY_PAGEDOWN:
  477. case GF_KEY_MEDIANEXTTRACK:
  478. request_next_playlist_item = 1;
  479. break;
  480. case GF_KEY_MEDIAPREVIOUSTRACK:
  481. break;
  482. case GF_KEY_ESCAPE:
  483. gf_term_set_option(term, GF_OPT_FULLSCREEN, !gf_term_get_option(term, GF_OPT_FULLSCREEN));
  484. break;
  485. case GF_KEY_F:
  486. if (evt->key.flags & GF_KEY_MOD_CTRL) fprintf(stderr, "Rendering rate: %f FPS\n", gf_term_get_framerate(term, 0));
  487. break;
  488. case GF_KEY_T:
  489. if (evt->key.flags & GF_KEY_MOD_CTRL) fprintf(stderr, "Scene Time: %f \n", gf_term_get_time_in_ms(term)/1000.0);
  490. break;
  491. case GF_KEY_D:
  492. 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 );
  493. break;
  494. case GF_KEY_4:
  495. if (evt->key.flags & GF_KEY_MOD_CTRL)
  496. gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_4_3);
  497. break;
  498. case GF_KEY_5:
  499. if (evt->key.flags & GF_KEY_MOD_CTRL)
  500. gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_16_9);
  501. break;
  502. case GF_KEY_6:
  503. if (evt->key.flags & GF_KEY_MOD_CTRL)
  504. gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_FILL_SCREEN);
  505. break;
  506. case GF_KEY_7:
  507. if (evt->key.flags & GF_KEY_MOD_CTRL)
  508. gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_KEEP);
  509. break;
  510. case GF_KEY_P:
  511. if (evt->key.flags & GF_KEY_MOD_CTRL && is_connected) {
  512. Bool is_pause = gf_term_get_option(term, GF_OPT_PLAY_STATE);
  513. fprintf(stderr, "[Status: %s]\n", is_pause ? "Playing" : "Paused");
  514. 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);
  515. }
  516. break;
  517. case GF_KEY_S:
  518. if ((evt->key.flags & GF_KEY_MOD_CTRL) && is_connected) {
  519. gf_term_set_option(term, GF_OPT_PLAY_STATE, GF_STATE_STEP_PAUSE);
  520. fprintf(stderr, "Step time: ");
  521. PrintTime(gf_term_get_time_in_ms(term));
  522. fprintf(stderr, "\n");
  523. }
  524. break;
  525. case GF_KEY_B:
  526. if ((evt->key.flags & GF_KEY_MOD_CTRL) && is_connected)
  527. ViewODs(term, 1);
  528. break;
  529. case GF_KEY_M:
  530. if ((evt->key.flags & GF_KEY_MOD_CTRL) && is_connected)
  531. ViewODs(term, 0);
  532. break;
  533. case GF_KEY_H:
  534. if ((evt->key.flags & GF_KEY_MOD_CTRL) && is_connected)
  535. gf_term_switch_quality(term, 1);
  536. break;
  537. case GF_KEY_L:
  538. if ((evt->key.flags & GF_KEY_MOD_CTRL) && is_connected)
  539. gf_term_switch_quality(term, 0);
  540. break;
  541. }
  542. break;
  543. case GF_EVENT_CONNECT:
  544. if (evt->connect.is_connected) {
  545. is_connected = 1;
  546. fprintf(stderr, "Service Connected\n");
  547. } else if (is_connected) {
  548. fprintf(stderr, "Service %s\n", is_connected ? "Disconnected" : "Connection Failed");
  549. is_connected = 0;
  550. Duration = 0;
  551. }
  552. if (init_w && init_h) {
  553. gf_term_set_size(term, init_w, init_h);
  554. }
  555. ResetCaption();
  556. break;
  557. case GF_EVENT_EOS:
  558. restart = 1;
  559. break;
  560. case GF_EVENT_SIZE:
  561. if (user.init_flags & GF_TERM_WINDOWLESS) {
  562. GF_Event move;
  563. move.type = GF_EVENT_MOVE;
  564. move.move.align_x = align_mode & 0xFF;
  565. move.move.align_y = (align_mode>>8) & 0xFF;
  566. move.move.relative = 2;
  567. gf_term_user_event(term, &move);
  568. }
  569. break;
  570. case GF_EVENT_SCENE_SIZE:
  571. if (forced_width && forced_height) {
  572. GF_Event size;
  573. size.type = GF_EVENT_SIZE;
  574. size.size.width = forced_width;
  575. size.size.height = forced_height;
  576. gf_term_user_event(term, &size);
  577. }
  578. break;
  579. case GF_EVENT_METADATA:
  580. ResetCaption();
  581. break;
  582. case GF_EVENT_QUIT:
  583. Run = 0;
  584. break;
  585. case GF_EVENT_DISCONNECT:
  586. gf_term_disconnect(term);
  587. break;
  588. case GF_EVENT_MIGRATE:
  589. {
  590. }
  591. break;
  592. case GF_EVENT_NAVIGATE_INFO:
  593. if (evt->navigate.to_url) fprintf(stderr, "Go to URL: \"%s\"\r", evt->navigate.to_url);
  594. break;
  595. case GF_EVENT_NAVIGATE:
  596. if (gf_term_is_supported_url(term, evt->navigate.to_url, 1, no_mime_check)) {
  597. strcpy(the_url, evt->navigate.to_url);
  598. fprintf(stderr, "Navigating to URL %s\n", the_url);
  599. gf_term_navigate_to(term, evt->navigate.to_url);
  600. return 1;
  601. } else {
  602. fprintf(stderr, "Navigation destination not supported\nGo to URL: %s\n", evt->navigate.to_url);
  603. }
  604. break;
  605. case GF_EVENT_SET_CAPTION:
  606. gf_term_user_event(term, evt);
  607. break;
  608. case GF_EVENT_AUTHORIZATION:
  609. if (!strlen(evt->auth.user)) {
  610. fprintf(stderr, "Authorization required for site %s\n", evt->auth.site_url);
  611. fprintf(stderr, "login: ");
  612. scanf("%s", evt->auth.user);
  613. } else {
  614. fprintf(stderr, "Authorization required for %s@%s\n", evt->auth.user, evt->auth.site_url);
  615. }
  616. fprintf(stderr, "password: ");
  617. gf_prompt_set_echo_off(1);
  618. scanf("%s", evt->auth.password);
  619. gf_prompt_set_echo_off(0);
  620. return 1;
  621. case GF_EVENT_SYS_COLORS:
  622. #ifdef WIN32
  623. evt->sys_cols.sys_colors[0] = get_sys_col(COLOR_ACTIVEBORDER);
  624. evt->sys_cols.sys_colors[1] = get_sys_col(COLOR_ACTIVECAPTION);
  625. evt->sys_cols.sys_colors[2] = get_sys_col(COLOR_APPWORKSPACE);
  626. evt->sys_cols.sys_colors[3] = get_sys_col(COLOR_BACKGROUND);
  627. evt->sys_cols.sys_colors[4] = get_sys_col(COLOR_BTNFACE);
  628. evt->sys_cols.sys_colors[5] = get_sys_col(COLOR_BTNHIGHLIGHT);
  629. evt->sys_cols.sys_colors[6] = get_sys_col(COLOR_BTNSHADOW);
  630. evt->sys_cols.sys_colors[7] = get_sys_col(COLOR_BTNTEXT);
  631. evt->sys_cols.sys_colors[8] = get_sys_col(COLOR_CAPTIONTEXT);
  632. evt->sys_cols.sys_colors[9] = get_sys_col(COLOR_GRAYTEXT);
  633. evt->sys_cols.sys_colors[10] = get_sys_col(COLOR_HIGHLIGHT);
  634. evt->sys_cols.sys_colors[11] = get_sys_col(COLOR_HIGHLIGHTTEXT);
  635. evt->sys_cols.sys_colors[12] = get_sys_col(COLOR_INACTIVEBORDER);
  636. evt->sys_cols.sys_colors[13] = get_sys_col(COLOR_INACTIVECAPTION);
  637. evt->sys_cols.sys_colors[14] = get_sys_col(COLOR_INACTIVECAPTIONTEXT);
  638. evt->sys_cols.sys_colors[15] = get_sys_col(COLOR_INFOBK);
  639. evt->sys_cols.sys_colors[16] = get_sys_col(COLOR_INFOTEXT);
  640. evt->sys_cols.sys_colors[17] = get_sys_col(COLOR_MENU);
  641. evt->sys_cols.sys_colors[18] = get_sys_col(COLOR_MENUTEXT);
  642. evt->sys_cols.sys_colors[19] = get_sys_col(COLOR_SCROLLBAR);
  643. evt->sys_cols.sys_colors[20] = get_sys_col(COLOR_3DDKSHADOW);
  644. evt->sys_cols.sys_colors[21] = get_sys_col(COLOR_3DFACE);
  645. evt->sys_cols.sys_colors[22] = get_sys_col(COLOR_3DHIGHLIGHT);
  646. evt->sys_cols.sys_colors[23] = get_sys_col(COLOR_3DLIGHT);
  647. evt->sys_cols.sys_colors[24] = get_sys_col(COLOR_3DSHADOW);
  648. evt->sys_cols.sys_colors[25] = get_sys_col(COLOR_WINDOW);
  649. evt->sys_cols.sys_colors[26] = get_sys_col(COLOR_WINDOWFRAME);
  650. evt->sys_cols.sys_colors[27] = get_sys_col(COLOR_WINDOWTEXT);
  651. return 1;
  652. #else
  653. memset(evt->sys_cols.sys_colors, 0, sizeof(u32)*28);
  654. return 1;
  655. #endif
  656. break;
  657. }
  658. return 0;
  659. }
  660. void list_modules(GF_ModuleManager *modules)
  661. {
  662. u32 i;
  663. fprintf(stderr, "\rAvailable modules:\n");
  664. for (i=0; i<gf_modules_get_count(modules); i++) {
  665. char *str = (char *) gf_modules_get_file_name(modules, i);
  666. if (str) fprintf(stderr, "\t%s\n", str);
  667. }
  668. fprintf(stderr, "\n");
  669. }
  670. void set_navigation()
  671. {
  672. GF_Err e;
  673. char navstr[20], nav;
  674. u32 type = gf_term_get_option(term, GF_OPT_NAVIGATION_TYPE);
  675. e = GF_OK;
  676. if (!type) {
  677. fprintf(stdout, "Content/compositor doesn't allow user-selectable navigation\n");
  678. } else if (type==1) {
  679. fprintf(stdout, "Select Navigation (\'N\'one, \'E\'xamine, \'S\'lide): ");
  680. scanf("%s", navstr);
  681. nav = navstr[0];
  682. if (nav=='N') e = gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_NONE);
  683. else if (nav=='E') e = gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_EXAMINE);
  684. else if (nav=='S') e = gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_SLIDE);
  685. else fprintf(stdout, "Unknown selector \'%c\' - only \'N\',\'E\',\'S\' allowed\n", nav);
  686. } else if (type==2) {
  687. fprintf(stdout, "Select Navigation (\'N\'one, \'W\'alk, \'F\'ly, \'E\'xamine, \'P\'an, \'S\'lide, \'G\'ame, \'V\'R, \'O\'rbit): ");
  688. scanf("%s", navstr);
  689. nav = navstr[0];
  690. if (nav=='N') e = gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_NONE);
  691. else if (nav=='W') e = gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_WALK);
  692. else if (nav=='F') e = gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_FLY);
  693. else if (nav=='E') e = gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_EXAMINE);
  694. else if (nav=='P') e = gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_PAN);
  695. else if (nav=='S') e = gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_SLIDE);
  696. else if (nav=='G') e = gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_GAME);
  697. else if (nav=='O') e = gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_ORBIT);
  698. else if (nav=='V') e = gf_term_set_option(term, GF_OPT_NAVIGATION, GF_NAVIGATE_VR);
  699. else fprintf(stdout, "Unknown selector %c - only \'N\',\'W\',\'F\',\'E\',\'P\',\'S\',\'G\', \'V\', \'O\' allowed\n", nav);
  700. }
  701. if (e) fprintf(stdout, "Error setting mode: %s\n", gf_error_to_string(e));
  702. }
  703. static Bool get_time_list(char *arg, u32 *times, u32 *nb_times)
  704. {
  705. char *str;
  706. Float var;
  707. Double sec;
  708. u32 h, m, s, ms, f, fps;
  709. if (!arg || (arg[0]=='-') || !isdigit(arg[0])) return 0;
  710. /*SMPTE time code*/
  711. if (strchr(arg, ':') && strchr(arg, ';') && strchr(arg, '/')) {
  712. if (sscanf(arg, "%02d:%02d:%02d;%02d/%02d", &h, &m, &s, &f, &fps)==5) {
  713. sec = 0;
  714. if (fps) sec = ((Double)f) / fps;
  715. sec += 3600*h + 60*m + s;
  716. times[*nb_times] = (u32) (1000*sec);
  717. (*nb_times) ++;
  718. return 1;
  719. }
  720. }
  721. while (arg) {
  722. str = strchr(arg, '-');
  723. if (str) str[0] = 0;
  724. /*HH:MM:SS:MS time code*/
  725. if (strchr(arg, ':') && (sscanf(arg, "%02d:%02d:%02d:%02d", &h, &m, &s, &ms)==4)) {
  726. sec = ms;
  727. sec /= 1000;
  728. sec += 3600*h + 60*m + s;
  729. times[*nb_times] = (u32) (1000*sec);
  730. (*nb_times) ++;
  731. } else if (sscanf(arg, "%f", &var)==1) {
  732. sec = atof(arg);
  733. times[*nb_times] = (u32) (1000*sec);
  734. (*nb_times) ++;
  735. }
  736. if (!str) break;
  737. str[0] = '-';
  738. arg = str+1;
  739. }
  740. return 1;
  741. }
  742. static void on_gpac_log(void *cbk, u32 ll, u32 lm, const char *fmt, va_list list)
  743. {
  744. FILE *logs = cbk;
  745. if (rti_logs && (lm & GF_LOG_RTI)) {
  746. char szMsg[2048];
  747. vsprintf(szMsg, fmt, list);
  748. UpdateRTInfo(szMsg + 6 /*"[RTI] "*/);
  749. } else {
  750. if (log_time_start) fprintf(logs, "[At %d]", gf_sys_clock() - log_time_start);
  751. vfprintf(logs, fmt, list);
  752. fflush(logs);
  753. }
  754. }
  755. static void init_rti_logs(char *rti_file, char *url, Bool use_rtix)
  756. {
  757. if (rti_logs) fclose(rti_logs);
  758. rti_logs = gf_f64_open(rti_file, "wt");
  759. if (rti_logs) {
  760. fprintf(rti_logs, "!! GPAC RunTime Info ");
  761. if (url) fprintf(rti_logs, "for file %s", url);
  762. fprintf(rti_logs, " !!\n");
  763. fprintf(rti_logs, "SysTime(ms)\tSceneTime(ms)\tCPU\tFPS\tMemory(kB)\tObservation\n");
  764. /*turn on RTI loging*/
  765. if (use_rtix) {
  766. gf_log_set_callback(NULL, on_gpac_log);
  767. gf_log_set_tool_level(GF_LOG_ALL, GF_LOG_ERROR);
  768. gf_log_set_tool_level(GF_LOG_RTI, GF_LOG_DEBUG);
  769. GF_LOG(GF_LOG_DEBUG, GF_LOG_RTI, ("[RTI] System state when enabling log\n"));
  770. } else if (log_time_start) {
  771. log_time_start = gf_sys_clock();
  772. }
  773. }
  774. }
  775. #ifdef GPAC_IPHONE
  776. int SDL_main (int argc, char *argv[])
  777. #else
  778. int main (int argc, char *argv[])
  779. #endif
  780. {
  781. char c;
  782. const char *str;
  783. u32 i, times[100], nb_times, dump_mode;
  784. u32 simulation_time = 0;
  785. Bool auto_exit = 0;
  786. Bool start_fs = 0;
  787. Bool use_rtix = 0;
  788. Bool rgbds_dump = 0;
  789. Bool rgbd_dump = 0;
  790. Bool depth_dump = 0;
  791. Bool pause_at_first = 0;
  792. Bool enable_mem_tracker = 0;
  793. Double fps = 25.0;
  794. Bool ret, fill_ar, visible;
  795. char *url_arg, *the_cfg, *rti_file;
  796. GF_SystemRTInfo rti;
  797. FILE *playlist = NULL;
  798. FILE *logfile = NULL;
  799. Float scale = 1;
  800. int *libgpac_so = NULL;
  801. libgpac_so = dlopen("/Applications/osmo4ios.app/libgpac_dynamic.dylib", RTLD_LAZY);
  802. fprintf(stderr, "dlopen libgpac_so: %p\n", libgpac_so);
  803. fprintf(stderr, "dlsym: %p gf_log_lt\n", gf_log_lt = dlsym(libgpac_so, "gf_log_lt"));
  804. fprintf(stderr, "dlsym: %p AVI_close\n", AVI_close = dlsym(libgpac_so, "AVI_close"));
  805. fprintf(stderr, "dlsym: %p gf_sleep\n", gf_sleep = dlsym(libgpac_so, "gf_sleep"));
  806. fprintf(stderr, "dlsym: %p gf_term_del\n", gf_term_del = dlsym(libgpac_so, "gf_term_del"));
  807. fprintf(stderr, "dlsym: %p gf_sc_release_screen_buffer\n", gf_sc_release_screen_buffer = dlsym(libgpac_so, "gf_sc_release_screen_buffer"));
  808. fprintf(stderr, "dlsym: %p gf_prompt_get_char\n", gf_prompt_get_char = dlsym(libgpac_so, "gf_prompt_get_char"));
  809. fprintf(stderr, "dlsym: %p gf_set_progress\n", gf_set_progress = dlsym(libgpac_so, "gf_set_progress"));
  810. fprintf(stderr, "dlsym: %p gf_term_new\n", gf_term_new = dlsym(libgpac_so, "gf_term_new"));
  811. fprintf(stderr, "dlsym: %p gf_term_process_step\n", gf_term_process_step = dlsym(libgpac_so, "gf_term_process_step"));
  812. fprintf(stderr, "dlsym: %p gf_sc_get_screen_buffer\n", gf_sc_get_screen_buffer = dlsym(libgpac_so, "gf_sc_get_screen_buffer"));
  813. 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"));
  814. fprintf(stderr, "dlsym: %p gf_term_step_clocks\n", gf_term_step_clocks = dlsym(libgpac_so, "gf_term_step_clocks"));
  815. fprintf(stderr, "dlsym: %p gf_prompt_set_echo_off\n", gf_prompt_set_echo_off = dlsym(libgpac_so, "gf_prompt_set_echo_off"));
  816. fprintf(stderr, "dlsym: %p gf_log_tool_level_on\n", gf_log_tool_level_on = dlsym(libgpac_so, "gf_log_tool_level_on"));
  817. fprintf(stderr, "dlsym: %p gf_cfg_set_key\n", gf_cfg_set_key = dlsym(libgpac_so, "gf_cfg_set_key"));
  818. fprintf(stderr, "dlsym: %p gf_cfg_get_section_count\n", gf_cfg_get_section_count = dlsym(libgpac_so, "gf_cfg_get_section_count"));
  819. fprintf(stderr, "dlsym: %p gf_term_get_service_info\n", gf_term_get_service_info = dlsym(libgpac_so, "gf_term_get_service_info"));
  820. fprintf(stderr, "dlsym: %p gf_term_set_size\n", gf_term_set_size = dlsym(libgpac_so, "gf_term_set_size"));
  821. fprintf(stderr, "dlsym: %p gf_sys_get_rti\n", gf_sys_get_rti = dlsym(libgpac_so, "gf_sys_get_rti"));
  822. fprintf(stderr, "dlsym: %p gf_term_play_from_time\n", gf_term_play_from_time = dlsym(libgpac_so, "gf_term_play_from_time"));
  823. fprintf(stderr, "dlsym: %p gf_malloc\n", gf_malloc = dlsym(libgpac_so, "gf_malloc"));
  824. fprintf(stderr, "dlsym: %p gf_log_set_tool_level\n", gf_log_set_tool_level = dlsym(libgpac_so, "gf_log_set_tool_level"));
  825. fprintf(stderr, "dlsym: %p gf_log_set_tools_levels\n", gf_log_set_tools_levels = dlsym(libgpac_so, "gf_log_set_tools_levels"));
  826. fprintf(stderr, "dlsym: %p gf_log_modify_tools_levels\n", gf_log_modify_tools_levels = dlsym(libgpac_so, "gf_log_modify_tools_levels"));
  827. 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"));
  828. fprintf(stderr, "dlsym: %p gf_term_get_option\n", gf_term_get_option = dlsym(libgpac_so, "gf_term_get_option"));
  829. fprintf(stderr, "dlsym: %p gf_term_user_event\n", gf_term_user_event = dlsym(libgpac_so, "gf_term_user_event"));
  830. fprintf(stderr, "dlsym: %p gf_modules_get_file_name\n", gf_modules_get_file_name = dlsym(libgpac_so, "gf_modules_get_file_name"));
  831. fprintf(stderr, "dlsym: %p gf_mx_new\n", gf_mx_new = dlsym(libgpac_so, "gf_mx_new"));
  832. fprintf(stderr, "dlsym: %p gf_list_count\n", gf_list_count = dlsym(libgpac_so, "gf_list_count"));
  833. fprintf(stderr, "dlsym: %p gf_free\n", gf_free = dlsym(libgpac_so, "gf_free"));
  834. fprintf(stderr, "dlsym: %p gf_term_get_world_info\n", gf_term_get_world_info = dlsym(libgpac_so, "gf_term_get_world_info"));
  835. fprintf(stderr, "dlsym: %p gf_cfg_get_section_name\n", gf_cfg_get_section_name = dlsym(libgpac_so, "gf_cfg_get_section_name"));
  836. fprintf(stderr, "dlsym: %p gf_term_navigate_to\n", gf_term_navigate_to = dlsym(libgpac_so, "gf_term_navigate_to"));
  837. fprintf(stderr, "dlsym: %p gf_modules_del\n", gf_modules_del = dlsym(libgpac_so, "gf_modules_del"));
  838. fprintf(stderr, "dlsym: %p gf_modules_new\n", gf_modules_new = dlsym(libgpac_so, "gf_modules_new"));
  839. fprintf(stderr, "dlsym: %p gf_sys_init\n", gf_sys_init = dlsym(libgpac_so, "gf_sys_init"));
  840. fprintf(stderr, "dlsym: %p gf_log\n", gf_log = dlsym(libgpac_so, "gf_log"));
  841. fprintf(stderr, "dlsym: %p gf_term_get_object_info\n", gf_term_get_object_info = dlsym(libgpac_so, "gf_term_get_object_info"));
  842. fprintf(stderr, "dlsym: %p gf_mx_p\n", gf_mx_p = dlsym(libgpac_so, "gf_mx_p"));
  843. fprintf(stderr, "dlsym: %p gf_mx_v\n", gf_mx_v = dlsym(libgpac_so, "gf_mx_v"));
  844. fprintf(stderr, "dlsym: %p gf_mx_del\n", gf_mx_del = dlsym(libgpac_so, "gf_mx_del"));
  845. fprintf(stderr, "dlsym: %p gf_term_process_flush\n", gf_term_process_flush = dlsym(libgpac_so, "gf_term_process_flush"));
  846. fprintf(stderr, "dlsym: %p gf_cfg_get_key_name\n", gf_cfg_get_key_name = dlsym(libgpac_so, "gf_cfg_get_key_name"));
  847. fprintf(stderr, "dlsym: %p AVI_write_frame\n", AVI_write_frame = dlsym(libgpac_so, "AVI_write_frame"));
  848. fprintf(stderr, "dlsym: %p gf_cfg_del\n", gf_cfg_del = dlsym(libgpac_so, "gf_cfg_del"));
  849. 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"));
  850. fprintf(stderr, "dlsym: %p gf_term_process_shortcut\n", gf_term_process_shortcut = dlsym(libgpac_so, "gf_term_process_shortcut"));
  851. fprintf(stderr, "dlsym: %p gf_cfg_init\n", gf_cfg_init = dlsym(libgpac_so, "gf_cfg_init"));
  852. fprintf(stderr, "dlsym: %p gf_term_get_download_info\n", gf_term_get_download_info = dlsym(libgpac_so, "gf_term_get_download_info"));
  853. fprintf(stderr, "dlsym: %p gf_sys_clock\n", gf_sys_clock = dlsym(libgpac_so, "gf_sys_clock"));
  854. fprintf(stderr, "dlsym: %p gf_term_get_object\n", gf_term_get_object = dlsym(libgpac_so, "gf_term_get_object"));
  855. fprintf(stderr, "dlsym: %p gf_term_set_option\n", gf_term_set_option = dlsym(libgpac_so, "gf_term_set_option"));
  856. fprintf(stderr, "dlsym: %p gf_sys_close\n", gf_sys_close = dlsym(libgpac_so, "gf_sys_close"));
  857. fprintf(stderr, "dlsym: %p gf_term_connect_from_time\n", gf_term_connect_from_time = dlsym(libgpac_so, "gf_term_connect_from_time"));
  858. fprintf(stderr, "dlsym: %p AVI_open_output_file\n", AVI_open_output_file = dlsym(libgpac_so, "AVI_open_output_file"));
  859. fprintf(stderr, "dlsym: %p gf_cfg_get_key\n", gf_cfg_get_key = dlsym(libgpac_so, "gf_cfg_get_key"));
  860. fprintf(stderr, "dlsym: %p AVI_set_video\n", AVI_set_video = dlsym(libgpac_so, "AVI_set_video"));
  861. fprintf(stderr, "dlsym: %p gf_term_set_speed\n", gf_term_set_speed = dlsym(libgpac_so, "gf_term_set_speed"));
  862. fprintf(stderr, "dlsym: %p gf_cfg_get_key_count\n", gf_cfg_get_key_count = dlsym(libgpac_so, "gf_cfg_get_key_count"));
  863. fprintf(stderr, "dlsym: %p gf_term_object_subscene_type\n", gf_term_object_subscene_type = dlsym(libgpac_so, "gf_term_object_subscene_type"));
  864. fprintf(stderr, "dlsym: %p gf_term_get_framerate\n", gf_term_get_framerate = dlsym(libgpac_so, "gf_term_get_framerate"));
  865. fprintf(stderr, "dlsym: %p gf_error_to_string\n", gf_error_to_string = dlsym(libgpac_so, "gf_error_to_string"));
  866. fprintf(stderr, "dlsym: %p gf_stretch_bits\n", gf_stretch_bits = dlsym(libgpac_so, "gf_stretch_bits"));
  867. fprintf(stderr, "dlsym: %p gf_list_del\n", gf_list_del = dlsym(libgpac_so, "gf_list_del"));
  868. fprintf(stderr, "dlsym: %p gf_list_get\n", gf_list_get = dlsym(libgpac_so, "gf_list_get"));
  869. fprintf(stderr, "dlsym: %p gf_term_disconnect\n", gf_term_disconnect = dlsym(libgpac_so, "gf_term_disconnect"));
  870. fprintf(stderr, "dlsym: %p gf_term_is_supported_url\n", gf_term_is_supported_url = dlsym(libgpac_so, "gf_term_is_supported_url"));
  871. fprintf(stderr, "dlsym: %p gf_list_new\n", gf_list_new = dlsym(libgpac_so, "gf_list_new"));
  872. fprintf(stderr, "dlsym: %p gf_modules_get_option\n", gf_modules_get_option = dlsym(libgpac_so, "gf_modules_get_option"));
  873. fprintf(stderr, "dlsym: %p gf_term_dump_scene\n", gf_term_dump_scene = dlsym(libgpac_so, "gf_term_dump_scene"));
  874. fprintf(stderr, "dlsym: %p gf_prompt_has_input\n", gf_prompt_has_input = dlsym(libgpac_so, "gf_prompt_has_input"));
  875. fprintf(stderr, "dlsym: %p gf_term_scene_update\n", gf_term_scene_update = dlsym(libgpac_so, "gf_term_scene_update"));
  876. fprintf(stderr, "dlsym: %p gf_term_connect\n", gf_term_connect = dlsym(libgpac_so, "gf_term_connect"));
  877. fprintf(stderr, "dlsym: %p gf_term_get_object_count\n", gf_term_get_object_count = dlsym(libgpac_so, "gf_term_get_object_count"));
  878. fprintf(stderr, "dlsym: %p gf_modules_get_count\n", gf_modules_get_count = dlsym(libgpac_so, "gf_modules_get_count"));
  879. fprintf(stderr, "dlsym: %p gf_term_get_root_object\n", gf_term_get_root_object = dlsym(libgpac_so, "gf_term_get_root_object"));
  880. 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"));
  881. fprintf(stderr, "dlsym: %p gf_term_connect_with_path\n", gf_term_connect_with_path = dlsym(libgpac_so, "gf_term_connect_with_path"));
  882. fprintf(stderr, "dlsym: %p gf_log_set_callback\n", gf_log_set_callback = dlsym(libgpac_so, "gf_log_set_callback"));
  883. fprintf(stderr, "dlsym: %p gf_term_switch_quality\n", gf_term_switch_quality = dlsym(libgpac_so, "gf_term_switch_quality"));
  884. fprintf(stderr, "dlsym: %p gf_term_release_screen_buffer\n", gf_term_release_screen_buffer = dlsym(libgpac_so, "gf_term_release_screen_buffer"));
  885. fprintf(stderr, "dlsym: %p gf_term_get_screen_buffer\n", gf_term_get_screen_buffer = dlsym(libgpac_so, "gf_term_get_screen_buffer"));
  886. fprintf(stderr, "dlsym: %p gf_f64_open\n", gf_f64_open = dlsym(libgpac_so, "gf_f64_open"));
  887. fprintf(stderr, "dlsym: %p gf_fwrite\n", gf_fwrite = dlsym(libgpac_so, "gf_fwrite"));
  888. fprintf(stderr, "dlsym: %p gf_img_png_enc\n", gf_img_png_enc = dlsym(libgpac_so, "gf_img_png_enc"));
  889. fprintf(stderr, "dlsym: %p utf8_to_ucs4\n", utf8_to_ucs4 = dlsym(libgpac_so, "utf8_to_ucs4"));
  890. /*by default use current dir*/
  891. strcpy(the_url, ".");
  892. memset(&user, 0, sizeof(GF_User));
  893. dump_mode = 0;
  894. fill_ar = visible = 0;
  895. url_arg = the_cfg = rti_file = NULL;
  896. nb_times = 0;
  897. times[0] = 0;
  898. /*first locate config file if specified*/
  899. for (i=1; i<(u32) argc; i++) {
  900. char *arg = argv[i];
  901. if (!strcmp(arg, "-c") || !strcmp(arg, "-cfg")) {
  902. the_cfg = argv[i+1];
  903. i++;
  904. }
  905. else if (!strcmp(arg, "-mem-track")) enable_mem_tracker = 1;
  906. }
  907. gf_sys_init(enable_mem_tracker);
  908. gf_iphone_set_sdl_video_module(SDL_NewVideo);
  909. gf_iphone_set_sdl_audio_module(SDL_NewAudio);
  910. cfg_file = gf_cfg_init(the_cfg, NULL);
  911. if (!cfg_file) {
  912. fprintf(stdout, "Error: Configuration File \"GPAC.cfg\" not found\n");
  913. if (logfile) fclose(logfile);
  914. return 1;
  915. }
  916. gf_log_set_tools_levels( gf_cfg_get_key(cfg_file, "General", "Logs") );
  917. for (i=1; i<(u32) argc; i++) {
  918. char *arg = argv[i];
  919. // if (isalnum(arg[0]) || (arg[0]=='/') || (arg[0]=='.') || (arg[0]=='\\') ) {
  920. if (arg[0] != '-') {
  921. url_arg = arg;
  922. } else if (!strcmp(arg, "-c") || !strcmp(arg, "-cfg")) {
  923. the_cfg = argv[i+1];
  924. i++;
  925. } else if (!strcmp(arg, "-rti")) {
  926. rti_file = argv[i+1];
  927. i++;
  928. } else if (!strcmp(arg, "-rtix")) {
  929. rti_file = argv[i+1];
  930. i++;
  931. use_rtix = 1;
  932. } else if (!strcmp(arg, "-fill")) {
  933. fill_ar = 1;
  934. } else if (!strcmp(arg, "-show")) {
  935. visible = 1;
  936. } else if (!strcmp(arg, "-avi")) {
  937. if (rgbds_dump) dump_mode = 5;
  938. else if (depth_dump) dump_mode = 8;
  939. else if (rgbd_dump) dump_mode = 10;
  940. else dump_mode=1;
  941. if ((url_arg || (i+2<(u32)argc)) && get_time_list(argv[i+1], times, &nb_times)) i++;
  942. } else if (!strcmp(arg, "-rgbds")) { /*get dump in rgbds pixel format*/
  943. rgbds_dump = 1;
  944. dump_mode=6; /* rgbds texture directly*/
  945. if (dump_mode==1) dump_mode = 5; /* .avi rgbds dump*/
  946. } else if (!strcmp(arg, "-rgbd")) { /*get dump in rgbd pixel format*/
  947. rgbd_dump = 1;
  948. dump_mode=9; /* rgbd texture directly*/
  949. if (dump_mode==1) dump_mode = 10; /* .avi rgbds dump*/
  950. } else if (!strcmp(arg, "-depth")) {
  951. depth_dump = 1;
  952. if (dump_mode==2) dump_mode=7; /* grayscale .bmp depth dump*/
  953. else if (dump_mode==1) dump_mode=8; /* .avi depth dump*/
  954. else dump_mode=4; /*depth dump*/
  955. } else if (!strcmp(arg, "-bmp")) {
  956. if(depth_dump) dump_mode=7; /*grayscale depth .bmp dump*/
  957. else dump_mode=2;
  958. if ((url_arg || (i+2<(u32)argc)) && get_time_list(argv[i+1], times, &nb_times)) i++;
  959. } else if (!strcmp(arg, "-raw")) {
  960. dump_mode = 3;
  961. if ((url_arg || (i+2<(u32)argc)) && get_time_list(argv[i+1], times, &nb_times)) i++;
  962. } else if (!stricmp(arg, "-size")) {
  963. if (sscanf(argv[i+1], "%dx%d", &forced_width, &forced_height) != 2) {
  964. forced_width = forced_height = 0;
  965. }
  966. i++;
  967. } else if (!stricmp(arg, "-scale")) {
  968. sscanf(argv[i+1], "%f", &scale);
  969. i++;
  970. } else if (!stricmp(arg, "-fps")) {
  971. fps = atof(argv[i+1]);
  972. i++;
  973. } else if (!strcmp(arg, "-quiet")) {
  974. be_quiet = 1;
  975. } else if (!strcmp(arg, "-log-file") || !strcmp(arg, "-lf")) {
  976. logfile = gf_f64_open(argv[i+1], "wt");
  977. gf_log_set_callback(logfile, on_gpac_log);
  978. i++;
  979. } else if (!strcmp(arg, "-logs")) {
  980. gf_log_set_tools_levels( argv[i+1] );
  981. i++;
  982. } else if (!strcmp(arg, "-log-clock") || !strcmp(arg, "-lc")) {
  983. log_time_start = 1;
  984. } else if (!strcmp(arg, "-align")) {
  985. if (argv[i+1][0]=='m') align_mode = 1;
  986. else if (argv[i+1][0]=='b') align_mode = 2;
  987. align_mode <<= 8;
  988. if (argv[i+1][1]=='m') align_mode |= 1;
  989. else if (argv[i+1][1]=='r') align_mode |= 2;
  990. i++;
  991. }
  992. else if (!strcmp(arg, "-no-wnd")) user.init_flags |= GF_TERM_WINDOWLESS;
  993. #if defined(__DARWIN__) || defined(__APPLE__)
  994. else if (!strcmp(arg, "-thread")) not_threaded = 0;
  995. #else
  996. else if (!strcmp(arg, "-no-thread")) not_threaded = 1;
  997. #endif
  998. else if (!strcmp(arg, "-no-audio")) no_audio = 1;
  999. else if (!strcmp(arg, "-no-regulation")) no_regulation = 1;
  1000. else if (!strcmp(arg, "-fs")) start_fs = 1;
  1001. else if (!strcmp(arg, "-pause")) pause_at_first = 1;
  1002. else if (!strcmp(arg, "-exit")) auto_exit = 1;
  1003. else if (!strcmp(arg, "-mem-track")) enable_mem_tracker = 1;
  1004. else if (!strcmp(arg, "-opt")) {
  1005. char *sep, *sep2, szSec[1024], szKey[1024], szVal[1024];
  1006. sep = strchr(argv[i+1], ':');
  1007. if (sep) {
  1008. sep[0] = 0;
  1009. strcpy(szSec, argv[i+1]);
  1010. sep[0] = ':'; sep ++;
  1011. sep2 = strchr(sep, '=');
  1012. if (sep2) {
  1013. sep2[0] = 0;
  1014. strcpy(szKey, sep);
  1015. strcpy(szVal, sep2+1);
  1016. sep2[0] = '=';
  1017. if (!stricmp(szVal, "null")) szVal[0]=0;
  1018. gf_cfg_set_key(cfg_file, szSec, szKey, szVal[0] ? szVal : NULL);
  1019. }
  1020. }
  1021. i++;
  1022. }
  1023. else if (!strncmp(arg, "-run-for=", 9)) simulation_time = atoi(arg+9);
  1024. else {
  1025. PrintUsage();
  1026. return 1;
  1027. }
  1028. }
  1029. if (!logfile) {
  1030. const char *opt = gf_cfg_get_key(cfg_file, "General", "LogFile");
  1031. if (opt) {
  1032. logfile = gf_f64_open(opt, "wt");
  1033. if (logfile)
  1034. gf_log_set_callback(logfile, on_gpac_log);
  1035. }
  1036. }
  1037. if (dump_mode && !url_arg) {
  1038. fprintf(stdout, "Missing argument for dump\n");
  1039. PrintUsage();
  1040. if (logfile) fclose(logfile);
  1041. return 1;
  1042. }
  1043. if (dump_mode) rti_file = NULL;
  1044. gf_sys_get_rti(500, &rti, GF_RTI_SYSTEM_MEMORY_ONLY);
  1045. memory_at_gpac_startup = rti.physical_memory_avail;
  1046. if (rti_file) init_rti_logs(rti_file, url_arg, use_rtix);
  1047. /*setup dumping options*/
  1048. if (dump_mode) {
  1049. user.init_flags |= GF_TERM_NO_AUDIO | GF_TERM_NO_COMPOSITOR_THREAD | GF_TERM_NO_REGULATION /*| GF_TERM_INIT_HIDE*/;
  1050. if (visible || dump_mode==8) user.init_flags |= GF_TERM_INIT_HIDE;
  1051. } else {
  1052. init_w = forced_width;
  1053. init_h = forced_height;
  1054. }
  1055. fprintf(stderr, "Loading modules\n");
  1056. str = gf_cfg_get_key(cfg_file, "General", "ModulesDirectory");
  1057. user.modules = gf_modules_new((const unsigned char *) str, cfg_file);
  1058. if (user.modules) i = gf_modules_get_count(user.modules);
  1059. if (!i || !user.modules) {
  1060. fprintf(stdout, "Error: no modules found in %s - exiting\n", str);
  1061. if (user.modules) gf_modules_del(user.modules);
  1062. gf_cfg_del(cfg_file);
  1063. gf_sys_close();
  1064. if (logfile) fclose(logfile);
  1065. return 1;
  1066. }
  1067. fprintf(stderr, "Modules Loaded (%d found in %s)\n", i, str);
  1068. user.config = cfg_file;
  1069. user.EventProc = GPAC_EventProc;
  1070. /*dummy in this case (global vars) but MUST be non-NULL*/
  1071. user.opaque = user.modules;
  1072. if (not_threaded) user.init_flags |= GF_TERM_NO_COMPOSITOR_THREAD;
  1073. if (no_audio) user.init_flags |= GF_TERM_NO_AUDIO;
  1074. if (no_regulation) user.init_flags |= GF_TERM_NO_REGULATION;
  1075. fprintf(stderr, "Loading GPAC Terminal\n");
  1076. term = gf_term_new(&user);
  1077. if (!term) {
  1078. fprintf(stderr, "\nInit error - check you have at least one video out and one rasterizer...\nFound modules:\n");
  1079. list_modules(user.modules);
  1080. gf_modules_del(user.modules);
  1081. gf_cfg_del(cfg_file);
  1082. gf_sys_close();
  1083. if (logfile) fclose(logfile);
  1084. return 1;
  1085. }
  1086. fprintf(stderr, "Terminal Loaded\n");
  1087. if (dump_mode) {
  1088. // gf_term_set_option(term, GF_OPT_VISIBLE, 0);
  1089. if (fill_ar) gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_FILL_SCREEN);
  1090. } else {
  1091. /*check video output*/
  1092. str = gf_cfg_get_key(cfg_file, "Video", "DriverName");
  1093. if (!strcmp(str, "Raw Video Output")) fprintf(stdout, "WARNING: using raw output video (memory only) - no display used\n");
  1094. /*check audio output*/
  1095. str = gf_cfg_get_key(cfg_file, "Audio", "DriverName");
  1096. 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");
  1097. str = gf_cfg_get_key(cfg_file, "General", "NoMIMETypeFetch");
  1098. no_mime_check = (str && !stricmp(str, "yes")) ? 1 : 0;
  1099. }
  1100. str = gf_cfg_get_key(cfg_file, "HTTPProxy", "Enabled");
  1101. if (str && !strcmp(str, "yes")) {
  1102. str = gf_cfg_get_key(cfg_file, "HTTPProxy", "Name");
  1103. if (str) fprintf(stdout, "HTTP Proxy %s enabled\n", str);
  1104. }
  1105. if (rti_file) {
  1106. str = gf_cfg_get_key(cfg_file, "General", "RTIRefreshPeriod");
  1107. if (str) {
  1108. rti_update_time_ms = atoi(str);
  1109. } else {
  1110. gf_cfg_set_key(cfg_file, "General", "RTIRefreshPeriod", "200");
  1111. }
  1112. UpdateRTInfo("At GPAC load time\n");
  1113. }
  1114. Run = 1;
  1115. ret = 1;
  1116. if (dump_mode) {
  1117. if (!nb_times) {
  1118. times[0] = 0;
  1119. nb_times++;
  1120. }
  1121. ret = dump_file(url_arg, dump_mode, fps, forced_width, forced_height, scale, times, nb_times);
  1122. Run = 0;
  1123. } else
  1124. /*connect if requested*/
  1125. if (url_arg) {
  1126. char *ext;
  1127. strcpy(the_url, url_arg);
  1128. ext = strrchr(the_url, '.');
  1129. if (ext && (!stricmp(ext, ".m3u") || !stricmp(ext, ".pls"))) {
  1130. fprintf(stdout, "Opening Playlist %s\n", the_url);
  1131. playlist = gf_f64_open(the_url, "rt");
  1132. if (playlist) {
  1133. strcpy(pl_path, the_url);
  1134. fscanf(playlist, "%s", the_url);
  1135. fprintf(stdout, "Opening URL %s\n", the_url);
  1136. gf_term_connect_with_path(term, the_url, pl_path);
  1137. } else {
  1138. fprintf(stdout, "Hit 'h' for help\n\n");
  1139. }
  1140. } else {
  1141. fprintf(stdout, "Opening URL %s\n", the_url);
  1142. if (pause_at_first) fprintf(stdout, "[Status: Paused]\n");
  1143. gf_term_connect_from_time(term, the_url, 0, pause_at_first);
  1144. }
  1145. } else {
  1146. fprintf(stdout, "Hit 'h' for help\n\n");
  1147. str = gf_cfg_get_key(cfg_file, "General", "StartupFile");
  1148. if (str) {
  1149. strcpy(the_url, "MP4Client "GPAC_FULL_VERSION);
  1150. gf_term_connect(term, str);
  1151. startup_file = 1;
  1152. }
  1153. }
  1154. /*force fullscreen*/
  1155. if (start_fs)
  1156. gf_term_set_option(term, GF_OPT_FULLSCREEN, 1);
  1157. while (Run) {
  1158. /*we don't want getchar to block*/
  1159. if (1 || !gf_prompt_has_input()) {
  1160. if (restart) {
  1161. restart = 0;
  1162. gf_term_play_from_time(term, 0, 0);
  1163. }
  1164. if (request_next_playlist_item) {
  1165. c = '\n';
  1166. request_next_playlist_item = 0;
  1167. goto force_input;
  1168. }
  1169. if (!use_rtix || display_rti) UpdateRTInfo(NULL);
  1170. if (not_threaded) {
  1171. //printf("gf_term_process_step from run loop\n");
  1172. gf_term_process_step(term);
  1173. if (auto_exit && gf_term_get_option(term, GF_OPT_IS_OVER)) {
  1174. Run = 0;
  1175. }
  1176. } else {
  1177. gf_sleep(rti_update_time_ms);
  1178. }
  1179. /*sim time*/
  1180. if (simulation_time && (gf_term_get_time_in_ms(term)>simulation_time)) {
  1181. Run = 0;
  1182. }
  1183. continue;
  1184. }
  1185. c = gf_prompt_get_char();
  1186. force_input:
  1187. switch (c) {
  1188. case 'q':
  1189. Run = 0;
  1190. break;
  1191. case 'X':
  1192. exit(0);
  1193. break;
  1194. case 'Q':
  1195. break;
  1196. case 'o':
  1197. startup_file = 0;
  1198. gf_term_disconnect(term);
  1199. fprintf(stdout, "Enter the absolute URL\n");
  1200. scanf("%s", the_url);
  1201. if (rti_file) init_rti_logs(rti_file, the_url, use_rtix);
  1202. gf_term_connect(term, the_url);
  1203. break;
  1204. case 'O':
  1205. gf_term_disconnect(term);
  1206. fprintf(stdout, "Enter the absolute URL to the playlist\n");
  1207. scanf("%s", the_url);
  1208. playlist = gf_f64_open(the_url, "rt");
  1209. if (playlist) {
  1210. fscanf(playlist, "%s", the_url);
  1211. fprintf(stdout, "Opening URL %s\n", the_url);
  1212. gf_term_connect(term, the_url);
  1213. }
  1214. break;
  1215. case '\n':
  1216. case 'N':
  1217. if (playlist) {
  1218. gf_term_disconnect(term);
  1219. if (fscanf(playlist, "%s", the_url) == EOF) {
  1220. fprintf(stdout, "No more items - exiting\n");
  1221. Run = 0;
  1222. } else {
  1223. fprintf(stdout, "Opening URL %s\n", the_url);
  1224. gf_term_connect_with_path(term, the_url, pl_path);
  1225. }
  1226. }
  1227. break;
  1228. case 'P':
  1229. if (playlist) {
  1230. u32 count;
  1231. gf_term_disconnect(term);
  1232. scanf("%d", &count);
  1233. while (count) {
  1234. fscanf(playlist, "%s", the_url);
  1235. count--;
  1236. }
  1237. fprintf(stdout, "Opening URL %s\n", the_url);
  1238. gf_term_connect(term, the_url);
  1239. }
  1240. break;
  1241. case 'r':
  1242. if (is_connected) {
  1243. gf_term_disconnect(term);
  1244. gf_term_connect(term, startup_file ? gf_cfg_get_key(cfg_file, "General", "StartupFile") : the_url);
  1245. }
  1246. break;
  1247. case 'D':
  1248. if (is_connected) gf_term_disconnect(term);
  1249. break;
  1250. case 'p':
  1251. if (is_connected) {
  1252. Bool is_pause = gf_term_get_option(term, GF_OPT_PLAY_STATE);
  1253. fprintf(stdout, "[Status: %s]\n", is_pause ? "Playing" : "Paused");
  1254. gf_term_set_option(term, GF_OPT_PLAY_STATE, is_pause ? GF_STATE_PLAYING : GF_STATE_PAUSED);
  1255. }
  1256. break;
  1257. case 's':
  1258. if (is_connected) {
  1259. gf_term_set_option(term, GF_OPT_PLAY_STATE, GF_STATE_STEP_PAUSE);
  1260. fprintf(stdout, "Step time: ");
  1261. PrintTime(gf_term_get_time_in_ms(term));
  1262. fprintf(stdout, "\n");
  1263. }
  1264. break;
  1265. case 'z':
  1266. if (!CanSeek || (Duration<=2000)) {
  1267. fprintf(stdout, "scene not seekable\n");
  1268. } else {
  1269. Double res;
  1270. s32 seekTo;
  1271. fprintf(stdout, "Duration: ");
  1272. PrintTime(Duration);
  1273. res = gf_term_get_time_in_ms(term);
  1274. res *= 100; res /= (s64)Duration;
  1275. fprintf(stdout, " (current %.2f %%)\nEnter Seek percentage:\n", res);
  1276. if (scanf("%d", &seekTo) == 1) {
  1277. if (seekTo > 100) seekTo = 100;
  1278. res = (Double)(s64)Duration; res /= 100; res *= seekTo;
  1279. gf_term_play_from_time(term, (u64) (s64) res, 0);
  1280. }
  1281. }
  1282. break;
  1283. case 't':
  1284. {
  1285. if (is_connected) {
  1286. fprintf(stdout, "Current Time: ");
  1287. PrintTime(gf_term_get_time_in_ms(term));
  1288. fprintf(stdout, " - Duration: ");
  1289. PrintTime(Duration);
  1290. fprintf(stdout, "\n");
  1291. }
  1292. }
  1293. break;
  1294. case 'w':
  1295. if (is_connected) PrintWorldInfo(term);
  1296. break;
  1297. case 'v':
  1298. if (is_connected) PrintODList(term, NULL, 0, 0, "Root");
  1299. break;
  1300. case 'i':
  1301. if (is_connected) {
  1302. u32 ID;
  1303. fprintf(stdout, "Enter OD ID (0 for main OD): ");
  1304. fflush(stdout);
  1305. scanf("%d", &ID);
  1306. ViewOD(term, ID, (u32)-1);
  1307. }
  1308. break;
  1309. case 'j':
  1310. if (is_connected) {
  1311. u32 num;
  1312. fprintf(stdout, "Enter OD number (0 for main OD): ");
  1313. fflush(stdout);
  1314. scanf("%d", &num);
  1315. ViewOD(term, (u32)-1, num);
  1316. }
  1317. break;
  1318. case 'b':
  1319. if (is_connected) ViewODs(term, 1);
  1320. break;
  1321. case 'm':
  1322. if (is_connected) ViewODs(term, 0);
  1323. break;
  1324. case 'l':
  1325. list_modules(user.modules);
  1326. break;
  1327. case 'n':
  1328. if (is_connected) set_navigation();
  1329. break;
  1330. case 'x':
  1331. if (is_connected) gf_term_set_option(term, GF_OPT_NAVIGATION_TYPE, 0);
  1332. break;
  1333. case 'd':
  1334. if (is_connected) {
  1335. GF_ObjectManager *odm = NULL;
  1336. char radname[GF_MAX_PATH], *sExt;
  1337. GF_Err e;
  1338. u32 i, count, odid;
  1339. Bool xml_dump, std_out;
  1340. fprintf(stdout, "Enter Inline OD ID if any or 0");
  1341. fflush(stdout);
  1342. radname[0] = 0;
  1343. scanf("%d", &odid);
  1344. if (odid) {
  1345. GF_ObjectManager *root_odm = gf_term_get_root_object(term);
  1346. if (!root_odm) break;
  1347. count = gf_term_get_object_count(term, root_odm);
  1348. for (i=0; i<count; i++) {
  1349. GF_MediaInfo info;
  1350. odm = gf_term_get_object(term, root_odm, i);
  1351. if (gf_term_get_object_info(term, odm, &info) == GF_OK) {
  1352. if (info.od->objectDescriptorID==odid) break;
  1353. }
  1354. odm = NULL;
  1355. }
  1356. }
  1357. fprintf(stdout, "Enter file radical name (+\'.x\' for XML dumping) - \"std\" for stdout: ");
  1358. fflush(stdout);
  1359. scanf("%s", radname);
  1360. sExt = strrchr(radname, '.');
  1361. xml_dump = 0;
  1362. if (sExt) {
  1363. if (!stricmp(sExt, ".x")) xml_dump = 1;
  1364. sExt[0] = 0;
  1365. }
  1366. std_out = strnicmp(radname, "std", 3) ? 0 : 1;
  1367. e = gf_term_dump_scene(term, std_out ? NULL : radname, NULL, xml_dump, 0, odm);
  1368. fprintf(stdout, "Dump done (%s)\n", gf_error_to_string(e));
  1369. }
  1370. break;
  1371. case 'c':
  1372. PrintGPACConfig();
  1373. break;
  1374. case '3':
  1375. {
  1376. Bool use_3d = !gf_term_get_option(term, GF_OPT_USE_OPENGL);
  1377. if (gf_term_set_option(term, GF_OPT_USE_OPENGL, use_3d)==GF_OK) {
  1378. fprintf(stdout, "Using %s for 2D drawing\n", use_3d ? "OpenGL" : "2D rasterizer");
  1379. }
  1380. }
  1381. break;
  1382. case 'k':
  1383. {
  1384. Bool opt = gf_term_get_option(term, GF_OPT_STRESS_MODE);
  1385. opt = !opt;
  1386. fprintf(stdout, "Turning stress mode %s\n", opt ? "on" : "off");
  1387. gf_term_set_option(term, GF_OPT_STRESS_MODE, opt);
  1388. }
  1389. break;
  1390. case '4': gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_4_3); break;
  1391. case '5': gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_16_9); break;
  1392. case '6': gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_FILL_SCREEN); break;
  1393. case '7': gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_KEEP); break;
  1394. case 'C':
  1395. switch (gf_term_get_option(term, GF_OPT_MEDIA_CACHE)) {
  1396. case GF_MEDIA_CACHE_DISABLED: gf_term_set_option(term, GF_OPT_MEDIA_CACHE, GF_MEDIA_CACHE_ENABLED); break;
  1397. case GF_MEDIA_CACHE_ENABLED: gf_term_set_option(term, GF_OPT_MEDIA_CACHE, GF_MEDIA_CACHE_DISABLED); break;
  1398. case GF_MEDIA_CACHE_RUNNING: fprintf(stdout, "Streaming Cache is running - please stop it first\n"); continue;
  1399. }
  1400. switch (gf_term_get_option(term, GF_OPT_MEDIA_CACHE)) {
  1401. case GF_MEDIA_CACHE_ENABLED: fprintf(stdout, "Streaming Cache Enabled\n"); break;
  1402. case GF_MEDIA_CACHE_DISABLED: fprintf(stdout, "Streaming Cache Disabled\n"); break;
  1403. case GF_MEDIA_CACHE_RUNNING: fprintf(stdout, "Streaming Cache Running\n"); break;
  1404. }
  1405. break;
  1406. case 'S':
  1407. case 'A':
  1408. if (gf_term_get_option(term, GF_OPT_MEDIA_CACHE)==GF_MEDIA_CACHE_RUNNING) {
  1409. gf_term_set_option(term, GF_OPT_MEDIA_CACHE, (c=='S') ? GF_MEDIA_CACHE_DISABLED : GF_MEDIA_CACHE_DISCARD);
  1410. fprintf(stdout, "Streaming Cache stopped\n");
  1411. } else {
  1412. fprintf(stdout, "Streaming Cache not running\n");
  1413. }
  1414. break;
  1415. case 'R':
  1416. display_rti = !display_rti;
  1417. ResetCaption();
  1418. break;
  1419. case 'F':
  1420. if (display_rti) display_rti = 0;
  1421. else display_rti = 2;
  1422. ResetCaption();
  1423. break;
  1424. case 'u':
  1425. {
  1426. GF_Err e;
  1427. char szCom[8192];
  1428. fprintf(stdout, "Enter command to send:\n");
  1429. fflush(stdin);
  1430. szCom[0] = 0;
  1431. scanf("%[^\t\n]", szCom);
  1432. e = gf_term_scene_update(term, NULL, szCom);
  1433. if (e) fprintf(stdout, "Processing command failed: %s\n", gf_error_to_string(e));
  1434. }
  1435. break;
  1436. case 'L':
  1437. {
  1438. char szLog[1024];
  1439. fprintf(stdout, "Enter new log level:\n");
  1440. scanf("%s", szLog);
  1441. gf_log_modify_tools_levels( szLog );
  1442. }
  1443. break;
  1444. case 'g':
  1445. {
  1446. GF_SystemRTInfo rti;
  1447. gf_sys_get_rti(rti_update_time_ms, &rti, 0);
  1448. fprintf(stdout, "GPAC allocated memory "LLD"\n", rti.gpac_memory);
  1449. }
  1450. break;
  1451. case 'M':
  1452. {
  1453. u32 size;
  1454. fprintf(stdout, "Enter new video cache memory in kBytes (current %d):\n", gf_term_get_option(term, GF_OPT_VIDEO_CACHE_SIZE));
  1455. scanf("%d", &size);
  1456. gf_term_set_option(term, GF_OPT_VIDEO_CACHE_SIZE, size);
  1457. }
  1458. break;
  1459. case 'E':
  1460. gf_term_set_option(term, GF_OPT_RELOAD_CONFIG, 1);
  1461. break;
  1462. case 'B':
  1463. switch_bench();
  1464. break;
  1465. /*extract to PNG*/
  1466. case 'Z':
  1467. {
  1468. GF_VideoSurface fb;
  1469. GF_Err e;
  1470. e = gf_term_get_screen_buffer(term, &fb);
  1471. if (e) {
  1472. fprintf(stdout, "Error dumping screen buffer %s\n", gf_error_to_string(e) );
  1473. } else {
  1474. u32 dst_size = fb.width*fb.height*3;
  1475. char *dst=malloc(sizeof(char)*dst_size);
  1476. e = gf_img_png_enc(fb.video_buffer, fb.width, fb.height, fb.pitch_y, fb.pixel_format, dst, &dst_size);
  1477. if (e) {
  1478. fprintf(stdout, "Error encoding PNG %s\n", gf_error_to_string(e) );
  1479. } else {
  1480. FILE *png = gf_f64_open("dump.png", "wb");
  1481. if (!png) {
  1482. fprintf(stdout, "Error writing file dump.png\n");
  1483. } else {
  1484. gf_fwrite(dst, dst_size, 1, png);
  1485. fclose(png);
  1486. fprintf(stdout, "Writing file dump.png\n");
  1487. }
  1488. }
  1489. if (dst) free(dst);
  1490. gf_term_release_screen_buffer(term, &fb);
  1491. }
  1492. }
  1493. break;
  1494. case 'h':
  1495. PrintHelp();
  1496. break;
  1497. default:
  1498. break;
  1499. }
  1500. }
  1501. gf_term_disconnect(term);
  1502. if (rti_file) UpdateRTInfo("Disconnected\n");
  1503. fprintf(stdout, "Deleting terminal... ");
  1504. if (playlist) fclose(playlist);
  1505. gf_term_del(term);
  1506. fprintf(stdout, "OK\n");
  1507. fprintf(stdout, "GPAC cleanup ...\n");
  1508. gf_modules_del(user.modules);
  1509. gf_cfg_del(cfg_file);
  1510. #ifdef GPAC_MEMORY_TRACKING
  1511. if (enable_mem_tracker) {
  1512. gf_memory_print();
  1513. fprintf(stdout, "print any key\n");
  1514. while (!gf_prompt_has_input()) {
  1515. gf_sleep(100);
  1516. }
  1517. }
  1518. #endif
  1519. gf_sys_close();
  1520. if (rti_logs) fclose(rti_logs);
  1521. if (logfile) fclose(logfile);
  1522. fprintf(stdout, "Bye\n");
  1523. return 0;
  1524. }
  1525. void PrintWorldInfo(GF_Terminal *term)
  1526. {
  1527. u32 i;
  1528. const char *title;
  1529. GF_List *descs;
  1530. descs = gf_list_new();
  1531. title = gf_term_get_world_info(term, NULL, descs);
  1532. if (!title && !gf_list_count(descs)) {
  1533. fprintf(stdout, "No World Info available\n");
  1534. } else {
  1535. fprintf(stdout, "\t%s\n", title ? title : "No title available");
  1536. for (i=0; i<gf_list_count(descs); i++) {
  1537. char *str = gf_list_get(descs, i);
  1538. fprintf(stdout, "%s\n", str);
  1539. }
  1540. }
  1541. gf_list_del(descs);
  1542. }
  1543. void PrintODList(GF_Terminal *term, GF_ObjectManager *root_odm, u32 num, u32 indent, char *root_name)
  1544. {
  1545. GF_MediaInfo odi;
  1546. u32 i, count;
  1547. char szIndent[50];
  1548. GF_ObjectManager *odm;
  1549. if (!root_odm) {
  1550. fprintf(stdout, "Currently loaded objects:\n");
  1551. root_odm = gf_term_get_root_object(term);
  1552. }
  1553. if (!root_odm) return;
  1554. if (gf_term_get_object_info(term, root_odm, &odi) != GF_OK) return;
  1555. if (!odi.od) {
  1556. fprintf(stdout, "Service not attached\n");
  1557. return;
  1558. }
  1559. for (i=0;i<indent;i++) szIndent[i]=' ';
  1560. szIndent[indent]=0;
  1561. fprintf(stdout, "%s", szIndent);
  1562. fprintf(stdout, "#%d %s - ", num, root_name);
  1563. if (odi.media_url) {
  1564. fprintf(stdout, "%s\n", odi.media_url);
  1565. } else {
  1566. fprintf(stdout, "OD ID %d\n", odi.od->objectDescriptorID);
  1567. }
  1568. szIndent[indent]=' ';
  1569. szIndent[indent+1]=0;
  1570. indent++;
  1571. count = gf_term_get_object_count(term, root_odm);
  1572. for (i=0; i<count; i++) {
  1573. odm = gf_term_get_object(term, root_odm, i);
  1574. if (!odm) break;
  1575. num++;
  1576. if (gf_term_get_object_info(term, odm, &odi) == GF_OK) {
  1577. switch (gf_term_object_subscene_type(term, odm)) {
  1578. case 1:
  1579. PrintODList(term, odm, num, indent, "Root");
  1580. break;
  1581. case 2:
  1582. PrintODList(term, odm, num, indent, "Inline Scene");
  1583. break;
  1584. case 3:
  1585. PrintODList(term, odm, num, indent, "EXTERNPROTO Library");
  1586. break;
  1587. default:
  1588. fprintf(stdout, "%s", szIndent);
  1589. fprintf(stdout, "#%d - ", num);
  1590. if (odi.media_url) {
  1591. fprintf(stdout, "%s", odi.media_url);
  1592. } else {
  1593. fprintf(stdout, "ID %d", odi.od->objectDescriptorID);
  1594. }
  1595. fprintf(stdout, " - %s\n", (odi.od_type==GF_STREAM_VISUAL) ? "Video" : (odi.od_type==GF_STREAM_AUDIO) ? "Audio" : "Systems");
  1596. break;
  1597. }
  1598. }
  1599. }
  1600. }
  1601. void ViewOD(GF_Terminal *term, u32 OD_ID, u32 number)
  1602. {
  1603. GF_MediaInfo odi;
  1604. u32 i, j, count, d_enum,id;
  1605. GF_Err e;
  1606. char code[5];
  1607. NetStatCommand com;
  1608. GF_ObjectManager *odm, *root_odm = gf_term_get_root_object(term);
  1609. if (!root_odm) return;
  1610. odm = NULL;
  1611. if ((!OD_ID && (number == (u32)(-1))) ||
  1612. ((OD_ID == (u32)(-1)) && !number)) {
  1613. odm = root_odm;
  1614. if ((gf_term_get_object_info(term, odm, &odi) != GF_OK)) odm=NULL;
  1615. } else {
  1616. count = gf_term_get_object_count(term, root_odm);
  1617. for (i=0; i<count; i++) {
  1618. odm = gf_term_get_object(term, root_odm, i);
  1619. if (!odm) break;
  1620. if (gf_term_get_object_info(term, odm, &odi) == GF_OK) {
  1621. if ((number == (u32)(-1)) && (odi.od->objectDescriptorID == OD_ID)) break;
  1622. else if (i == (u32)(number-1)) break;
  1623. }
  1624. odm = NULL;
  1625. }
  1626. }
  1627. if (!odm) {
  1628. if (number == (u32)-1) fprintf(stdout, "cannot find OD with ID %d\n", OD_ID);
  1629. else fprintf(stdout, "cannot find OD with number %d\n", number);
  1630. return;
  1631. }
  1632. if (!odi.od) {
  1633. if (number == (u32)-1) fprintf(stdout, "Object %d not attached yet\n", OD_ID);
  1634. else fprintf(stdout, "Object #%d not attached yet\n", number);
  1635. return;
  1636. }
  1637. if (!odi.od) {
  1638. fprintf(stdout, "Service not attached\n");
  1639. return;
  1640. }
  1641. if (odi.od->tag==GF_ODF_IOD_TAG) {
  1642. fprintf(stdout, "InitialObjectDescriptor %d\n", odi.od->objectDescriptorID);
  1643. fprintf(stdout, "Profiles and Levels: Scene %x - Graphics %x - Visual %x - Audio %x - OD %x\n",
  1644. odi.scene_pl, odi.graphics_pl, odi.visual_pl, odi.audio_pl, odi.OD_pl);
  1645. fprintf(stdout, "Inline Profile Flag %d\n", odi.inline_pl);
  1646. } else {
  1647. fprintf(stdout, "ObjectDescriptor %d\n", odi.od->objectDescriptorID);
  1648. }
  1649. fprintf(stdout, "Object Duration: ");
  1650. if (odi.duration) {
  1651. PrintTime((u32) (odi.duration*1000));
  1652. } else {
  1653. fprintf(stdout, "unknown");
  1654. }
  1655. fprintf(stdout, "\n");
  1656. if (odi.owns_service) {
  1657. fprintf(stdout, "Service Handler: %s\n", odi.service_handler);
  1658. fprintf(stdout, "Service URL: %s\n", odi.service_url);
  1659. }
  1660. if (odi.codec_name) {
  1661. Float avg_dec_time;
  1662. switch (odi.od_type) {
  1663. case GF_STREAM_VISUAL:
  1664. fprintf(stdout, "Video Object: Width %d - Height %d\r\n", odi.width, odi.height);
  1665. fprintf(stdout, "Media Codec: %s\n", odi.codec_name);
  1666. if (odi.par) fprintf(stdout, "Pixel Aspect Ratio: %d:%d\n", (odi.par>>16)&0xFF, (odi.par)&0xFF);
  1667. break;
  1668. case GF_STREAM_AUDIO:
  1669. fprintf(stdout, "Audio Object: Sample Rate %d - %d channels\r\n", odi.sample_rate, odi.num_channels);
  1670. fprintf(stdout, "Media Codec: %s\n", odi.codec_name);
  1671. break;
  1672. case GF_STREAM_SCENE:
  1673. case GF_STREAM_PRIVATE_SCENE:
  1674. if (odi.width && odi.height) {
  1675. fprintf(stdout, "Scene Description - Width %d - Height %d\n", odi.width, odi.height);
  1676. } else {
  1677. fprintf(stdout, "Scene Description - no size specified\n");
  1678. }
  1679. fprintf(stdout, "Scene Codec: %s\n", odi.codec_name);
  1680. break;
  1681. case GF_STREAM_TEXT:
  1682. if (odi.width && odi.height) {
  1683. fprintf(stdout, "Text Object: Width %d - Height %d\n", odi.width, odi.height);
  1684. } else {
  1685. fprintf(stdout, "Text Object: No size specified\n");
  1686. }
  1687. fprintf(stdout, "Text Codec %s\n", odi.codec_name);
  1688. break;
  1689. }
  1690. avg_dec_time = 0;
  1691. if (odi.nb_dec_frames) {
  1692. avg_dec_time = (Float) odi.total_dec_time;
  1693. avg_dec_time /= odi.nb_dec_frames;
  1694. }
  1695. fprintf(stdout, "\tBitrate over last second: %d kbps\n\tMax bitrate over one second: %d kbps\n\tAverage Decoding Time %.2f ms (%d max)\n\tTotal decoded frames %d\n",
  1696. (u32) odi.avg_bitrate/1024, odi.max_bitrate/1024, avg_dec_time, odi.max_dec_time, odi.nb_dec_frames);
  1697. }
  1698. if (odi.protection) fprintf(stdout, "Encrypted Media%s\n", (odi.protection==2) ? " NOT UNLOCKED" : "");
  1699. count = gf_list_count(odi.od->ESDescriptors);
  1700. fprintf(stdout, "%d streams in OD\n", count);
  1701. for (i=0; i<count; i++) {
  1702. GF_ESD *esd = (GF_ESD *) gf_list_get(odi.od->ESDescriptors, i);
  1703. fprintf(stdout, "\nStream ID %d - Clock ID %d\n", esd->ESID, esd->OCRESID);
  1704. if (esd->dependsOnESID) fprintf(stdout, "\tDepends on Stream ID %d for decoding\n", esd->dependsOnESID);
  1705. switch (esd->decoderConfig->streamType) {
  1706. case GF_STREAM_OD: fprintf(stdout, "\tOD Stream - version %d\n", esd->decoderConfig->objectTypeIndication); break;
  1707. case GF_STREAM_OCR: fprintf(stdout, "\tOCR Stream\n"); break;
  1708. case GF_STREAM_SCENE: fprintf(stdout, "\tScene Description Stream - version %d\n", esd->decoderConfig->objectTypeIndication); break;
  1709. case GF_STREAM_VISUAL:
  1710. fprintf(stdout, "\tVisual Stream - media type: ");
  1711. switch (esd->decoderConfig->objectTypeIndication) {
  1712. case GPAC_OTI_VIDEO_MPEG4_PART2: fprintf(stdout, "MPEG-4\n"); break;
  1713. case GPAC_OTI_VIDEO_MPEG2_SIMPLE: fprintf(stdout, "MPEG-2 Simple Profile\n"); break;
  1714. case GPAC_OTI_VIDEO_MPEG2_MAIN: fprintf(stdout, "MPEG-2 Main Profile\n"); break;
  1715. case GPAC_OTI_VIDEO_MPEG2_SNR: fprintf(stdout, "MPEG-2 SNR Profile\n"); break;
  1716. case GPAC_OTI_VIDEO_MPEG2_SPATIAL: fprintf(stdout, "MPEG-2 Spatial Profile\n"); break;
  1717. case GPAC_OTI_VIDEO_MPEG2_HIGH: fprintf(stdout, "MPEG-2 High Profile\n"); break;
  1718. case GPAC_OTI_VIDEO_MPEG2_422: fprintf(stdout, "MPEG-2 422 Profile\n"); break;
  1719. case GPAC_OTI_VIDEO_MPEG1: fprintf(stdout, "MPEG-1\n"); break;
  1720. case GPAC_OTI_IMAGE_JPEG: fprintf(stdout, "JPEG\n"); break;
  1721. case GPAC_OTI_IMAGE_PNG: fprintf(stdout, "PNG\n"); break;
  1722. case GPAC_OTI_IMAGE_JPEG_2000: fprintf(stdout, "JPEG2000\n"); break;
  1723. case GPAC_OTI_MEDIA_GENERIC:
  1724. memcpy(code, esd->decoderConfig->decoderSpecificInfo->data, 4);
  1725. code[4] = 0;
  1726. fprintf(stdout, "GPAC Intern (%s)\n", code);
  1727. break;
  1728. default:
  1729. fprintf(stdout, "Private Type (0x%x)\n", esd->decoderConfig->objectTypeIndication);
  1730. break;
  1731. }
  1732. break;
  1733. case GF_STREAM_AUDIO:
  1734. fprintf(stdout, "\tAudio Stream - media type: ");
  1735. switch (esd->decoderConfig->objectTypeIndication) {
  1736. case GPAC_OTI_AUDIO_AAC_MPEG4: fprintf(stdout, "MPEG-4\n"); break;
  1737. case GPAC_OTI_AUDIO_AAC_MPEG2_MP: fprintf(stdout, "MPEG-2 AAC Main Profile\n"); break;
  1738. case GPAC_OTI_AUDIO_AAC_MPEG2_LCP: fprintf(stdout, "MPEG-2 AAC LowComplexity Profile\n"); break;
  1739. case GPAC_OTI_AUDIO_AAC_MPEG2_SSRP: fprintf(stdout, "MPEG-2 AAC Scalable Sampling Rate Profile\n"); break;
  1740. case GPAC_OTI_AUDIO_MPEG2_PART3: fprintf(stdout, "MPEG-2 Audio\n"); break;
  1741. case GPAC_OTI_AUDIO_MPEG1: fprintf(stdout, "MPEG-1 Audio\n"); break;
  1742. case GPAC_OTI_AUDIO_EVRC_VOICE: fprintf(stdout, "EVRC Audio\n"); break;
  1743. case GPAC_OTI_AUDIO_SMV_VOICE: fprintf(stdout, "SMV Audio\n"); break;
  1744. case GPAC_OTI_AUDIO_13K_VOICE: fprintf(stdout, "QCELP Audio\n"); break;
  1745. case GPAC_OTI_MEDIA_GENERIC:
  1746. memcpy(code, esd->decoderConfig->decoderSpecificInfo->data, 4);
  1747. code[4] = 0;
  1748. fprintf(stdout, "GPAC Intern (%s)\n", code);
  1749. break;
  1750. default:
  1751. fprintf(stdout, "Private Type (0x%x)\n", esd->decoderConfig->objectTypeIndication);
  1752. break;
  1753. }
  1754. break;
  1755. case GF_STREAM_MPEG7: fprintf(stdout, "\tMPEG-7 Stream - version %d\n", esd->decoderConfig->objectTypeIndication); break;
  1756. case GF_STREAM_IPMP: fprintf(stdout, "\tIPMP Stream - version %d\n", esd->decoderConfig->objectTypeIndication); break;
  1757. case GF_STREAM_OCI: fprintf(stdout, "\tOCI Stream - version %d\n", esd->decoderConfig->objectTypeIndication); break;
  1758. case GF_STREAM_MPEGJ: fprintf(stdout, "\tMPEGJ Stream - version %d\n", esd->decoderConfig->objectTypeIndication); break;
  1759. case GF_STREAM_INTERACT: fprintf(stdout, "\tUser Interaction Stream - version %d\n", esd->decoderConfig->objectTypeIndication); break;
  1760. case GF_STREAM_TEXT: fprintf(stdout, "\tStreaming Text Stream - version %d\n", esd->decoderConfig->objectTypeIndication); break;
  1761. default: fprintf(stdout, "Unknown Stream\r\n"); break;
  1762. }
  1763. fprintf(stdout, "\tBuffer Size %d\n\tAverage Bitrate %d bps\n\tMaximum Bitrate %d bps\n", esd->decoderConfig->bufferSizeDB, esd->decoderConfig->avgBitrate, esd->decoderConfig->maxBitrate);
  1764. if (esd->slConfig->predefined==SLPredef_SkipSL) {
  1765. fprintf(stdout, "\tNot using MPEG-4 Synchronization Layer\n");
  1766. } else {
  1767. fprintf(stdout, "\tStream Clock Resolution %d\n", esd->slConfig->timestampResolution);
  1768. }
  1769. if (esd->URLString) fprintf(stdout, "\tStream Location: %s\n", esd->URLString);
  1770. /*check language*/
  1771. if (esd->langDesc) {
  1772. u32 i=0;
  1773. char lan[4], *szLang;
  1774. lan[0] = esd->langDesc->langCode>>16;
  1775. lan[1] = (esd->langDesc->langCode>>8)&0xFF;
  1776. lan[2] = (esd->langDesc->langCode)&0xFF;
  1777. lan[3] = 0;
  1778. if ((lan[0]=='u') && (lan[1]=='n') && (lan[2]=='d')) szLang = "Undetermined";
  1779. else {
  1780. szLang = lan;
  1781. while (GF_ISO639_Lang[i]) {
  1782. if (GF_ISO639_Lang[i+2][0] && strstr(GF_ISO639_Lang[i+1], lan)) {
  1783. szLang = (char*) GF_ISO639_Lang[i];
  1784. break;
  1785. }
  1786. i+=3;
  1787. }
  1788. }
  1789. fprintf(stdout, "\tStream Language: %s\n", szLang);
  1790. }
  1791. }
  1792. fprintf(stdout, "\n");
  1793. /*check OCI (not everything interests us) - FIXME: support for unicode*/
  1794. count = gf_list_count(odi.od->OCIDescriptors);
  1795. if (count) {
  1796. fprintf(stdout, "%d Object Content Information descriptors in OD\n", count);
  1797. for (i=0; i<count; i++) {
  1798. GF_Descriptor *desc = (GF_Descriptor *) gf_list_get(odi.od->OCIDescriptors, i);
  1799. switch (desc->tag) {
  1800. case GF_ODF_SEGMENT_TAG:
  1801. {
  1802. GF_Segment *sd = (GF_Segment *) desc;
  1803. fprintf(stdout, "Segment Descriptor: Name: %s - start time %g sec - duration %g sec\n", sd->SegmentName, sd->startTime, sd->Duration);
  1804. }
  1805. break;
  1806. case GF_ODF_CC_NAME_TAG:
  1807. {
  1808. GF_CC_Name *ccn = (GF_CC_Name *)desc;
  1809. fprintf(stdout, "Content Creators:\n");
  1810. for (j=0; j<gf_list_count(ccn->ContentCreators); j++) {
  1811. GF_ContentCreatorInfo *ci = (GF_ContentCreatorInfo *) gf_list_get(ccn->ContentCreators, j);
  1812. if (!ci->isUTF8) continue;
  1813. fprintf(stdout, "\t%s\n", ci->contentCreatorName);
  1814. }
  1815. }
  1816. break;
  1817. case GF_ODF_SHORT_TEXT_TAG:
  1818. {
  1819. GF_ShortTextual *std = (GF_ShortTextual *)desc;
  1820. fprintf(stdout, "Description:\n\tEvent: %s\n\t%s\n", std->eventName, std->eventText);
  1821. }
  1822. break;
  1823. default:
  1824. break;
  1825. }
  1826. }
  1827. fprintf(stdout, "\n");
  1828. }
  1829. switch (odi.status) {
  1830. case 0: fprintf(stdout, "Stopped - "); break;
  1831. case 1: fprintf(stdout, "Playing - "); break;
  1832. case 2: fprintf(stdout, "Paused - "); break;
  1833. case 3: fprintf(stdout, "Not setup yet\n"); return;
  1834. default: fprintf(stdout, "Setup Failed\n"); return;
  1835. }
  1836. if (odi.buffer>=0) fprintf(stdout, "Buffer: %d ms - ", odi.buffer);
  1837. else fprintf(stdout, "Not buffering - ");
  1838. fprintf(stdout, "Clock drift: %d ms\n", odi.clock_drift);
  1839. if (odi.db_unit_count) fprintf(stdout, "%d AU in DB\n", odi.db_unit_count);
  1840. if (odi.cb_max_count) fprintf(stdout, "Composition Buffer: %d CU (%d max)\n", odi.cb_unit_count, odi.cb_max_count);
  1841. fprintf(stdout, "\n");
  1842. if (odi.owns_service) {
  1843. const char *url;
  1844. u32 done, total, bps;
  1845. d_enum = 0;
  1846. while (gf_term_get_download_info(term, odm, &d_enum, &url, NULL, &done, &total, &bps)) {
  1847. if (d_enum==1) fprintf(stdout, "Current Downloads in service:\n");
  1848. if (done && total) {
  1849. fprintf(stdout, "%s: %d / %d bytes (%.2f %%) - %.2f kBps\n", url, done, total, (100.0f*done)/total, ((Float)bps)/1024.0f);
  1850. } else {
  1851. fprintf(stdout, "%s: %.2f kbps\n", url, ((Float)8*bps)/1024.0f);
  1852. }
  1853. }
  1854. if (!d_enum) fprintf(stdout, "No Downloads in service\n");
  1855. fprintf(stdout, "\n");
  1856. }
  1857. d_enum = 0;
  1858. while (gf_term_get_channel_net_info(term, odm, &d_enum, &id, &com, &e)) {
  1859. if (e) continue;
  1860. if (!com.bw_down && !com.bw_up) continue;
  1861. fprintf(stdout, "Stream ID %d statistics:\n", id);
  1862. if (com.multiplex_port) {
  1863. fprintf(stdout, "\tMultiplex Port %d - multiplex ID %d\n", com.multiplex_port, com.port);
  1864. } else {
  1865. fprintf(stdout, "\tPort %d\n", com.port);
  1866. }
  1867. fprintf(stdout, "\tPacket Loss Percentage: %.4f\n", com.pck_loss_percentage);
  1868. fprintf(stdout, "\tDown Bandwidth: %d bps\n", com.bw_down);
  1869. if (com.bw_up) fprintf(stdout, "\tUp Bandwidth: %d bps\n", com.bw_up);
  1870. if (com.ctrl_port) {
  1871. if (com.multiplex_port) {
  1872. fprintf(stdout, "\tControl Multiplex Port: %d - Control Multiplex ID %d\n", com.multiplex_port, com.ctrl_port);
  1873. } else {
  1874. fprintf(stdout, "\tControl Port: %d\n", com.ctrl_port);
  1875. }
  1876. fprintf(stdout, "\tDown Bandwidth: %d bps\n", com.ctrl_bw_down);
  1877. fprintf(stdout, "\tUp Bandwidth: %d bps\n", com.ctrl_bw_up);
  1878. }
  1879. fprintf(stdout, "\n");
  1880. }
  1881. }
  1882. void PrintODTiming(GF_Terminal *term, GF_ObjectManager *odm)
  1883. {
  1884. GF_MediaInfo odi;
  1885. if (!odm) return;
  1886. if (gf_term_get_object_info(term, odm, &odi) != GF_OK) return;
  1887. if (!odi.od) {
  1888. fprintf(stdout, "Service not attached\n");
  1889. return;
  1890. }
  1891. fprintf(stdout, "OD %d: ", odi.od->objectDescriptorID);
  1892. switch (odi.status) {
  1893. case 1: fprintf(stdout, "Playing - "); break;
  1894. case 2: fprintf(stdout, "Paused - "); break;
  1895. default: fprintf(stdout, "Stopped - "); break;
  1896. }
  1897. if (odi.buffer>=0) fprintf(stdout, "Buffer: %d ms - ", odi.buffer);
  1898. else fprintf(stdout, "Not buffering - ");
  1899. fprintf(stdout, "Clock drift: %d ms", odi.clock_drift);
  1900. fprintf(stdout, " - time: ");
  1901. PrintTime((u32) (odi.current_time*1000));
  1902. fprintf(stdout, "\n");
  1903. }
  1904. void PrintODBuffer(GF_Terminal *term, GF_ObjectManager *odm)
  1905. {
  1906. Float avg_dec_time;
  1907. GF_MediaInfo odi;
  1908. if (!odm) return;
  1909. if (gf_term_get_object_info(term, odm, &odi) != GF_OK) return;
  1910. if (!odi.od) {
  1911. fprintf(stdout, "Service not attached\n");
  1912. return;
  1913. }
  1914. fprintf(stdout, "OD %d: ", odi.od->objectDescriptorID);
  1915. switch (odi.status) {
  1916. case 1: fprintf(stdout, "Playing"); break;
  1917. case 2: fprintf(stdout, "Paused"); break;
  1918. default: fprintf(stdout, "Stopped"); break;
  1919. }
  1920. if (odi.buffer>=0) fprintf(stdout, " - Buffer: %d ms", odi.buffer);
  1921. if (odi.db_unit_count) fprintf(stdout, " - DB: %d AU", odi.db_unit_count);
  1922. if (odi.cb_max_count) fprintf(stdout, " - CB: %d/%d CUs", odi.cb_unit_count, odi.cb_max_count);
  1923. fprintf(stdout, "\n * %d decoded frames - %d dropped frames\n", odi.nb_dec_frames, odi.nb_droped);
  1924. avg_dec_time = 0;
  1925. if (odi.nb_dec_frames) { avg_dec_time = (Float) odi.total_dec_time; avg_dec_time /= odi.nb_dec_frames; }
  1926. fprintf(stdout, " * Avg Bitrate %d kbps (%d max) - Avg Decoding Time %.2f ms (%d max)\n",
  1927. (u32) odi.avg_bitrate/1024, odi.max_bitrate/1024, avg_dec_time, odi.max_dec_time);
  1928. }
  1929. void ViewODs(GF_Terminal *term, Bool show_timing)
  1930. {
  1931. u32 i, count;
  1932. GF_ObjectManager *odm, *root_odm = gf_term_get_root_object(term);
  1933. if (!root_odm) return;
  1934. if (show_timing) {
  1935. PrintODTiming(term, root_odm);
  1936. } else {
  1937. PrintODBuffer(term, root_odm);
  1938. }
  1939. count = gf_term_get_object_count(term, root_odm);
  1940. for (i=0; i<count; i++) {
  1941. odm = gf_term_get_object(term, root_odm, i);
  1942. if (show_timing) {
  1943. PrintODTiming(term, odm);
  1944. } else {
  1945. PrintODBuffer(term, odm);
  1946. }
  1947. }
  1948. fprintf(stdout, "\n");
  1949. }
  1950. void PrintGPACConfig()
  1951. {
  1952. u32 i, j, cfg_count, key_count;
  1953. char szName[200];
  1954. char *secName = NULL;
  1955. fprintf(stdout, "Enter section name (\"*\" for complete dump):\n");
  1956. scanf("%s", szName);
  1957. if (strcmp(szName, "*")) secName = szName;
  1958. fprintf(stdout, "\n\n*** GPAC Configuration ***\n\n");
  1959. cfg_count = gf_cfg_get_section_count(cfg_file);
  1960. for (i=0; i<cfg_count; i++) {
  1961. const char *sec = gf_cfg_get_section_name(cfg_file, i);
  1962. if (secName) {
  1963. if (stricmp(sec, secName)) continue;
  1964. } else {
  1965. if (!stricmp(sec, "General")) continue;
  1966. if (!stricmp(sec, "MimeTypes")) continue;
  1967. if (!stricmp(sec, "RecentFiles")) continue;
  1968. }
  1969. fprintf(stdout, "[%s]\n", sec);
  1970. key_count = gf_cfg_get_key_count(cfg_file, sec);
  1971. for (j=0; j<key_count; j++) {
  1972. const char *key = gf_cfg_get_key_name(cfg_file, sec, j);
  1973. const char *val = gf_cfg_get_key(cfg_file, sec, key);
  1974. fprintf(stdout, "%s=%s\n", key, val);
  1975. }
  1976. fprintf(stdout, "\n");
  1977. }
  1978. }