📄 main.c
字号:
/* * GPAC - Multimedia Framework C SDK * * Copyright (c) Jean Le Feuvre 2000-2005 * All rights reserved * * This file is part of GPAC / command-line client * * GPAC is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * GPAC is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * *//*includes both terminal and od browser*/#include <gpac/terminal.h>#include <gpac/term_info.h>#include <gpac/constants.h>#include <gpac/options.h>#include <gpac/modules/service.h>/*ISO 639 languages*/#include <gpac/iso639.h>#ifndef WIN32#include <pwd.h>#include <unistd.h>#else/*for GetModuleFileName*/#include <windows.h>#endif/*local prototypes*/void PrintWorldInfo(GF_Terminal *term);void ViewOD(GF_Terminal *term, u32 OD_ID);void PrintODList(GF_Terminal *term);void ViewODs(GF_Terminal *term, Bool show_timing);void PrintGPACConfig();static Bool not_threaded = 0;Bool is_connected = 0;Bool startup_file = 0;GF_User user;GF_Terminal *term;u64 Duration;GF_Err last_error = GF_OK;static GF_Config *cfg_file;static Bool display_rti = 0;static Bool Run;static Bool CanSeek = 0;static u32 Volume=100;static char the_url[GF_MAX_PATH];static Bool no_mime_check = 0;static Bool be_quiet = 0;/*windowless options*/u32 align_mode = 0;u32 init_w = 0;u32 init_h = 0;u32 last_x, last_y;Bool right_down = 0;#ifndef GPAC_READ_ONLYvoid dump_frame(GF_Terminal *term, char *rad_path, u32 dump_type, u32 frameNum);Bool dump_file(char *the_url, u32 dump_mode, Double fps, u32 width, u32 height, u32 *times, u32 nb_times);#endifvoid PrintUsage(){ fprintf(stdout, "Usage MP4Client [options] [filename]\n" "\t-c fileName: user-defined configuration file\n" "\t-rti fileName: logs run-time info (FPS, CPU, Mem usage) to file\n" "\t-quiet: removes script message, buffering and downloading status\n" "\t-log-file file: sets output log file.\n" "\t-log-level lev: sets log level. Possible values are:\n" "\t \"error\" : logs only error messages\n" "\t \"warning\" : logs error+warning messages\n" "\t \"info\" : logs error+warning+info messages\n" "\t \"debug\" : logs all messages\n" "\n" "\t-log-tools lt: sets tool(s) to log. List of \':\'-separated values:\n" "\t \"core\" : libgpac core\n" "\t \"coding\" : bitstream formats (audio, video, scene)\n" "\t \"container\" : container formats (ISO File, MPEG-2 TS, AVI, ...)\n" "\t \"network\" : network data exept RTP trafic\n" "\t \"rtp\" : rtp trafic\n" "\t \"author\" : authoring tools (hint, import, export)\n" "\t \"sync\" : terminal sync layer\n" "\t \"codec\" : terminal codec messages\n" "\t \"parser\" : scene parsers (svg, xmt, bt) and other\n" "\t \"media\" : terminal media object management\n" "\t \"scene\" : scene graph and scene manager\n" "\t \"script\" : scripting engine messages\n" "\t \"compose\" : composition engine (events, etc)\n" "\t \"render\" : renderng engine (2D, 3D, etc)\n" "\t \"service\" : network service management\n" "\t \"mmio\" : Audio/Video HW I/O management\n" "\t \"none\" : no tool logged\n" "\t \"all\" : all tools logged\n" "\n" "\t-size WxH: specifies visual size (default: scene size)\n" "\t-no-thread: disables thread usage (except for audio)\n" "\t-no-wnd: uses windowless mode (Win32 only)\n" "\t-align vh: specifies v and h alignment for windowless mode\n" " possible v values: t(op), m(iddle), b(ottom)\n" " possible h values: l(eft), m(iddle), r(ight)\n" " default alignment is top-left\n" "Dumper Options:\n" "\t-bmp [times]: dumps given frames to bmp\n" "\t-raw [times]: dumps given frames to bmp\n" "\t-avi [times]: dumps given file to raw avi\n" "\t-fps FPS: specifies frame rate for AVI dumping (default: 25.0)\n" "\t-2d: uses 2D renderer\n" "\t-3d: uses 3D renderer\n" "\t-fill: uses fill aspect ratio for dumping (default: none)\n" "\t-show: show window while dumping (default: no)\n" "MP4Client - GPAC command line player and dumper - version %s\n" "GPAC Written by Jean Le Feuvre (c) 2001-2005 - ENST (c) 2005-200X\n", GPAC_VERSION );}void PrintHelp(){ fprintf(stdout, "MP4Client command keys:\n" "\to: connect to the specified URL\n" "\tO: connect to the specified URL in playlist mode\n" "\tN: switch to the next URL in the playlist\n" "\tr: restart current presentation\n" "\tp: play/pause the presentation\n" "\ts: step one frame ahead\n" "\tz: seek into presentation\n" "\tt: print current timing\n" "\n" "\tw: view world info\n" "\tv: view Object Descriptor list\n" "\ti: view Object Descriptor info\n" "\tb: view media objects timing and buffering info\n" "\tm: view media objects buffering and memory info\n" "\td: dumps scene graph\n" "\n" "\tC: Enable Streaming Cache\n" "\tS: Stops Streaming Cache and save to file\n" "\tA: Aborts Streaming Cache\n" "\n" "\tk: turns stress mode on/off\n" "\tn: changes navigation mode\n" "\tx: reset to last active viewpoint\n" "\n" "\t2: restart using 2D renderer\n" "\t3: restart using 3D renderer\n" "\n" "\t4: forces 4/3 Aspect Ratio\n" "\t5: forces 16/9 Aspect Ratio\n" "\t6: forces no Aspect Ratio (always fill screen)\n" "\t7: forces original Aspect Ratio (default)\n" "\n" "\tL: changes to new log level. CF MP4Client usage for possible values\n" "\tM: select new tools to log. CF MP4Client usage for possible values\n" "\n" "\tl: list available modules\n" "\tc: prints some GPAC configuration info\n" "\tR: toggles run-time info display on/off\n" "\tq: exit the application\n" "\th: print this message\n" "\n" "MP4Client - GPAC command line player - version %s\n" "GPAC Written by Jean Le Feuvre (c) 2001-2005 - ENST (c) 2005-200X\n", GPAC_VERSION );}GF_Config *create_default_config(char *file_path, char *file_name){ GF_Config *cfg; char szPath[GF_MAX_PATH]; FILE *f; sprintf(szPath, "%s%c%s", file_path, GF_PATH_SEPARATOR, file_name); f = fopen(szPath, "wt"); fprintf(stdout, "create %s: %s\n", szPath, (f==NULL) ? "Error" : "OK"); if (!f) return NULL; fclose(f); cfg = gf_cfg_new(file_path, file_name); if (!cfg) return NULL;#ifdef GPAC_MODULES_PATH fprintf(stdout, "Using module directory %s \n", GPAC_MODULES_PATH); strcpy(szPath, GPAC_MODULES_PATH);#else fprintf(stdout, "Please enter full path to GPAC modules directory:\n"); scanf("%s", szPath);#endif gf_cfg_set_key(cfg, "General", "ModulesDirectory", szPath); gf_cfg_set_key(cfg, "Audio", "ForceConfig", "yes"); gf_cfg_set_key(cfg, "Audio", "NumBuffers", "2"); gf_cfg_set_key(cfg, "Audio", "TotalDuration", "120"); gf_cfg_set_key(cfg, "Audio", "DisableNotification", "no"); gf_cfg_set_key(cfg, "Rendering", "RendererName", "GPAC 2D Renderer"); gf_cfg_set_key(cfg, "FontEngine", "DriverName", "ft_font");#ifdef WIN32 GetWindowsDirectory((char*)szPath, MAX_PATH); if (szPath[strlen((char*)szPath)-1] != '\\') strcat((char*)szPath, "\\"); strcat((char *)szPath, "Fonts");#elif defined(__DARWIN__) || defined(__APPLE__) fprintf(stdout, "Please enter full path to a TrueType font directory (.ttf, .ttc) - enter to default:\n"); scanf("%s", szPath);#else /*these fonts seems installed by default on many systems...*/ gf_cfg_set_key(cfg, "FontEngine", "FontSerif", "Bitstream Vera Serif"); gf_cfg_set_key(cfg, "FontEngine", "FontSans", "Bitstream Vera Sans"); gf_cfg_set_key(cfg, "FontEngine", "FontFixed", "Bitstream Vera Monospace"); strcpy(szPath, "/usr/share/fonts/truetype/");#endif fprintf(stdout, "Using default font directory %s\n", szPath); gf_cfg_set_key(cfg, "FontEngine", "FontDirectory", szPath);#ifdef WIN32 fprintf(stdout, "Please enter full path to a cache directory for HTTP downloads:\n"); scanf("%s", szPath); gf_cfg_set_key(cfg, "General", "CacheDirectory", szPath);#else fprintf(stdout, "Using /tmp as a cache directory for HTTP downloads:\n"); gf_cfg_set_key(cfg, "General", "CacheDirectory", "/tmp");#endif gf_cfg_set_key(cfg, "Downloader", "CleanCache", "yes"); gf_cfg_set_key(cfg, "Rendering", "AntiAlias", "All"); gf_cfg_set_key(cfg, "Rendering", "Framerate", "30"); /*use power-of-2 emulation*/ gf_cfg_set_key(cfg, "Render3D", "EmulatePOW2", "yes");#ifdef WIN32 gf_cfg_set_key(cfg, "Render2D", "ScalableZoom", "yes"); gf_cfg_set_key(cfg, "Video", "DriverName", "DirectX Video Output");#else#ifdef __DARWIN__ gf_cfg_set_key(cfg, "Video", "DriverName", "SDL Video Output"); /*SDL not so fast with scalable zoom*/ gf_cfg_set_key(cfg, "Render2D", "ScalableZoom", "no");#else gf_cfg_set_key(cfg, "Video", "DriverName", "X11 Video Output"); /*x11 only supports scalable zoom*/ gf_cfg_set_key(cfg, "Render2D", "ScalableZoom", "yes"); gf_cfg_set_key(cfg, "Audio", "DriverName", "SDL Audio Output");#endif#endif gf_cfg_set_key(cfg, "Video", "SwitchResolution", "no"); gf_cfg_set_key(cfg, "Network", "AutoReconfigUDP", "yes"); gf_cfg_set_key(cfg, "Network", "UDPNotAvailable", "no"); gf_cfg_set_key(cfg, "Network", "UDPTimeout", "10000"); gf_cfg_set_key(cfg, "Network", "BufferLength", "3000"); /*store and reload*/ gf_cfg_del(cfg); return gf_cfg_new(file_path, file_name);}static void PrintTime(u64 time){ u32 ms, h, m, s; h = (u32) (time / 1000 / 3600); m = (u32) (time / 1000 / 60 - h*60); s = (u32) (time / 1000 - h*3600 - m*60); ms = (u32) (time - (h*3600 + m*60 + s) * 1000); fprintf(stdout, "%02d:%02d:%02d.%02d", h, m, s, ms);}#define RTI_UPDATE_TIME_MS 200static FILE *rti_logs = NULL;static u64 memory_at_gpac_startup = 0;static u64 memory_at_gpac_load = 0;static void init_rti_logs(char *rti_file, char *url){ if (rti_logs) fclose(rti_logs); rti_logs = fopen(rti_file, "wt"); if (rti_logs) { fprintf(rti_logs, "!! GPAC RunTime Info "); if (url) fprintf(rti_logs, "for file %s", url); fprintf(rti_logs, " !!\n"); fprintf(rti_logs, "SysTime(ms)\tSceneTime(ms)\tCPU\tFPS\tMemory(kB)\tObservation\n"); memory_at_gpac_load = 0; }}static void UpdateRTInfo(const char *legend){ GF_SystemRTInfo rti; /*refresh every second*/ if ((!display_rti && !rti_logs) || !gf_sys_get_rti(RTI_UPDATE_TIME_MS, &rti, 0 /*GF_RTI_ALL_PROCESSES_TIMES | GF_RTI_PROCESS_MEMORY*/) /*|| !rti.sampling_period_duration*/) return; if (display_rti) { char szMsg[1024]; GF_Event evt; if (!rti.process_memory) rti.process_memory = (u32) (memory_at_gpac_startup-rti.physical_memory_avail); if (!rti.gpac_memory) rti.gpac_memory = (u32) (memory_at_gpac_startup-rti.physical_memory_avail); sprintf(szMsg, "FPS %02.2f - CPU %02d (%02d) - Mem %d kB", gf_term_get_framerate(term, 0), rti.total_cpu_usage, rti.process_cpu_usage, (u32) (rti.gpac_memory / 1024) ); evt.type = GF_EVENT_SET_CAPTION; evt.caption.caption = szMsg; gf_term_user_event(term, &evt); } if (rti_logs) { if (!memory_at_gpac_load) memory_at_gpac_load = rti.gpac_memory; fprintf(rti_logs, "%d\t%d\t%d\t%d\t%d\t%s\n", gf_sys_clock(), gf_term_get_time_in_ms(term), rti.total_cpu_usage, (u32) gf_term_get_framerate(term, 0), (u32) ((rti.gpac_memory - memory_at_gpac_load) / 1024), legend ); }}static void ResetCaption(){ GF_Event event; if (display_rti) return; event.type = GF_EVENT_SET_CAPTION; if (is_connected) { char szName[1024]; NetInfoCommand com; event.caption.caption = NULL; /*get any service info*/ if (!startup_file && gf_term_get_service_info(term, gf_term_get_root_object(term), &com) == GF_OK) { strcpy(szName, ""); if (com.track_info) { char szBuf[10]; sprintf(szBuf, "%02d ", (u32) (com.track_info>>16) ); strcat(szName, szBuf); } if (com.artist) { strcat(szName, com.artist); strcat(szName, " "); } if (com.name) { strcat(szName, com.name); strcat(szName, " "); } if (com.album) { strcat(szName, "("); strcat(szName, com.album); strcat(szName, ")"); } if (strlen(szName)) event.caption.caption = szName; } if (!event.caption.caption) { char *str = strrchr(the_url, '\\'); if (!str) str = strrchr(the_url, '/'); event.caption.caption = str ? str+1 : the_url; } } else { event.caption.caption = "GPAC MP4Client " GPAC_VERSION; } gf_term_user_event(term, &event);}#ifdef WIN32u32 get_sys_col(int idx){ u32 res; DWORD val = GetSysColor(idx); res = (val)&0xFF; res<<=8; res |= (val>>8)&0xFF; res<<=8; res |= (val>>16)&0xFF; return res;}#endifBool GPAC_EventProc(void *ptr, GF_Event *evt){ if (!term) return 0; switch (evt->type) { case GF_EVENT_UPDATE_RTI: UpdateRTInfo(evt->caption.caption); break; case GF_EVENT_RESET_RTI: memory_at_gpac_load = 0; UpdateRTInfo(evt->caption.caption); break; case GF_EVENT_DURATION: Duration = 1000; Duration = (u64) (((s64) Duration) * evt->duration.duration); CanSeek = evt->duration.can_seek; break; case GF_EVENT_MESSAGE: { const char *servName; if (!evt->message.service || !strcmp(evt->message.service, the_url)) { servName = "main service"; } else { servName = evt->message.service; } if (!evt->message.message) return 0; if (evt->message.error==GF_SCRIPT_INFO) { fprintf(stdout, "%s\n", evt->message.message); } else if (evt->message.error) { if (!is_connected) last_error = evt->message.error; fprintf(stdout, "%s (%s): %s\n", evt->message.message, servName, gf_error_to_string(evt->message.error)); } else if (!be_quiet) fprintf(stdout, "(%s) %s\r", servName, evt->message.message); } break; case GF_EVENT_PROGRESS: { char *szTitle = ""; if (evt->progress.progress_type==0) szTitle = "Buffer "; else if (evt->progress.progress_type==1) szTitle = "Download "; else if (evt->progress.progress_type==2) szTitle = "Import "; gf_set_progress(szTitle, evt->progress.done, evt->progress.total); } break; case GF_EVENT_MOUSEDOUBLECLICK: gf_term_set_option(term, GF_OPT_FULLSCREEN, !gf_term_get_option(term, GF_OPT_FULLSCREEN)); return 0; case GF_EVENT_MOUSEDOWN: if (evt->mouse.button==GF_MOUSE_RIGHT) { right_down = 1; last_x = evt->mouse.x; last_y = evt->mouse.y; } return 0; case GF_EVENT_MOUSEUP: if (evt->mouse.button==GF_MOUSE_RIGHT) { right_down = 0; last_x = evt->mouse.x; last_y = evt->mouse.y; } return 0; case GF_EVENT_MOUSEMOVE: if (right_down && (user.init_flags & GF_TERM_WINDOWLESS) ) { GF_Event move; move.move.x = evt->mouse.x - last_x; move.move.y = evt->mouse.y - last_y; move.type = GF_EVENT_MOVE; move.move.relative = 1; gf_term_user_event(term, &move);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -