Line data Source code
1 : /*
2 : * GPAC - Multimedia Framework C SDK
3 : *
4 : * Authors: Jean Le Feuvre
5 : * Copyright (c) Telecom ParisTech 2000-2021
6 : * All rights reserved
7 : *
8 : * This file is part of GPAC / common tools sub-project
9 : *
10 : * GPAC is free software; you can redistribute it and/or modify
11 : * it under the terms of the GNU Lesser General Public License as published by
12 : * the Free Software Foundation; either version 2, or (at your option)
13 : * any later version.
14 : *
15 : * GPAC is distributed in the hope that it will be useful,
16 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : * GNU Lesser General Public License for more details.
19 : *
20 : * You should have received a copy of the GNU Lesser General Public
21 : * License along with this library; see the file COPYING. If not, write to
22 : * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23 : *
24 : */
25 :
26 : #include <gpac/tools.h>
27 : #include <gpac/thread.h>
28 :
29 :
30 : //ugly patch, we have a concurrence issue with gf_4cc_to_str, for now fixed by rolling buffers
31 : #define NB_4CC_BUF 10
32 : static char szTYPE_BUF[NB_4CC_BUF][GF_4CC_MSIZE];
33 : static u32 buf_4cc_idx=0;
34 :
35 : GF_EXPORT
36 230404 : const char *gf_4cc_to_str(u32 type)
37 : {
38 : u32 ch, i;
39 230404 : char *szTYPE = szTYPE_BUF[buf_4cc_idx];
40 : char *name = (char *)szTYPE;
41 230404 : if (!type) return "00000000";
42 230312 : buf_4cc_idx++;
43 230312 : if (buf_4cc_idx==NB_4CC_BUF)
44 22155 : buf_4cc_idx=0;
45 :
46 921248 : for (i = 0; i < 4; i++) {
47 921248 : ch = type >> (8 * (3-i) ) & 0xff;
48 921248 : if ( ch >= 0x20 && ch <= 0x7E ) {
49 917227 : *name = ch;
50 917227 : name++;
51 : } else {
52 : sprintf(name, "%02X", ch);
53 4021 : name += 2;
54 : }
55 : }
56 230312 : *name = 0;
57 230312 : return (const char *) szTYPE;
58 : }
59 :
60 : GF_EXPORT
61 1 : u32 gf_4cc_parse(const char *val)
62 : {
63 1 : if (val && strlen(val)==4) return GF_4CC(val[0], val[1], val[2], val[3]);
64 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] Value is not a properly defined 4CC", val));
65 : return 0;
66 : }
67 :
68 : static const char *szProg[] =
69 : {
70 : " ",
71 : "= ",
72 : "== ",
73 : "=== ",
74 : "==== ",
75 : "===== ",
76 : "====== ",
77 : "======= ",
78 : "======== ",
79 : "========= ",
80 : "========== ",
81 : "=========== ",
82 : "============ ",
83 : "============= ",
84 : "============== ",
85 : "=============== ",
86 : "================ ",
87 : "================= ",
88 : "================== ",
89 : "=================== ",
90 : "====================",
91 : };
92 :
93 : static u64 prev_pos = (u64) -1;
94 : static u64 prev_pc = (u64) -1;
95 : extern char gf_prog_lf;
96 :
97 346 : static void gf_on_progress_std(const char *_title, u64 done, u64 total)
98 : {
99 : Double prog;
100 : u32 pos, pc;
101 346 : const char *szT = _title ? (char *)_title : (char *) "";
102 346 : prog = (double) done;
103 346 : prog /= total;
104 346 : pos = MIN((u32) (20 * prog), 20);
105 :
106 346 : if (pos>prev_pos) {
107 40 : prev_pos = 0;
108 40 : prev_pc = 0;
109 : }
110 346 : pc = (u32) ( 100 * prog);
111 346 : if ((pos!=prev_pos) || (pc!=prev_pc)) {
112 122 : prev_pos = pos;
113 122 : prev_pc = pc;
114 122 : fprintf(stderr, "%s: |%s| (%02d/100)%c", szT, szProg[pos], pc, gf_prog_lf);
115 122 : fflush(stderr);
116 : }
117 346 : if (done==total) {
118 14 : if (prev_pos) {
119 14 : u32 len = (u32) strlen(szT) + 40;
120 682 : while (len) {
121 654 : fprintf(stderr, " ");
122 654 : len--;
123 : };
124 14 : fprintf(stderr, "%c", gf_prog_lf);
125 : }
126 14 : prev_pos = 0;
127 : }
128 346 : }
129 :
130 : static gf_on_progress_cbk prog_cbk = NULL;
131 : static void *user_cbk;
132 : static Bool gpac_no_color_logs = GF_FALSE;
133 :
134 : GF_EXPORT
135 1598681 : void gf_set_progress(const char *title, u64 done, u64 total)
136 : {
137 1598681 : if (done>=total)
138 : done=total;
139 1598681 : if (prog_cbk) {
140 1598335 : prog_cbk(user_cbk, title, done, total);
141 : }
142 : #ifndef _WIN32_WCE
143 : else {
144 346 : gf_on_progress_std(title, done, total);
145 : }
146 : #endif
147 1598681 : }
148 :
149 : GF_EXPORT
150 6190 : void gf_set_progress_callback(void *_user_cbk, gf_on_progress_cbk _prog_cbk)
151 : {
152 6190 : prog_cbk = _prog_cbk;
153 6190 : user_cbk = _user_cbk;
154 6190 : }
155 :
156 : #ifndef GPAC_DISABLE_LOG
157 :
158 : /*ENTRIES MUST BE IN THE SAME ORDER AS LOG_TOOL DECLARATION IN <gpac/tools.h>*/
159 : static struct log_tool_info {
160 : u32 type;
161 : const char *name;
162 : GF_LOG_Level level;
163 : } global_log_tools [] =
164 : {
165 : { GF_LOG_CORE, "core", GF_LOG_WARNING },
166 : { GF_LOG_CODING, "coding", GF_LOG_WARNING },
167 : { GF_LOG_CONTAINER, "container", GF_LOG_WARNING },
168 : { GF_LOG_NETWORK, "network", GF_LOG_WARNING },
169 : { GF_LOG_HTTP, "http", GF_LOG_WARNING },
170 : { GF_LOG_RTP, "rtp", GF_LOG_WARNING },
171 : { GF_LOG_AUTHOR, "author", GF_LOG_WARNING },
172 : { GF_LOG_SYNC, "sync", GF_LOG_WARNING },
173 : { GF_LOG_CODEC, "codec", GF_LOG_WARNING },
174 : { GF_LOG_PARSER, "parser", GF_LOG_WARNING },
175 : { GF_LOG_MEDIA, "media", GF_LOG_WARNING },
176 : { GF_LOG_SCENE, "scene", GF_LOG_WARNING },
177 : { GF_LOG_SCRIPT, "script", GF_LOG_WARNING },
178 : { GF_LOG_INTERACT, "interact", GF_LOG_WARNING },
179 : { GF_LOG_COMPOSE, "compose", GF_LOG_WARNING },
180 : { GF_LOG_CACHE, "cache", GF_LOG_WARNING },
181 : { GF_LOG_MMIO, "mmio", GF_LOG_WARNING },
182 : { GF_LOG_RTI, "rti", GF_LOG_WARNING },
183 : { GF_LOG_SMIL, "smil", GF_LOG_WARNING },
184 : { GF_LOG_MEMORY, "mem", GF_LOG_WARNING },
185 : { GF_LOG_AUDIO, "audio", GF_LOG_WARNING },
186 : { GF_LOG_MODULE, "module", GF_LOG_WARNING },
187 : { GF_LOG_MUTEX, "mutex", GF_LOG_WARNING },
188 : { GF_LOG_CONDITION, "condition", GF_LOG_WARNING },
189 : { GF_LOG_DASH, "dash", GF_LOG_WARNING },
190 : { GF_LOG_FILTER, "filter", GF_LOG_WARNING },
191 : { GF_LOG_SCHEDULER, "sched", GF_LOG_WARNING },
192 : { GF_LOG_ROUTE, "route", GF_LOG_WARNING },
193 : { GF_LOG_CONSOLE, "console", GF_LOG_INFO },
194 : { GF_LOG_APP, "app", GF_LOG_INFO },
195 : };
196 :
197 : #define GF_LOG_TOOL_MAX_NAME_SIZE (GF_LOG_TOOL_MAX*10)
198 :
199 : #endif
200 :
201 : GF_EXPORT
202 183 : GF_Err gf_log_modify_tools_levels(const char *val_)
203 : {
204 : #ifndef GPAC_DISABLE_LOG
205 : char tmp[GF_LOG_TOOL_MAX_NAME_SIZE];
206 : const char *val = tmp;
207 183 : if (!val_) val_ = "";
208 : assert(strlen(val_) < GF_LOG_TOOL_MAX_NAME_SIZE);
209 : strncpy(tmp, val_, GF_LOG_TOOL_MAX_NAME_SIZE - 1);
210 183 : tmp[GF_LOG_TOOL_MAX_NAME_SIZE - 1] = 0;
211 :
212 368 : while (val && strlen(val)) {
213 : void default_log_callback(void *cbck, GF_LOG_Level level, GF_LOG_Tool tool, const char *fmt, va_list vlist);
214 : u32 level;
215 : const char *next_val = NULL;
216 : const char *tools = NULL;
217 : /*look for log level*/
218 185 : char *sep_level = strchr(val, '@');
219 185 : if (!sep_level) {
220 136 : if (!strcmp(val, "ncl")) {
221 1 : gpac_no_color_logs = GF_TRUE;
222 1 : gf_log_set_callback(NULL, default_log_callback);
223 1 : if (!val[3]) break;
224 0 : val += 4;
225 0 : continue;
226 135 : } else if (!strcmp(val, "strict")) {
227 135 : gf_log_set_strict_error(GF_TRUE);
228 135 : if (!val[6]) break;
229 0 : val += 7;
230 0 : continue;
231 0 : } else if (!strcmp(val, "quiet")) {
232 : u32 i;
233 0 : for (i=0; i<GF_LOG_TOOL_MAX; i++)
234 0 : global_log_tools[i].level = GF_LOG_QUIET;
235 :
236 0 : if (!val[5]) break;
237 0 : val += 6;
238 0 : continue;
239 : } else {
240 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("Unrecognized log format %s - expecting logTool@logLevel\n", val));
241 : return GF_BAD_PARAM;
242 : }
243 : }
244 :
245 49 : if (!strnicmp(sep_level+1, "error", 5)) {
246 : level = GF_LOG_ERROR;
247 5 : next_val = sep_level+1 + 5;
248 : }
249 44 : else if (!strnicmp(sep_level+1, "warning", 7)) {
250 : level = GF_LOG_WARNING;
251 0 : next_val = sep_level+1 + 7;
252 : }
253 44 : else if (!strnicmp(sep_level+1, "info", 4)) {
254 : level = GF_LOG_INFO;
255 6 : next_val = sep_level+1 + 4;
256 : }
257 38 : else if (!strnicmp(sep_level+1, "debug", 5)) {
258 : level = GF_LOG_DEBUG;
259 38 : next_val = sep_level+1 + 5;
260 : }
261 0 : else if (!strnicmp(sep_level+1, "quiet", 5)) {
262 : level = GF_LOG_QUIET;
263 0 : next_val = sep_level+1 + 5;
264 : }
265 : else {
266 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("Unknown log level specified: %s\n", sep_level+1));
267 : return GF_BAD_PARAM;
268 : }
269 :
270 49 : sep_level[0] = 0;
271 : tools = val;
272 106 : while (tools) {
273 : u32 i;
274 :
275 57 : char *sep = strchr(tools, ':');
276 57 : if (sep) sep[0] = 0;
277 :
278 57 : if (!stricmp(tools, "all")) {
279 30 : for (i=0; i<GF_LOG_TOOL_MAX; i++)
280 30 : global_log_tools[i].level = level;
281 : }
282 56 : else if (!strcmp(val, "ncl")) {
283 0 : gpac_no_color_logs = GF_TRUE;
284 0 : gf_log_set_callback(NULL, default_log_callback);
285 : }
286 : else {
287 : Bool found = GF_FALSE;
288 908 : for (i=0; i<GF_LOG_TOOL_MAX; i++) {
289 964 : if (!strcmp(global_log_tools[i].name, tools)) {
290 56 : global_log_tools[i].level = level;
291 : found = GF_TRUE;
292 : break;
293 : }
294 : }
295 : if (!found) {
296 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("Unknown log tool specified: %s\n", tools));
297 : sep_level[0] = '@';
298 : if (sep) sep[0] = ':';
299 : return GF_BAD_PARAM;
300 : }
301 : }
302 :
303 57 : if (!sep) break;
304 8 : sep[0] = ':';
305 8 : tools = sep+1;
306 : }
307 :
308 49 : sep_level[0] = '@';
309 49 : if (!next_val[0]) break;
310 2 : val = next_val+1;
311 : }
312 : #endif
313 : return GF_OK;
314 : }
315 :
316 : GF_EXPORT
317 183 : GF_Err gf_log_set_tools_levels(const char *val, Bool reset_all)
318 : {
319 : #ifndef GPAC_DISABLE_LOG
320 : u32 i;
321 183 : if (reset_all) {
322 0 : for (i=0; i<GF_LOG_TOOL_MAX; i++)
323 0 : global_log_tools[i].level = GF_LOG_WARNING;
324 : }
325 183 : return gf_log_modify_tools_levels(val);
326 : #else
327 : return GF_OK;
328 : #endif
329 : }
330 :
331 : GF_EXPORT
332 1 : char *gf_log_get_tools_levels()
333 : {
334 : #ifndef GPAC_DISABLE_LOG
335 : u32 i, level, len;
336 : char szLogs[GF_MAX_PATH];
337 : char szLogTools[GF_MAX_PATH];
338 : strcpy(szLogTools, "");
339 :
340 : level = GF_LOG_QUIET;
341 7 : while (level <= GF_LOG_DEBUG) {
342 : u32 nb_tools = 0;
343 : strcpy(szLogs, "");
344 155 : for (i=0; i<GF_LOG_TOOL_MAX; i++) {
345 150 : if (global_log_tools[i].level == level) {
346 30 : strcat(szLogs, global_log_tools[i].name);
347 : strcat(szLogs, ":");
348 30 : nb_tools++;
349 : }
350 : }
351 5 : if (nb_tools) {
352 : char *levelstr = "@warning";
353 3 : if (level==GF_LOG_QUIET) levelstr = "@quiet";
354 3 : else if (level==GF_LOG_ERROR) levelstr = "@error";
355 3 : else if (level==GF_LOG_WARNING) levelstr = "@warning";
356 2 : else if (level==GF_LOG_INFO) levelstr = "@info";
357 : else if (level==GF_LOG_DEBUG) levelstr = "@debug";
358 :
359 3 : if (nb_tools>GF_LOG_TOOL_MAX/2) {
360 : strcpy(szLogs, szLogTools);
361 : strcpy(szLogTools, "all");
362 : strcat(szLogTools, levelstr);
363 1 : if (strlen(szLogs)) {
364 : strcat(szLogTools, ":");
365 : strcat(szLogTools, szLogs);
366 : }
367 : } else {
368 2 : if (strlen(szLogTools)) {
369 : strcat(szLogTools, ":");
370 : }
371 : /*remove last ':' from tool*/
372 2 : szLogs[ strlen(szLogs) - 1 ] = 0;
373 : strcat(szLogTools, szLogs);
374 : strcat(szLogTools, levelstr);
375 : }
376 : }
377 5 : level++;
378 : }
379 1 : len = (u32) strlen(szLogTools);
380 1 : if (len) {
381 : /*remove last ':' from level*/
382 1 : if (szLogTools[ len-1 ] == ':') szLogTools[ len-1 ] = 0;
383 1 : return gf_strdup(szLogTools);
384 : }
385 : #endif
386 0 : return gf_strdup("all@quiet");
387 : }
388 :
389 :
390 : #if defined(GPAC_CONFIG_WIN32) || defined(WIN32)
391 : #include <windows.h>
392 : #include <wincon.h>
393 : static HANDLE console = NULL;
394 : static WORD console_attr_ori = 0;
395 : static CONSOLE_SCREEN_BUFFER_INFO cbck_console;
396 : static CONSOLE_CURSOR_INFO cbck_cursor;
397 : static PCHAR_INFO cbck_buffer=NULL;
398 : static Bool cbck_stored=GF_FALSE;
399 : static Bool is_mintty = GF_FALSE;
400 : #endif
401 :
402 :
403 :
404 :
405 : GF_EXPORT
406 443819 : void gf_sys_set_console_code(FILE *std, GF_ConsoleCodes code)
407 : {
408 : u32 color_code;
409 :
410 443819 : if (gf_sys_is_test_mode() || gpac_no_color_logs)
411 : return;
412 38750 : color_code = code & 0xFFFF;
413 : #if defined(GPAC_CONFIG_WIN32) || defined(WIN32)
414 : WORD attribs=0;
415 : if (!is_mintty && (console == NULL)) {
416 : CONSOLE_SCREEN_BUFFER_INFO console_info;
417 : const char *shellv = getenv("SHELL");
418 : if (shellv) {
419 : is_mintty = GF_TRUE;
420 : GF_LOG(GF_LOG_INFO, GF_LOG_CORE, ("[Console] Detected MSys/MinGW/Cygwin TTY, will use VT for coloring\n"))
421 : } else {
422 : console = GetStdHandle(STD_ERROR_HANDLE);
423 : if (console != INVALID_HANDLE_VALUE) {
424 : GetConsoleScreenBufferInfo(console, &console_info);
425 : console_attr_ori = console_info.wAttributes;
426 : GF_LOG(GF_LOG_INFO, GF_LOG_CORE, ("[Console] Detected Windows shell, will use SetConsoleTextAttribute for coloring\n"))
427 : }
428 : }
429 : }
430 :
431 : if (is_mintty) goto win32_ismtty;
432 :
433 : switch(color_code) {
434 : case GF_CONSOLE_RED:
435 : attribs = FOREGROUND_INTENSITY | FOREGROUND_RED;
436 : break;
437 : case GF_CONSOLE_BLUE:
438 : attribs = FOREGROUND_INTENSITY | FOREGROUND_BLUE;
439 : break;
440 : case GF_CONSOLE_GREEN:
441 : attribs = FOREGROUND_INTENSITY | FOREGROUND_GREEN;
442 : break;
443 : case GF_CONSOLE_YELLOW:
444 : attribs = FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN;
445 : break;
446 : case GF_CONSOLE_MAGENTA:
447 : attribs = FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_BLUE;
448 : break;
449 : case GF_CONSOLE_CYAN:
450 : attribs = FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_BLUE;
451 : break;
452 : case GF_CONSOLE_WHITE:
453 : attribs = FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE;
454 : break;
455 :
456 : case GF_CONSOLE_SAVE:
457 : if (!cbck_stored) {
458 : u32 size, line, line_incr;
459 : COORD pos;
460 : BOOL res;
461 : SMALL_RECT region;
462 :
463 : res = GetConsoleScreenBufferInfo(console, &cbck_console);
464 : if (res) res = GetConsoleCursorInfo(console, &cbck_cursor);
465 :
466 : if (!res) {
467 : GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("Failed to save win32 console info\n"));
468 : return;
469 : }
470 : size = cbck_console.dwSize.X * cbck_console.dwSize.Y;
471 : cbck_buffer = (PCHAR_INFO) gf_malloc(size * sizeof(CHAR_INFO));
472 : pos.X = 0;
473 : region.Left = 0;
474 : region.Right = cbck_console.dwSize.X - 1;
475 : line_incr = 12000 / cbck_console.dwSize.X;
476 : for (line=0; line < (u32) cbck_console.dwSize.Y; line += line_incr) {
477 : pos.Y = line;
478 : region.Top = line;
479 : region.Bottom = line + line_incr - 1;
480 : if (!ReadConsoleOutput(console, cbck_buffer, cbck_console.dwSize, pos, ®ion)) {
481 : gf_free(cbck_buffer);
482 : cbck_buffer = NULL;
483 : GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("Failed to save win32 console info\n"));
484 : return;
485 : }
486 : }
487 : cbck_stored = GF_TRUE;
488 : }
489 : return;
490 :
491 : case GF_CONSOLE_RESTORE:
492 : if (cbck_stored) {
493 : COORD pos;
494 : SMALL_RECT region;
495 : BOOL res;
496 : pos.X = pos.Y = 0;
497 : region.Top = region.Left = 0;
498 : region.Bottom = cbck_console.dwSize.Y - 1;
499 : region.Right = cbck_console.dwSize.X - 1;
500 : res = SetConsoleScreenBufferSize(console, cbck_console.dwSize);
501 : if (res) res = SetConsoleWindowInfo(console, TRUE, &cbck_console.srWindow);
502 : if (res) res = SetConsoleCursorPosition(console, cbck_console.dwCursorPosition);
503 : if (res) res = SetConsoleTextAttribute(console, cbck_console.wAttributes);
504 :
505 : if (!res) {
506 : GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("Failed to restore win32 console info\n"));
507 : return;
508 : }
509 : WriteConsoleOutput(console, cbck_buffer, cbck_console.dwSize,
510 : pos, ®ion);
511 : gf_free(cbck_buffer);
512 : cbck_stored = GF_FALSE;
513 : }
514 : return;
515 :
516 : case GF_CONSOLE_CLEAR:
517 : {
518 : COORD coords;
519 : DWORD written;
520 : DWORD consolesize;
521 : CONSOLE_SCREEN_BUFFER_INFO console_info;
522 :
523 : coords.X = coords.Y = 0;
524 : GetConsoleScreenBufferInfo(console, &console_info);
525 : consolesize = console_info.dwSize.X * console_info.dwSize.Y;
526 :
527 : /* fill space & attribute */
528 : FillConsoleOutputCharacter(console, ' ', consolesize, coords, &written);
529 : FillConsoleOutputAttribute(console, console_info.wAttributes, consolesize, coords, &written);
530 : SetConsoleCursorPosition(console, coords);
531 : }
532 : return;
533 : case GF_CONSOLE_RESET:
534 : default:
535 : attribs = console_attr_ori;
536 : }
537 :
538 : if ((code & 0xFFFF0000) && !color_code) {
539 : attribs |= COMMON_LVB_UNDERSCORE;
540 : }
541 :
542 : SetConsoleTextAttribute(console, attribs);
543 : return;
544 :
545 : win32_ismtty:
546 : #endif
547 :
548 :
549 : #if !defined(_WIN32_WCE)
550 :
551 38750 : switch(color_code) {
552 : case GF_CONSOLE_RED: fprintf(std, "\x1b[31m"); break;
553 : case GF_CONSOLE_BLUE:
554 : fprintf(std, "\x1b[34m");
555 : break;
556 : case GF_CONSOLE_GREEN:
557 : fprintf(std, "\x1b[32m");
558 : break;
559 : case GF_CONSOLE_YELLOW:
560 : fprintf(std, "\x1b[33m");
561 : break;
562 : case GF_CONSOLE_MAGENTA:
563 : fprintf(std, "\x1b[35m");
564 : break;
565 : case GF_CONSOLE_CYAN:
566 : fprintf(std, "\x1b[36m");
567 : break;
568 : case GF_CONSOLE_WHITE:
569 : fprintf(std, "\x1b[37m");
570 : break;
571 :
572 : case GF_CONSOLE_CLEAR:
573 : fprintf(std, "\x1b[2J\x1b[0;0H");
574 : return;
575 :
576 : case GF_CONSOLE_SAVE:
577 : fprintf(std, "\033[?47h");
578 : return;
579 : case GF_CONSOLE_RESTORE:
580 : fprintf(std, "\033[?47l");
581 : fprintf(std, "\x1b[J");
582 : return;
583 :
584 23876 : case GF_CONSOLE_RESET:
585 : default:
586 23876 : if (!code)
587 : fprintf(std, "\x1b[0m");
588 : }
589 38750 : if (code) {
590 19387 : if (code & GF_CONSOLE_BOLD) fprintf(std, "\x1b[1m");
591 19387 : if (code & GF_CONSOLE_ITALIC) fprintf(std, "\x1b[3m");
592 19387 : if (code & GF_CONSOLE_UNDERLINED) fprintf(std, "\x1b[4m");
593 19387 : if (code & GF_CONSOLE_STRIKE) fprintf(std, "\x1b[9m");
594 : }
595 : #endif
596 : }
597 :
598 : #ifndef GPAC_DISABLE_LOG
599 : u32 call_lev = 0;
600 : u32 call_tool = 0;
601 :
602 : GF_EXPORT
603 851335154 : Bool gf_log_tool_level_on(GF_LOG_Tool log_tool, GF_LOG_Level log_level)
604 : {
605 851335154 : if (log_tool==GF_LOG_TOOL_MAX) return GF_TRUE;
606 851387457 : if (log_tool>GF_LOG_TOOL_MAX) return GF_FALSE;
607 851454957 : if (global_log_tools[log_tool].level >= log_level) return GF_TRUE;
608 851242707 : return GF_FALSE;
609 : }
610 :
611 87 : const char *gf_log_tool_name(GF_LOG_Tool log_tool)
612 : {
613 87 : if (log_tool>=GF_LOG_TOOL_MAX) return "unknown";
614 87 : return global_log_tools[log_tool].name;
615 : }
616 87 : const char *gf_log_level_name(GF_LOG_Level log_level)
617 : {
618 87 : switch (log_level) {
619 : case GF_LOG_DEBUG: return "debug";
620 87 : case GF_LOG_INFO: return "info";
621 0 : case GF_LOG_WARNING: return "warning";
622 0 : case GF_LOG_ERROR: return "error";
623 0 : default: return "unknown";
624 : }
625 : }
626 :
627 : GF_EXPORT
628 6286 : u32 gf_log_get_tool_level(GF_LOG_Tool log_tool)
629 : {
630 6286 : if (log_tool>=GF_LOG_TOOL_MAX) return GF_LOG_ERROR;
631 6286 : return global_log_tools[log_tool].level;
632 : }
633 :
634 : FILE *gpac_log_file = NULL;
635 : Bool gpac_log_time_start = GF_FALSE;
636 : Bool gpac_log_utc_time = GF_FALSE;
637 : static u64 gpac_last_log_time=0;
638 :
639 198287 : static void do_log_time(FILE *logs)
640 : {
641 198287 : if (gpac_log_time_start) {
642 7000 : u64 now = gf_sys_clock_high_res();
643 7000 : gf_fprintf(logs, "At "LLD" (diff %d) - ", now, (u32) (now - gpac_last_log_time) );
644 7000 : gpac_last_log_time = now;
645 : }
646 198287 : if (gpac_log_utc_time) {
647 466 : u64 utc_clock = gf_net_get_utc() ;
648 466 : time_t secs = utc_clock/1000;
649 : struct tm t;
650 466 : t = *gf_gmtime(&secs);
651 466 : gf_fprintf(logs, "UTC %d-%02d-%02dT%02d:%02d:%02dZ (TS "LLU") - ", 1900+t.tm_year, t.tm_mon+1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, utc_clock);
652 : }
653 198287 : }
654 :
655 : int gf_fileio_printf(GF_FileIO *gfio, const char *format, va_list args);
656 :
657 377 : void default_log_callback(void *cbck, GF_LOG_Level level, GF_LOG_Tool tool, const char *fmt, va_list vlist)
658 : {
659 377 : FILE *logs = gpac_log_file ? gpac_log_file : stderr;
660 377 : do_log_time(logs);
661 :
662 377 : if (gf_fileio_check(logs)) {
663 0 : gf_fileio_printf((GF_FileIO *)logs, fmt, vlist);
664 : } else {
665 : vfprintf(logs, fmt, vlist);
666 : }
667 377 : gf_fflush(logs);
668 377 : }
669 :
670 197910 : void default_log_callback_color(void *cbck, GF_LOG_Level level, GF_LOG_Tool tool, const char *fmt, va_list vlist)
671 : {
672 197910 : if (gpac_log_file) {
673 0 : default_log_callback(cbck, level, tool, fmt, vlist);
674 0 : return;
675 : }
676 197910 : switch(level) {
677 2254 : case GF_LOG_ERROR:
678 2254 : gf_sys_set_console_code(stderr, GF_CONSOLE_RED);
679 2254 : break;
680 1753 : case GF_LOG_WARNING:
681 1753 : gf_sys_set_console_code(stderr, GF_CONSOLE_YELLOW);
682 1753 : break;
683 96369 : case GF_LOG_INFO:
684 96369 : gf_sys_set_console_code(stderr, (tool==GF_LOG_APP) ? GF_CONSOLE_WHITE : GF_CONSOLE_GREEN);
685 96369 : break;
686 97534 : case GF_LOG_DEBUG:
687 97534 : gf_sys_set_console_code(stderr, GF_CONSOLE_CYAN);
688 97534 : break;
689 0 : default:
690 0 : gf_sys_set_console_code(stderr, GF_CONSOLE_WHITE);
691 0 : break;
692 : }
693 197910 : do_log_time(stderr);
694 :
695 197910 : vfprintf(stderr, fmt, vlist);
696 197910 : gf_sys_set_console_code(stderr, GF_CONSOLE_RESET);
697 197910 : gf_fflush(stderr);
698 : }
699 :
700 :
701 :
702 : static void *user_log_cbk = NULL;
703 : gf_log_cbk log_cbk = default_log_callback_color;
704 : static Bool log_exit_on_error = GF_FALSE;
705 : extern GF_Mutex *logs_mx;
706 :
707 : GF_EXPORT
708 2 : Bool gf_log_use_color()
709 : {
710 2 : return (log_cbk == default_log_callback_color) ? GF_TRUE : GF_FALSE;
711 : }
712 :
713 : GF_EXPORT
714 214552 : void gf_log(const char *fmt, ...)
715 : {
716 : va_list vl;
717 214552 : va_start(vl, fmt);
718 214552 : gf_mx_p(logs_mx);
719 214552 : log_cbk(user_log_cbk, call_lev, call_tool, fmt, vl);
720 214552 : gf_mx_v(logs_mx);
721 214552 : va_end(vl);
722 214552 : if (log_exit_on_error && (call_lev==GF_LOG_ERROR) && (call_tool != GF_LOG_MEMORY)) {
723 0 : exit(1);
724 : }
725 214552 : }
726 :
727 : GF_EXPORT
728 0 : void gf_log_va_list(GF_LOG_Level level, GF_LOG_Tool tool, const char *fmt, va_list vl)
729 : {
730 0 : log_cbk(user_log_cbk, call_lev, call_tool, fmt, vl);
731 0 : if (log_exit_on_error && (call_lev==GF_LOG_ERROR) && (call_tool != GF_LOG_MEMORY)) {
732 0 : exit(1);
733 : }
734 0 : }
735 :
736 : GF_EXPORT
737 176 : Bool gf_log_set_strict_error(Bool strict)
738 : {
739 176 : Bool old = log_exit_on_error;
740 176 : log_exit_on_error = strict;
741 176 : return old;
742 : }
743 :
744 : GF_EXPORT
745 63731 : void gf_log_set_tool_level(GF_LOG_Tool tool, GF_LOG_Level level)
746 : {
747 : assert(tool<=GF_LOG_TOOL_MAX);
748 63731 : if (tool==GF_LOG_ALL) {
749 : u32 i;
750 187530 : for (i=0; i<GF_LOG_TOOL_MAX; i++) {
751 187530 : global_log_tools[i].level = level;
752 : }
753 : } else {
754 57480 : global_log_tools[tool].level = level;
755 : }
756 63731 : }
757 :
758 : GF_EXPORT
759 214552 : void gf_log_lt(GF_LOG_Level ll, GF_LOG_Tool lt)
760 : {
761 214552 : call_lev = ll;
762 214552 : call_tool = lt;
763 214552 : }
764 :
765 : GF_EXPORT
766 15 : gf_log_cbk gf_log_set_callback(void *usr_cbk, gf_log_cbk cbk)
767 : {
768 15 : gf_log_cbk prev_cbk = log_cbk;
769 15 : log_cbk = cbk;
770 15 : if (!log_cbk) log_cbk = default_log_callback;
771 15 : if (usr_cbk) user_log_cbk = usr_cbk;
772 15 : return prev_cbk;
773 : }
774 :
775 : #else
776 : GF_EXPORT
777 : void gf_log(const char *fmt, ...)
778 : {
779 : }
780 : GF_EXPORT
781 : void gf_log_lt(GF_LOG_Level ll, GF_LOG_Tool lt)
782 : {
783 : }
784 : GF_EXPORT
785 : Bool gf_log_set_strict_error(Bool strict)
786 : {
787 : return GF_FALSE;
788 : }
789 :
790 : GF_EXPORT
791 : gf_log_cbk gf_log_set_callback(void *usr_cbk, gf_log_cbk cbk)
792 : {
793 : return NULL;
794 : }
795 :
796 : GF_EXPORT
797 : void gf_log_set_tool_level(GF_LOG_Tool tool, GF_LOG_Level level)
798 : {
799 : }
800 :
801 : GF_EXPORT
802 : u32 gf_log_get_tool_level(GF_LOG_Tool log_tool)
803 : {
804 : return 0;
805 : }
806 :
807 : GF_EXPORT
808 : Bool gf_log_tool_level_on(GF_LOG_Tool log_tool, GF_LOG_Level log_level)
809 : {
810 : return GF_FALSE;
811 : }
812 :
813 : #endif
814 :
815 : static char szErrMsg[50];
816 :
817 : GF_EXPORT
818 65 : const char *gf_error_to_string(GF_Err e)
819 : {
820 65 : switch (e) {
821 : case GF_EOS:
822 : return "End Of Stream / File";
823 0 : case GF_OK:
824 0 : return "No Error";
825 :
826 : /*General errors */
827 14 : case GF_BAD_PARAM:
828 14 : return "Bad Parameter";
829 0 : case GF_OUT_OF_MEM:
830 0 : return "Out Of Memory";
831 5 : case GF_IO_ERR:
832 5 : return "I/O Error";
833 2 : case GF_NOT_SUPPORTED:
834 2 : return "Feature Not Supported";
835 2 : case GF_CORRUPTED_DATA:
836 2 : return "Corrupted Data in file/stream";
837 :
838 : /*File Format Errors */
839 6 : case GF_ISOM_INVALID_FILE:
840 6 : return "Invalid IsoMedia File";
841 0 : case GF_ISOM_INCOMPLETE_FILE:
842 0 : return "IsoMedia File is truncated";
843 0 : case GF_ISOM_INVALID_MEDIA:
844 0 : return "Invalid IsoMedia Media";
845 0 : case GF_ISOM_INVALID_MODE:
846 0 : return "Invalid Mode while accessing the file";
847 0 : case GF_ISOM_UNKNOWN_DATA_REF:
848 0 : return "Media Data Reference not found";
849 :
850 : /*Object Descriptor Errors */
851 0 : case GF_ODF_INVALID_DESCRIPTOR:
852 0 : return "Invalid MPEG-4 Descriptor";
853 0 : case GF_ODF_FORBIDDEN_DESCRIPTOR:
854 0 : return "MPEG-4 Descriptor Not Allowed";
855 0 : case GF_ODF_INVALID_COMMAND:
856 0 : return "Read OD Command Failed";
857 :
858 : /*BIFS Errors */
859 0 : case GF_SG_UNKNOWN_NODE:
860 0 : return "Unknown BIFS Node";
861 0 : case GF_SG_INVALID_PROTO:
862 0 : return "Invalid Proto Interface";
863 0 : case GF_BIFS_UNKNOWN_VERSION:
864 0 : return "Invalid BIFS version";
865 0 : case GF_SCRIPT_ERROR:
866 0 : return "Invalid Script";
867 :
868 0 : case GF_BUFFER_TOO_SMALL:
869 0 : return "Bad Buffer size (too small)";
870 0 : case GF_NON_COMPLIANT_BITSTREAM:
871 0 : return "BitStream Not Compliant";
872 0 : case GF_FILTER_NOT_FOUND:
873 0 : return "Filter not found for the desired type";
874 :
875 20 : case GF_URL_ERROR:
876 20 : return "Requested URL is not valid or cannot be found";
877 0 : case GF_URL_REMOVED:
878 0 : return "Requested URL is no longer available";
879 :
880 0 : case GF_SERVICE_ERROR:
881 0 : return "Internal Service Error";
882 0 : case GF_REMOTE_SERVICE_ERROR:
883 0 : return "Dialog Failure with remote peer";
884 :
885 0 : case GF_STREAM_NOT_FOUND:
886 0 : return "Media Channel couldn't be found";
887 :
888 0 : case GF_IP_ADDRESS_NOT_FOUND:
889 0 : return "IP Address Not Found";
890 0 : case GF_IP_CONNECTION_FAILURE:
891 0 : return "IP Connection Failed";
892 0 : case GF_IP_NETWORK_FAILURE:
893 0 : return "Network Unreachable";
894 :
895 3 : case GF_IP_NETWORK_EMPTY:
896 3 : return "Network Timeout";
897 0 : case GF_IP_SOCK_WOULD_BLOCK:
898 0 : return "Socket Would Block";
899 5 : case GF_IP_CONNECTION_CLOSED:
900 5 : return "Connection to server closed";
901 0 : case GF_IP_UDP_TIMEOUT:
902 0 : return "UDP traffic timeout";
903 0 : case GF_AUTHENTICATION_FAILURE:
904 0 : return "Authentication failure";
905 0 : case GF_SCRIPT_NOT_READY:
906 0 : return "Script not ready for playback";
907 0 : case GF_INVALID_CONFIGURATION:
908 0 : return "Bad configuration for the current context";
909 8 : case GF_NOT_FOUND:
910 8 : return "At least one required element has not been found";
911 0 : case GF_PROFILE_NOT_SUPPORTED:
912 0 : return "Unsupported codec profile";
913 0 : case GF_REQUIRES_NEW_INSTANCE:
914 0 : return "Requires a new instance of the filter to be supported";
915 0 : case GF_FILTER_NOT_SUPPORTED:
916 0 : return "Not supported by any filter chain";
917 : default:
918 : sprintf(szErrMsg, "Unknown Error (%d)", e);
919 0 : return szErrMsg;
920 : }
921 : }
922 :
923 : static const u32 gf_crc_table[256] = {
924 : 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
925 : 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
926 : 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
927 : 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
928 : 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
929 : 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
930 : 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
931 : 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
932 : 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
933 : 0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
934 : 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
935 : 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
936 : 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
937 : 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
938 : 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
939 : 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
940 : 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
941 : 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
942 : 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
943 : 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
944 : 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
945 : 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
946 : 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
947 : 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
948 : 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
949 : 0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
950 : 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
951 : 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
952 : 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
953 : 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
954 : 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
955 : 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
956 : 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
957 : 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
958 : 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
959 : 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
960 : 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
961 : 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
962 : 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
963 : 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
964 : 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
965 : 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
966 : 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
967 : };
968 :
969 : GF_EXPORT
970 209657 : u32 gf_crc_32(const u8 *data, u32 len)
971 : {
972 : register u32 i;
973 : u32 crc = 0xffffffff;
974 209657 : if (!data) return 0;
975 646518064 : for (i=0; i<len; i++)
976 646518064 : crc = (crc << 8) ^ gf_crc_table[((crc >> 24) ^ *data++) & 0xff];
977 :
978 : return crc;
979 : }
980 :
981 :
982 : #define CHECK_MAC(_a) "#_a :" ? (_a) ? "yes":"no"
983 :
984 : static const char *gf_enabled_features()
985 : {
986 : const char *features = ""
987 : #ifdef GPAC_CONFIG_WIN32
988 : "GPAC_CONFIG_WIN32 "
989 : #endif
990 : #ifdef GPAC_CONFIG_DARWIN
991 : "GPAC_CONFIG_DARWIN "
992 : #endif
993 : #ifdef GPAC_CONFIG_LINUX
994 : "GPAC_CONFIG_LINUX "
995 : #endif
996 : #ifdef GPAC_CONFIG_ANDROID
997 : "GPAC_CONFIG_ANDROID "
998 : #endif
999 : #ifdef GPAC_CONFIG_IOS
1000 : "GPAC_CONFIG_IOS "
1001 : #endif
1002 : #ifdef GPAC_64_BITS
1003 : "GPAC_64_BITS "
1004 : #endif
1005 : #ifdef GPAC_FIXED_POINT
1006 : "GPAC_FIXED_POINT "
1007 : #endif
1008 : #ifdef GPAC_MEMORY_TRACKING
1009 : "GPAC_MEMORY_TRACKING "
1010 : #endif
1011 : #ifdef GPAC_BIG_ENDIAN
1012 : "GPAC_BIG_ENDIAN "
1013 : #endif
1014 : #ifdef GPAC_HAS_IPV6
1015 : "GPAC_HAS_IPV6 "
1016 : #endif
1017 : #ifdef GPAC_HAS_SSL
1018 : "GPAC_HAS_SSL "
1019 : #endif
1020 : #ifdef GPAC_HAS_SOCK_UN
1021 : "GPAC_HAS_SOCK_UN "
1022 : #endif
1023 : #ifdef GPAC_ENABLE_COVERAGE
1024 : "GPAC_ENABLE_COVERAGE "
1025 : #endif
1026 : #ifdef GPAC_MINIMAL_ODF
1027 : "GPAC_MINIMAL_ODF "
1028 : #endif
1029 : #ifdef GPAC_HAS_QJS
1030 : "GPAC_HAS_QJS "
1031 : #endif
1032 : #ifdef GPAC_HAS_FREETYPE
1033 : "GPAC_HAS_FREETYPE "
1034 : #endif
1035 : #ifdef GPAC_HAS_FAAD
1036 : "GPAC_HAS_FAAD "
1037 : #endif
1038 : #ifdef GPAC_HAS_MAD
1039 : "GPAC_HAS_MAD "
1040 : #endif
1041 : #ifdef GPAC_HAS_LIBA52
1042 : "GPAC_HAS_LIBA52 "
1043 : #endif
1044 : #ifdef GPAC_HAS_JPEG
1045 : "GPAC_HAS_JPEG "
1046 : #endif
1047 : #ifdef GPAC_HAS_PNG
1048 : "GPAC_HAS_PNG "
1049 : #endif
1050 : #ifdef GPAC_HAS_FFMPEG
1051 : "GPAC_HAS_FFMPEG "
1052 : #endif
1053 : #ifdef GPAC_HAS_OPENSVC
1054 : "GPAC_HAS_OPENSVC "
1055 : #endif
1056 : #ifdef GPAC_HAS_JP2
1057 : "GPAC_HAS_JP2 "
1058 : #endif
1059 : #ifdef GPAC_HAS_OPENHEVC
1060 : "GPAC_HAS_OPENHEVC "
1061 : #endif
1062 : #ifdef GPAC_HAS_THEORA
1063 : "GPAC_HAS_THEORA "
1064 : #endif
1065 : #ifdef GPAC_HAS_VORBIS
1066 : "GPAC_HAS_VORBIS "
1067 : #endif
1068 : #ifdef GPAC_HAS_XVID
1069 : "GPAC_HAS_XVID "
1070 : #endif
1071 : #ifdef GPAC_HAS_LINUX_DVB
1072 : "GPAC_HAS_LINUX_DVB "
1073 : #endif
1074 : #ifdef GPAC_HAS_GLU
1075 : "GPAC_HAS_GLU "
1076 : #endif
1077 :
1078 : #if defined(_WIN32_WCE)
1079 : #ifdef GPAC_USE_IGPP
1080 : "GPAC_USE_IGPP "
1081 : #endif
1082 : #ifdef GPAC_USE_IGPP_HP
1083 : "GPAC_USE_IGPP_HP "
1084 : #endif
1085 : #endif
1086 : ;
1087 : return features;
1088 : }
1089 :
1090 : static const char *gf_disabled_features()
1091 : {
1092 : const char *features = ""
1093 : #ifdef GPAC_DISABLE_3D
1094 : "GPAC_DISABLE_3D "
1095 : #endif
1096 : #ifdef GPAC_USE_TINYGL
1097 : "GPAC_USE_TINYGL "
1098 : #endif
1099 : #ifdef GPAC_USE_GLES1X
1100 : "GPAC_USE_GLES1X "
1101 : #endif
1102 : #ifdef GPAC_USE_GLES2
1103 : "GPAC_USE_GLES2 "
1104 : #endif
1105 : #ifdef GPAC_DISABLE_ZLIB
1106 : "GPAC_DISABLE_ZLIB "
1107 : #endif
1108 : #ifdef GPAC_DISABLE_SVG
1109 : "GPAC_DISABLE_SVG "
1110 : #endif
1111 : #ifdef GPAC_DISABLE_VRML
1112 : "GPAC_DISABLE_VRML "
1113 : #endif
1114 : #ifdef GPAC_DISABLE_BIFS
1115 : "GPAC_DISABLE_BIFS "
1116 : #endif
1117 : #ifdef GPAC_DISABLE_QTVR
1118 : "GPAC_DISABLE_QTVR "
1119 : #endif
1120 : #ifdef GPAC_DISABLE_AVILIB
1121 : "GPAC_DISABLE_AVILIB "
1122 : #endif
1123 : #ifdef GPAC_DISABLE_OGG
1124 : "GPAC_DISABLE_OGG "
1125 : #endif
1126 : #ifdef GPAC_DISABLE_MPEG2PS
1127 : "GPAC_DISABLE_MPEG2PS "
1128 : #endif
1129 : #ifdef GPAC_DISABLE_MPEG2PS
1130 : "GPAC_DISABLE_MPEG2TS "
1131 : #endif
1132 : #ifdef GPAC_DISABLE_SENG
1133 : "GPAC_DISABLE_SENG "
1134 : #endif
1135 : #ifdef GPAC_DISABLE_MEDIA_IMPORT
1136 : "GPAC_DISABLE_MEDIA_IMPORT "
1137 : #endif
1138 : #ifdef GPAC_DISABLE_AV_PARSERS
1139 : "GPAC_DISABLE_AV_PARSERS "
1140 : #endif
1141 : #ifdef GPAC_DISABLE_MEDIA_EXPORT
1142 : "GPAC_DISABLE_MEDIA_EXPORT "
1143 : #endif
1144 : #ifdef GPAC_DISABLE_SWF_IMPORT
1145 : "GPAC_DISABLE_SWF_IMPORT "
1146 : #endif
1147 : #ifdef GPAC_DISABLE_SCENE_STATS
1148 : "GPAC_DISABLE_SCENE_STATS "
1149 : #endif
1150 : #ifdef GPAC_DISABLE_SCENE_DUMP
1151 : "GPAC_DISABLE_SCENE_DUMP "
1152 : #endif
1153 : #ifdef GPAC_DISABLE_SCENE_ENCODER
1154 : "GPAC_DISABLE_SCENE_ENCODER "
1155 : #endif
1156 : #ifdef GPAC_DISABLE_LOADER_ISOM
1157 : "GPAC_DISABLE_LOADER_ISOM "
1158 : #endif
1159 : #ifdef GPAC_DISABLE_OD_DUMP
1160 : "GPAC_DISABLE_OD_DUMP "
1161 : #endif
1162 : #ifdef GPAC_DISABLE_CRYPTO
1163 : "GPAC_DISABLE_CRYPTO "
1164 : #endif
1165 : #ifdef GPAC_DISABLE_ISOM
1166 : "GPAC_DISABLE_CRYPTO "
1167 : #endif
1168 : #ifdef GPAC_DISABLE_ISOM_HINTING
1169 : "GPAC_DISABLE_ISOM_HINTING "
1170 : #endif
1171 : #ifdef GPAC_DISABLE_ISOM_WRITE
1172 : "GPAC_DISABLE_ISOM_WRITE "
1173 : #endif
1174 : #ifdef GPAC_DISABLE_ISOM_FRAGMENTS
1175 : "GPAC_DISABLE_ISOM_FRAGMENTS "
1176 : #endif
1177 : #ifdef GPAC_DISABLE_LASER
1178 : "GPAC_DISABLE_LASER "
1179 : #endif
1180 : #ifdef GPAC_DISABLE_STREAMING
1181 : "GPAC_DISABLE_STREAMING "
1182 : #endif
1183 : #ifdef GPAC_DISABLE_ROUTE
1184 : "GPAC_DISABLE_ROUTE "
1185 : #endif
1186 :
1187 : ;
1188 : return features;
1189 : }
1190 :
1191 : GF_EXPORT
1192 26 : const char *gf_sys_features(Bool disabled)
1193 : {
1194 26 : if (disabled)
1195 : return gf_disabled_features();
1196 : else
1197 13 : return gf_enabled_features();
1198 : }
1199 :
1200 : static const struct lang_def {
1201 : const char *name;
1202 : const char *three_char_code;
1203 : const char *two_char_code;
1204 : } defined_languages [] =
1205 : {
1206 : { "Abkhazian","abk","ab"} ,
1207 : { "Achinese","ace",""} ,
1208 : { "Acoli","ach",""} ,
1209 : { "Adangme","ada",""} ,
1210 : { "Adyghe; Adygei","ady",""} ,
1211 : { "Afar","aar","aa"} ,
1212 : { "Afrihili","afh",""} ,
1213 : { "Afrikaans","afr","af"} ,
1214 : { "Afro-Asiatic languages","afa",""} ,
1215 : { "Ainu","ain",""} ,
1216 : { "Akan","aka","ak"} ,
1217 : { "Akkadian","akk",""} ,
1218 : { "Albanian","sqi","sq"} ,
1219 : { "Aleut","ale",""} ,
1220 : { "Algonquian languages","alg",""} ,
1221 : { "Altaic languages","tut",""} ,
1222 : { "Amharic","amh","am"} ,
1223 : { "Angika","anp",""} ,
1224 : { "Apache languages","apa",""} ,
1225 : { "Arabic","ara","ar"} ,
1226 : { "Aragonese","arg","an"} ,
1227 : { "Arapaho","arp",""} ,
1228 : { "Arawak","arw",""} ,
1229 : { "Armenian","hye","hy"} ,
1230 : { "Aromanian; Arumanian; Macedo-Romanian","rup",""} ,
1231 : { "Artificial languages","art",""} ,
1232 : { "Assamese","asm","as"} ,
1233 : { "Asturian; Bable; Leonese; Asturleonese","ast",""} ,
1234 : { "Athapascan languages","ath",""} ,
1235 : { "Australian languages","aus",""} ,
1236 : { "Austronesian languages","map",""} ,
1237 : { "Avaric","ava","av"} ,
1238 : { "Avestan","ave","ae"} ,
1239 : { "Awadhi","awa",""} ,
1240 : { "Aymara","aym","ay"} ,
1241 : { "Azerbaijani","aze","az"} ,
1242 : { "Balinese","ban",""} ,
1243 : { "Baltic languages","bat",""} ,
1244 : { "Baluchi","bal",""} ,
1245 : { "Bambara","bam","bm"} ,
1246 : { "Bamileke languages","bai",""} ,
1247 : { "Banda languages","bad",""} ,
1248 : { "Bantu languages","bnt",""} ,
1249 : { "Basa","bas",""} ,
1250 : { "Bashkir","bak","ba"} ,
1251 : { "Basque","eus","eu"} ,
1252 : { "Batak languages","btk",""} ,
1253 : { "Beja; Bedawiyet","bej",""} ,
1254 : { "Belarusian","bel","be"} ,
1255 : { "Bemba","bem",""} ,
1256 : { "Bengali","ben","bn"} ,
1257 : { "Berber languages","ber",""} ,
1258 : { "Bhojpuri","bho",""} ,
1259 : { "Bihari languages","bih","bh"} ,
1260 : { "Bikol","bik",""} ,
1261 : { "Bini; Edo","bin",""} ,
1262 : { "Bislama","bis","bi"} ,
1263 : { "Blin; Bilin","byn",""} ,
1264 : { "Blissymbols; Blissymbolics; Bliss","zbl",""} ,
1265 : { "Bokmal, Norwegian; Norwegian Bokmal","nob","nb"} ,
1266 : { "Bosnian","bos","bs"} ,
1267 : { "Braj","bra",""} ,
1268 : { "Breton","bre","br"} ,
1269 : { "Buginese","bug",""} ,
1270 : { "Bulgarian","bul","bg"} ,
1271 : { "Buriat","bua",""} ,
1272 : { "Burmese","mya","my"} ,
1273 : { "Caddo","cad",""} ,
1274 : { "Catalan; Valencian","cat","ca"} ,
1275 : { "Caucasian languages","cau",""} ,
1276 : { "Cebuano","ceb",""} ,
1277 : { "Celtic languages","cel",""} ,
1278 : { "Central American Indian languages","cai",""} ,
1279 : { "Central Khmer","khm","km"} ,
1280 : { "Chagatai","chg",""} ,
1281 : { "Chamic languages","cmc",""} ,
1282 : { "Chamorro","cha","ch"} ,
1283 : { "Chechen","che","ce"} ,
1284 : { "Cherokee","chr",""} ,
1285 : { "Cheyenne","chy",""} ,
1286 : { "Chibcha","chb",""} ,
1287 : { "Chichewa; Chewa; Nyanja","nya","ny"} ,
1288 : { "Chinese","zho","zh"} ,
1289 : { "Chinook jargon","chn",""} ,
1290 : { "Chipewyan; Dene Suline","chp",""} ,
1291 : { "Choctaw","cho",""} ,
1292 : { "Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church} S{ lavonic","chu","cu"} ,
1293 : { "Chuukese","chk",""} ,
1294 : { "Chuvash","chv","cv"} ,
1295 : { "Classical Newari; Old Newari; Classical Nepal Bhasa","nwc",""} ,
1296 : { "Classical Syriac","syc",""} ,
1297 : { "Coptic","cop",""} ,
1298 : { "Cornish","cor","kw"} ,
1299 : { "Corsican","cos","co"} ,
1300 : { "Cree","cre","cr"} ,
1301 : { "Creek","mus",""} ,
1302 : { "Creoles and pidgins","crp",""} ,
1303 : { "Creoles and pidgins, English based","cpe",""} ,
1304 : { "Creoles and pidgins, French-based","cpf",""} ,
1305 : { "Creoles and pidgins, Portuguese-based","cpp",""} ,
1306 : { "Crimean Tatar; Crimean Turkish","crh",""} ,
1307 : { "Croatian","hrv","hr"} ,
1308 : { "Cushitic languages","cus",""} ,
1309 : { "Czech","ces","cs"} ,
1310 : { "Dakota","dak",""} ,
1311 : { "Danish","dan","da"} ,
1312 : { "Dargwa","dar",""} ,
1313 : { "Delaware","del",""} ,
1314 : { "Dinka","din",""} ,
1315 : { "Divehi; Dhivehi; Maldivian","div","dv"} ,
1316 : { "Dogri","doi",""} ,
1317 : { "Dogrib","dgr",""} ,
1318 : { "Dravidian languages","dra",""} ,
1319 : { "Duala","dua",""} ,
1320 : { "Dutch, Middle (ca.1050-1350)","dum",""} ,
1321 : { "Dutch; Flemish","nld","nl"} ,
1322 : { "Dyula","dyu",""} ,
1323 : { "Dzongkha","dzo","dz"} ,
1324 : { "Eastern Frisian","frs",""} ,
1325 : { "Efik","efi",""} ,
1326 : { "Egyptian (Ancient)","egy",""} ,
1327 : { "Ekajuk","eka",""} ,
1328 : { "Elamite","elx",""} ,
1329 : { "English","eng","en"} ,
1330 : { "English, Middle (1100-1500)","enm",""} ,
1331 : { "English, Old (ca.450-1100)","ang",""} ,
1332 : { "Erzya","myv",""} ,
1333 : { "Esperanto","epo","eo"} ,
1334 : { "Estonian","est","et"} ,
1335 : { "Ewe","ewe","ee"} ,
1336 : { "Ewondo","ewo",""} ,
1337 : { "Fang","fan",""} ,
1338 : { "Fanti","fat",""} ,
1339 : { "Faroese","fao","fo"} ,
1340 : { "Fijian","fij","fj"} ,
1341 : { "Filipino; Pilipino","fil",""} ,
1342 : { "Finnish","fin","fi"} ,
1343 : { "Finno-Ugrian languages","fiu",""} ,
1344 : { "Fon","fon",""} ,
1345 : { "French","fra","fr"} ,
1346 : { "French, Middle (ca.1400-1600)","frm",""} ,
1347 : { "French, Old (842-ca.1400)","fro",""} ,
1348 : { "Friulian","fur",""} ,
1349 : { "Fulah","ful","ff"} ,
1350 : { "Ga","gaa",""} ,
1351 : { "Gaelic; Scottish Gaelic","gla","gd"} ,
1352 : { "Galibi Carib","car",""} ,
1353 : { "Galician","glg","gl"} ,
1354 : { "Ganda","lug","lg"} ,
1355 : { "Gayo","gay",""} ,
1356 : { "Gbaya","gba",""} ,
1357 : { "Geez","gez",""} ,
1358 : { "Georgian","kat","ka"} ,
1359 : { "German","deu","de"} ,
1360 : { "German, Middle High (ca.1050-1500)","gmh",""} ,
1361 : { "German, Old High (ca.750-1050)","goh",""} ,
1362 : { "Germanic languages","gem",""} ,
1363 : { "Gilbertese","gil",""} ,
1364 : { "Gondi","gon",""} ,
1365 : { "Gorontalo","gor",""} ,
1366 : { "Gothic","got",""} ,
1367 : { "Grebo","grb",""} ,
1368 : { "Greek, Ancient (to 1453)","grc",""} ,
1369 : { "Greek, Modern (1453-)","ell","el"} ,
1370 : { "Guarani","grn","gn"} ,
1371 : { "Gujarati","guj","gu"} ,
1372 : { "Gwich'in","gwi",""} ,
1373 : { "Haida","hai",""} ,
1374 : { "Haitian; Haitian Creole","hat","ht"} ,
1375 : { "Hausa","hau","ha"} ,
1376 : { "Hawaiian","haw",""} ,
1377 : { "Hebrew","heb","he"} ,
1378 : { "Herero","her","hz"} ,
1379 : { "Hiligaynon","hil",""} ,
1380 : { "Himachali languages; Western Pahari languages","him",""} ,
1381 : { "Hindi","hin","hi"} ,
1382 : { "Hiri Motu","hmo","ho"} ,
1383 : { "Hittite","hit",""} ,
1384 : { "Hmong; Mong","hmn",""} ,
1385 : { "Hungarian","hun","hu"} ,
1386 : { "Hupa","hup",""} ,
1387 : { "Iban","iba",""} ,
1388 : { "Icelandic","isl","is"} ,
1389 : { "Ido","ido","io"} ,
1390 : { "Igbo","ibo","ig"} ,
1391 : { "Ijo languages","ijo",""} ,
1392 : { "Iloko","ilo",""} ,
1393 : { "Inari Sami","smn",""} ,
1394 : { "Indic languages","inc",""} ,
1395 : { "Indo-European languages","ine",""} ,
1396 : { "Indonesian","ind","id"} ,
1397 : { "Ingush","inh",""} ,
1398 : { "Interlingua (International Auxiliary Language Association)","ina","ia"} ,
1399 : { "Interlingue; Occidental","ile","ie"} ,
1400 : { "Inuktitut","iku","iu"} ,
1401 : { "Inupiaq","ipk","ik"} ,
1402 : { "Iranian languages","ira",""} ,
1403 : { "Irish","gle","ga"} ,
1404 : { "Irish, Middle (900-1200)","mga",""} ,
1405 : { "Irish, Old (to 900)","sga",""} ,
1406 : { "Iroquoian languages","iro",""} ,
1407 : { "Italian","ita","it"} ,
1408 : { "Japanese","jpn","ja"} ,
1409 : { "Javanese","jav","jv"} ,
1410 : { "Judeo-Arabic","jrb",""} ,
1411 : { "Judeo-Persian","jpr",""} ,
1412 : { "Kabardian","kbd",""} ,
1413 : { "Kabyle","kab",""} ,
1414 : { "Kachin; Jingpho","kac",""} ,
1415 : { "Kalaallisut; Greenlandic","kal","kl"} ,
1416 : { "Kalmyk; Oirat","xal",""} ,
1417 : { "Kamba","kam",""} ,
1418 : { "Kannada","kan","kn"} ,
1419 : { "Kanuri","kau","kr"} ,
1420 : { "Kara-Kalpak","kaa",""} ,
1421 : { "Karachay-Balkar","krc",""} ,
1422 : { "Karelian","krl",""} ,
1423 : { "Karen languages","kar",""} ,
1424 : { "Kashmiri","kas","ks"} ,
1425 : { "Kashubian","csb",""} ,
1426 : { "Kawi","kaw",""} ,
1427 : { "Kazakh","kaz","kk"} ,
1428 : { "Khasi","kha",""} ,
1429 : { "Khoisan languages","khi",""} ,
1430 : { "Khotanese; Sakan","kho",""} ,
1431 : { "Kikuyu; Gikuyu","kik","ki"} ,
1432 : { "Kimbundu","kmb",""} ,
1433 : { "Kinyarwanda","kin","rw"} ,
1434 : { "Kirghiz; Kyrgyz","kir","ky"} ,
1435 : { "Klingon; tlhIngan-Hol","tlh",""} ,
1436 : { "Komi","kom","kv"} ,
1437 : { "Kongo","kon","kg"} ,
1438 : { "Konkani","kok",""} ,
1439 : { "Korean","kor","ko"} ,
1440 : { "Kosraean","kos",""} ,
1441 : { "Kpelle","kpe",""} ,
1442 : { "Kru languages","kro",""} ,
1443 : { "Kuanyama; Kwanyama","kua","kj"} ,
1444 : { "Kumyk","kum",""} ,
1445 : { "Kurdish","kur","ku"} ,
1446 : { "Kurukh","kru",""} ,
1447 : { "Kutenai","kut",""} ,
1448 : { "Ladino","lad",""} ,
1449 : { "Lahnda","lah",""} ,
1450 : { "Lamba","lam",""} ,
1451 : { "Land Dayak languages","day",""} ,
1452 : { "Lao","lao","lo"} ,
1453 : { "Latin","lat","la"} ,
1454 : { "Latvian","lav","lv"} ,
1455 : { "Lezghian","lez",""} ,
1456 : { "Limburgan; Limburger; Limburgish","lim","li"} ,
1457 : { "Lingala","lin","ln"} ,
1458 : { "Lithuanian","lit","lt"} ,
1459 : { "Lojban","jbo",""} ,
1460 : { "Low German; Low Saxon; German, Low; Saxon, Low","nds",""} ,
1461 : { "Lower Sorbian","dsb",""} ,
1462 : { "Lozi","loz",""} ,
1463 : { "Luba-Katanga","lub","lu"} ,
1464 : { "Luba-Lulua","lua",""} ,
1465 : { "Luiseno","lui",""} ,
1466 : { "Lule Sami","smj",""} ,
1467 : { "Lunda","lun",""} ,
1468 : { "Luo (Kenya and Tanzania)","luo",""} ,
1469 : { "Lushai","lus",""} ,
1470 : { "Luxembourgish; Letzeburgesch","ltz","lb"} ,
1471 : { "Macedonian","mkd","mk"} ,
1472 : { "Madurese","mad",""} ,
1473 : { "Magahi","mag",""} ,
1474 : { "Maithili","mai",""} ,
1475 : { "Makasar","mak",""} ,
1476 : { "Malagasy","mlg","mg"} ,
1477 : { "Malay","msa","ms"} ,
1478 : { "Malayalam","mal","ml"} ,
1479 : { "Maltese","mlt","mt"} ,
1480 : { "Manchu","mnc",""} ,
1481 : { "Mandar","mdr",""} ,
1482 : { "Mandingo","man",""} ,
1483 : { "Manipuri","mni",""} ,
1484 : { "Manobo languages","mno",""} ,
1485 : { "Manx","glv","gv"} ,
1486 : { "Maori","mri","mi"} ,
1487 : { "Mapudungun; Mapuche","arn",""} ,
1488 : { "Marathi","mar","mr"} ,
1489 : { "Mari","chm",""} ,
1490 : { "Marshallese","mah","mh"} ,
1491 : { "Marwari","mwr",""} ,
1492 : { "Masai","mas",""} ,
1493 : { "Mayan languages","myn",""} ,
1494 : { "Mende","men",""} ,
1495 : { "Mi'kmaq; Micmac","mic",""} ,
1496 : { "Minangkabau","min",""} ,
1497 : { "Mirandese","mwl",""} ,
1498 : { "Mohawk","moh",""} ,
1499 : { "Moksha","mdf",""} ,
1500 : { "Mon-Khmer languages","mkh",""} ,
1501 : { "Mongo","lol",""} ,
1502 : { "Mongolian","mon","mn"} ,
1503 : { "Mossi","mos",""} ,
1504 : { "Multiple languages","mul",""} ,
1505 : { "Munda languages","mun",""} ,
1506 : { "N'Ko","nqo",""} ,
1507 : { "Nahuatl languages","nah",""} ,
1508 : { "Nauru","nau","na"} ,
1509 : { "Navajo; Navaho","nav","nv"} ,
1510 : { "Ndebele, North; North Ndebele","nde","nd"} ,
1511 : { "Ndebele, South; South Ndebele","nbl","nr"} ,
1512 : { "Ndonga","ndo","ng"} ,
1513 : { "Neapolitan","nap",""} ,
1514 : { "Nepal Bhasa; Newari","new",""} ,
1515 : { "Nepali","nep","ne"} ,
1516 : { "Nias","nia",""} ,
1517 : { "Niger-Kordofanian languages","nic",""} ,
1518 : { "Nilo-Saharan languages","ssa",""} ,
1519 : { "Niuean","niu",""} ,
1520 : { "No linguistic content; Not applicable","zxx",""} ,
1521 : { "Nogai","nog",""} ,
1522 : { "Norse, Old","non",""} ,
1523 : { "North American Indian languages","nai",""} ,
1524 : { "Northern Frisian","frr",""} ,
1525 : { "Northern Sami","sme","se"} ,
1526 : { "Norwegian","nor","no"} ,
1527 : { "Norwegian Nynorsk; Nynorsk, Norwegian","nno","nn"} ,
1528 : { "Nubian languages","nub",""} ,
1529 : { "Nyamwezi","nym",""} ,
1530 : { "Nyankole","nyn",""} ,
1531 : { "Nyoro","nyo",""} ,
1532 : { "Nzima","nzi",""} ,
1533 : { "Occitan (post 1500)","oci","oc"} ,
1534 : { "Official Aramaic (700-300 BCE); Imperial Aramaic (700-300 BCE)","arc",""} ,
1535 : { "Ojibwa","oji","oj"} ,
1536 : { "Oriya","ori","or"} ,
1537 : { "Oromo","orm","om"} ,
1538 : { "Osage","osa",""} ,
1539 : { "Ossetian; Ossetic","oss","os"} ,
1540 : { "Otomian languages","oto",""} ,
1541 : { "Pahlavi","pal",""} ,
1542 : { "Palauan","pau",""} ,
1543 : { "Pali","pli","pi"} ,
1544 : { "Pampanga; Kapampangan","pam",""} ,
1545 : { "Pangasinan","pag",""} ,
1546 : { "Panjabi; Punjabi","pan","pa"} ,
1547 : { "Papiamento","pap",""} ,
1548 : { "Papuan languages","paa",""} ,
1549 : { "Pedi; Sepedi; Northern Sotho","nso",""} ,
1550 : { "Persian","fas","fa"} ,
1551 : { "Persian, Old (ca.600-400 B.C.)","peo",""} ,
1552 : { "Philippine languages","phi",""} ,
1553 : { "Phoenician","phn",""} ,
1554 : { "Pohnpeian","pon",""} ,
1555 : { "Polish","pol","pl"} ,
1556 : { "Portuguese","por","pt"} ,
1557 : { "Prakrit languages","pra",""} ,
1558 : { "Provencal, Old (to 1500);Occitan, Old (to 1500)","pro",""} ,
1559 : { "Pushto; Pashto","pus","ps"} ,
1560 : { "Quechua","que","qu"} ,
1561 : { "Rajasthani","raj",""} ,
1562 : { "Rapanui","rap",""} ,
1563 : { "Rarotongan; Cook Islands Maori","rar",""} ,
1564 : { "Reserved for local use","qaa-qtz",""} ,
1565 : { "Romance languages","roa",""} ,
1566 : { "Romanian; Moldavian; Moldovan","ron","ro"} ,
1567 : { "Romansh","roh","rm"} ,
1568 : { "Romany","rom",""} ,
1569 : { "Rundi","run","rn"} ,
1570 : { "Russian","rus","ru"} ,
1571 : { "Salishan languages","sal",""} ,
1572 : { "Samaritan Aramaic","sam",""} ,
1573 : { "Sami languages","smi",""} ,
1574 : { "Samoan","smo","sm"} ,
1575 : { "Sandawe","sad",""} ,
1576 : { "Sango","sag","sg"} ,
1577 : { "Sanskrit","san","sa"} ,
1578 : { "Santali","sat",""} ,
1579 : { "Sardinian","srd","sc"} ,
1580 : { "Sasak","sas",""} ,
1581 : { "Scots","sco",""} ,
1582 : { "Selkup","sel",""} ,
1583 : { "Semitic languages","sem",""} ,
1584 : { "Serbian","srp","sr"} ,
1585 : { "Serer","srr",""} ,
1586 : { "Shan","shn",""} ,
1587 : { "Shona","sna","sn"} ,
1588 : { "Sichuan Yi; Nuosu","iii","ii"} ,
1589 : { "Sicilian","scn",""} ,
1590 : { "Sidamo","sid",""} ,
1591 : { "Sign Languages","sgn",""} ,
1592 : { "Siksika","bla",""} ,
1593 : { "Sindhi","snd","sd"} ,
1594 : { "Sinhala; Sinhalese","sin","si"} ,
1595 : { "Sino-Tibetan languages","sit",""} ,
1596 : { "Siouan languages","sio",""} ,
1597 : { "Skolt Sami","sms",""} ,
1598 : { "Slave (Athapascan)","den",""} ,
1599 : { "Slavic languages","sla",""} ,
1600 : { "Slovak","slk","sk"} ,
1601 : { "Slovenian","slv","sl"} ,
1602 : { "Sogdian","sog",""} ,
1603 : { "Somali","som","so"} ,
1604 : { "Songhai languages","son",""} ,
1605 : { "Soninke","snk",""} ,
1606 : { "Sorbian languages","wen",""} ,
1607 : { "Sotho, Southern","sot","st"} ,
1608 : { "South American Indian languages","sai",""} ,
1609 : { "Southern Altai","alt",""} ,
1610 : { "Southern Sami","sma",""} ,
1611 : { "Spanish; Castilian","spa","es"} ,
1612 : { "Sranan Tongo","srn",""} ,
1613 : { "Sukuma","suk",""} ,
1614 : { "Sumerian","sux",""} ,
1615 : { "Sundanese","sun","su"} ,
1616 : { "Susu","sus",""} ,
1617 : { "Swahili","swa","sw"} ,
1618 : { "Swati","ssw","ss"} ,
1619 : { "Swedish","swe","sv"} ,
1620 : { "Swiss German; Alemannic; Alsatian","gsw",""} ,
1621 : { "Syriac","syr",""} ,
1622 : { "Tagalog","tgl","tl"} ,
1623 : { "Tahitian","tah","ty"} ,
1624 : { "Tai languages","tai",""} ,
1625 : { "Tajik","tgk","tg"} ,
1626 : { "Tamashek","tmh",""} ,
1627 : { "Tamil","tam","ta"} ,
1628 : { "Tatar","tat","tt"} ,
1629 : { "Telugu","tel","te"} ,
1630 : { "Tereno","ter",""} ,
1631 : { "Tetum","tet",""} ,
1632 : { "Thai","tha","th"} ,
1633 : { "Tibetan","bod","bo"} ,
1634 : { "Tigre","tig",""} ,
1635 : { "Tigrinya","tir","ti"} ,
1636 : { "Timne","tem",""} ,
1637 : { "Tiv","tiv",""} ,
1638 : { "Tlingit","tli",""} ,
1639 : { "Tok Pisin","tpi",""} ,
1640 : { "Tokelau","tkl",""} ,
1641 : { "Tonga (Nyasa)","tog",""} ,
1642 : { "Tonga (Tonga Islands)","ton","to"} ,
1643 : { "Tsimshian","tsi",""} ,
1644 : { "Tsonga","tso","ts"} ,
1645 : { "Tswana","tsn","tn"} ,
1646 : { "Tumbuka","tum",""} ,
1647 : { "Tupi languages","tup",""} ,
1648 : { "Turkish","tur","tr"} ,
1649 : { "Turkish, Ottoman (1500-1928)","ota",""} ,
1650 : { "Turkmen","tuk","tk"} ,
1651 : { "Tuvalu","tvl",""} ,
1652 : { "Tuvinian","tyv",""} ,
1653 : { "Twi","twi","tw"} ,
1654 : { "Udmurt","udm",""} ,
1655 : { "Ugaritic","uga",""} ,
1656 : { "Uighur; Uyghur","uig","ug"} ,
1657 : { "Ukrainian","ukr","uk"} ,
1658 : { "Umbundu","umb",""} ,
1659 : { "Uncoded languages","mis",""} ,
1660 : { "Undetermined","und",""} ,
1661 : { "Upper Sorbian","hsb",""} ,
1662 : { "Urdu","urd","ur"} ,
1663 : { "Uzbek","uzb","uz"} ,
1664 : { "Vai","vai",""} ,
1665 : { "Venda","ven","ve"} ,
1666 : { "Vietnamese","vie","vi"} ,
1667 : { "Volapuk","vol","vo"} ,
1668 : { "Votic","vot",""} ,
1669 : { "Wakashan languages","wak",""} ,
1670 : { "Walloon","wln","wa"} ,
1671 : { "Waray","war",""} ,
1672 : { "Washo","was",""} ,
1673 : { "Welsh","cym","cy"} ,
1674 : { "Western Frisian","fry","fy"} ,
1675 : { "Wolaitta; Wolaytta","wal",""} ,
1676 : { "Wolof","wol","wo"} ,
1677 : { "Xhosa","xho","xh"} ,
1678 : { "Yakut","sah",""} ,
1679 : { "Yao","yao",""} ,
1680 : { "Yapese","yap",""} ,
1681 : { "Yiddish","yid","yi"} ,
1682 : { "Yoruba","yor","yo"} ,
1683 : { "Yupik languages","ypk",""} ,
1684 : { "Zande languages","znd",""} ,
1685 : { "Zapotec","zap",""} ,
1686 : { "Zaza; Dimili; Dimli; Kirdki; Kirmanjki; Zazaki","zza",""} ,
1687 : { "Zenaga","zen",""} ,
1688 : { "Zhuang; Chuang","zha","za"} ,
1689 : { "Zulu","zul","zu"} ,
1690 : { "Zuni","zun",""} ,
1691 : };
1692 :
1693 :
1694 : GF_EXPORT
1695 2 : u32 gf_lang_get_count()
1696 : {
1697 2 : return sizeof(defined_languages) / sizeof(struct lang_def);
1698 : }
1699 :
1700 : GF_EXPORT
1701 672 : s32 gf_lang_find(const char *lang_or_rfc_5646_code)
1702 : {
1703 : //find the language ISO639 entry for the given code
1704 : u32 i=0;
1705 : u32 len=0;
1706 : char *sep;
1707 : u32 count = sizeof(defined_languages) / sizeof(struct lang_def);
1708 :
1709 672 : if (!lang_or_rfc_5646_code) return -1;
1710 :
1711 672 : len = (u32)strlen(lang_or_rfc_5646_code);
1712 672 : sep = (char *) strchr(lang_or_rfc_5646_code, '-');
1713 672 : if (sep) {
1714 23 : sep[0] = 0;
1715 23 : len = (u32) strlen(lang_or_rfc_5646_code);
1716 23 : sep[0] = '-';
1717 : }
1718 :
1719 187384 : for (i=0; i<count; i++) {
1720 187384 : if (!strcmp(defined_languages[i].name, lang_or_rfc_5646_code)) {
1721 0 : return i;
1722 : }
1723 187384 : if ((len==3) && !strnicmp(defined_languages[i].three_char_code, lang_or_rfc_5646_code, 3)) {
1724 478 : return i;
1725 : }
1726 186906 : if ((len==2) && !strnicmp(defined_languages[i].two_char_code, lang_or_rfc_5646_code, 2)) {
1727 194 : return i;
1728 : }
1729 : }
1730 : return -1;
1731 : }
1732 :
1733 : GF_EXPORT
1734 704 : const char *gf_lang_get_name(u32 idx)
1735 : {
1736 704 : if (idx>=sizeof(defined_languages) / sizeof(struct lang_def)) return NULL;
1737 704 : return defined_languages[idx].name;
1738 : }
1739 :
1740 : GF_EXPORT
1741 1090 : const char *gf_lang_get_2cc(u32 idx)
1742 : {
1743 1090 : if (idx>=sizeof(defined_languages) / sizeof(struct lang_def)) return NULL;
1744 1090 : return defined_languages[idx].two_char_code;
1745 : }
1746 :
1747 : GF_EXPORT
1748 637 : const char *gf_lang_get_3cc(u32 idx)
1749 : {
1750 637 : if (idx>=sizeof(defined_languages) / sizeof(struct lang_def)) return NULL;
1751 637 : return defined_languages[idx].three_char_code;
1752 : }
1753 :
1754 : GF_EXPORT
1755 21929 : GF_Err gf_blob_get(const char *blob_url, u8 **out_data, u32 *out_size, u32 *out_flags)
1756 : {
1757 21929 : GF_Blob *blob = NULL;
1758 21929 : if (strncmp(blob_url, "gmem://", 7)) return GF_BAD_PARAM;
1759 21929 : if (sscanf(blob_url, "gmem://%p", &blob) != 1) return GF_BAD_PARAM;
1760 21929 : if (!blob) return GF_BAD_PARAM;
1761 21929 : if (out_data) *out_data = blob->data;
1762 21929 : if (out_size) *out_size = blob->size;
1763 21929 : if (out_flags) *out_flags = blob->flags;
1764 21929 : if (blob->data && blob->mx)
1765 21918 : gf_mx_p(blob->mx);
1766 : return GF_OK;
1767 : }
1768 :
1769 : GF_EXPORT
1770 21928 : GF_Err gf_blob_release(const char *blob_url)
1771 : {
1772 21928 : GF_Blob *blob = NULL;
1773 21928 : if (strncmp(blob_url, "gmem://", 7)) return GF_BAD_PARAM;
1774 21928 : if (sscanf(blob_url, "gmem://%p", &blob) != 1) return GF_BAD_PARAM;
1775 21928 : if (!blob) return GF_BAD_PARAM;
1776 21928 : if (blob->data && blob->mx)
1777 21918 : gf_mx_v(blob->mx);
1778 : return GF_OK;
1779 : }
1780 :
1781 : GF_EXPORT
1782 199243 : GF_Err gf_dynstrcat(char **str, const char *to_append, const char *sep)
1783 : {
1784 : u32 l1, l2, lsep;
1785 199243 : if (!to_append) return GF_OK;
1786 :
1787 190749 : lsep = sep ? (u32) strlen(sep) : 0;
1788 190749 : l1 = *str ? (u32) strlen(*str) : 0;
1789 190749 : l2 = (u32) strlen(to_append);
1790 190749 : if (l1) (*str) = gf_realloc((*str), sizeof(char)*(l1+l2+lsep+1));
1791 16354 : else (*str) = gf_realloc((*str), sizeof(char)*(l2+lsep+1));
1792 :
1793 190749 : if (! (*str) )
1794 : return GF_OUT_OF_MEM;
1795 :
1796 190749 : (*str)[l1]=0;
1797 190749 : if (l1 && sep) strcat((*str), sep);
1798 190749 : strcat((*str), to_append);
1799 190749 : return GF_OK;
1800 : }
1801 :
1802 : GF_EXPORT
1803 13196 : Bool gf_parse_lfrac(const char *value, GF_Fraction64 *frac)
1804 : {
1805 : Float v;
1806 : u32 len, i;
1807 : Bool all_num=GF_TRUE;
1808 : char *sep;
1809 13196 : if (!frac) return GF_FALSE;
1810 13196 : frac->num = 0;
1811 13196 : frac->den = 0;
1812 13196 : if (!value) return GF_FALSE;
1813 :
1814 13190 : if (sscanf(value, LLD"/"LLU, &frac->num, &frac->den) == 2) {
1815 : return GF_TRUE;
1816 : }
1817 8710 : if (sscanf(value, LLD"-"LLU, &frac->num, &frac->den) == 2) {
1818 : return GF_TRUE;
1819 : }
1820 5780 : if (sscanf(value, "%g", &v) != 1) {
1821 6 : frac->num = 0;
1822 6 : frac->den = 0;
1823 6 : return GF_FALSE;
1824 : }
1825 5774 : sep = strchr(value, '.');
1826 5774 : if (!sep) sep = strchr(value, ',');
1827 5774 : if (!sep) {
1828 5446 : frac->num = atoi(value);
1829 5446 : frac->den = 1;
1830 5446 : return GF_TRUE;
1831 : }
1832 :
1833 328 : len = (u32) strlen(sep+1);
1834 695 : for (i=1; i<=len; i++) {
1835 367 : if ((sep[i]<'0') || (sep[i]>'9')) {
1836 : all_num = GF_FALSE;
1837 : break;
1838 : }
1839 : }
1840 328 : if (all_num) {
1841 : u32 div_trail_zero = 1;
1842 328 : sscanf(value, LLD"."LLU, &frac->num, &frac->den);
1843 :
1844 : i=0;
1845 328 : frac->den = 1;
1846 1023 : while (i<len) {
1847 367 : i++;
1848 367 : frac->den *= 10;
1849 : }
1850 : //trash trailing zero
1851 : i=len;
1852 331 : while (i>0) {
1853 328 : if (sep[i] != '0') {
1854 : break;
1855 : }
1856 3 : div_trail_zero *= 10;
1857 3 : i--;
1858 : }
1859 :
1860 :
1861 328 : frac->num *= frac->den / div_trail_zero;
1862 328 : frac->num += atoi(sep+1) / div_trail_zero;
1863 328 : frac->den /= div_trail_zero;
1864 :
1865 328 : return GF_TRUE;
1866 : }
1867 :
1868 : sep += 1;
1869 0 : if (len <= 3) frac->den = 1000;
1870 0 : else if (len <= 6) frac->den = 1000000;
1871 0 : else frac->den = 1000000000;
1872 :
1873 0 : frac->num = (u64)( (atof(value) * frac->den) + 0.5 );
1874 0 : return GF_TRUE;
1875 : }
1876 :
1877 : GF_EXPORT
1878 8331 : Bool gf_parse_frac(const char *value, GF_Fraction *frac)
1879 : {
1880 : GF_Fraction64 r;
1881 : Bool res;
1882 8331 : if (!frac) return GF_FALSE;
1883 8331 : res = gf_parse_lfrac(value, &r);
1884 16662 : while ((r.num >= 0x80000000) && (r.den > 1000)) {
1885 0 : r.num /= 1000;
1886 0 : r.den /= 1000;
1887 : }
1888 8331 : frac->num = (s32) r.num;
1889 8331 : frac->den = (u32) r.den;
1890 8331 : return res;
1891 : }
|