1 /*
2 * GPAC - Multimedia Framework C SDK
3 *
4 * Authors: Cyril Concolato
5 * Copyright (c) Telecom ParisTech 2006-2012
6 * All rights reserved
7 *
8 * This file is part of GPAC / load&compare application
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 #include <gpac/scene_manager.h>
26 #include <zlib.h>
27
28 enum {
29 SVG = 0,
30 XMT = 1,
31 };
32
33 typedef struct {
34 char filename[100];
35 u32 size;
36 u32 gpacxml_loadtime;
37 u32 libxml_loadtime;
38 u32 gz_size;
39 u32 gpacxml_gz_loadtime;
40 u32 libxml_gz_loadtime;
41 u32 track_size;
42 u32 track_loadtime;
43 u32 decoded_size;
44 u32 decoded_loadtime;
45 } LoadData;
46
47 typedef struct {
48 FILE *out;
49 u32 type;
50 u32 nbloads;
51 u32 verbose;
52 Bool regenerate;
53 Bool spread_repeat;
54 u32 repeat_index;
55 GF_List *data;
56 } GF_LoadCompare;
57
load_mp4(GF_LoadCompare * lc,GF_ISOFile * mp4,u32 * loadtime)58 GF_Err load_mp4(GF_LoadCompare *lc, GF_ISOFile *mp4, u32 *loadtime)
59 {
60 GF_Err e = GF_OK;
61 GF_SceneLoader load;
62 u32 i, starttime, endtime;
63 u32 nb;
64 if (lc->spread_repeat) nb = 1;
65 else nb = lc->nbloads ;
66
67 *loadtime = 0;
68 for (i = 0; i< nb; i++) {
69 GF_SceneGraph *sg;
70 memset(&load, 0, sizeof(GF_SceneLoader));
71 sg = gf_sg_new();
72 load.ctx = gf_sm_new(sg);
73
74 load.isom = mp4;
75 starttime = gf_sys_clock();
76
77 e = gf_sm_load_init(&load);
78 if (e) {
79 fprintf(stderr, "Error loading MP4 file\n");
80 } else {
81 e = gf_sm_load_run(&load);
82 if (e) {
83 fprintf(stderr, "Error loading MP4 file\n");
84 } else {
85 endtime = gf_sys_clock();
86 *loadtime += endtime-starttime;
87 }
88 gf_sm_load_done(&load);
89 }
90 gf_sm_del(load.ctx);
91 gf_sg_del(sg);
92 }
93 return e;
94 }
95
load_progress(void * cbk,u32 done,u32 total)96 void load_progress(void *cbk, u32 done, u32 total) {
97 fprintf(stdout, "%d/%d\r", done, total);
98 }
99
gpacctx_load_file(GF_LoadCompare * lc,char * item_path,u32 * loadtime)100 GF_Err gpacctx_load_file(GF_LoadCompare *lc, char *item_path, u32 *loadtime)
101 {
102 GF_Err e = GF_OK;
103 GF_SceneLoader load;
104 u32 i, starttime, endtime;
105
106 u32 nb;
107 if (lc->spread_repeat) nb = 1;
108 else nb = lc->nbloads ;
109
110 *loadtime = 0;
111
112 for (i = 0; i<nb; i++) {
113 GF_SceneGraph *sg;
114 memset(&load, 0, sizeof(GF_SceneLoader));
115 sg = gf_sg_new();
116 load.ctx = gf_sm_new(sg);
117 load.OnProgress = load_progress;
118
119 load.fileName = item_path;
120 starttime = gf_sys_clock();
121
122 e = gf_sm_load_init(&load);
123 if (e) {
124 fprintf(stderr, "Error loading file %s\n", item_path);
125 } else {
126 e = gf_sm_load_run(&load);
127 if (e) {
128 fprintf(stderr, "Error loading file %s\n", item_path);
129 } else {
130 endtime = gf_sys_clock();
131 *loadtime += endtime-starttime;
132 }
133 gf_sm_load_done(&load);
134 }
135 gf_sm_del(load.ctx);
136 gf_sg_del(sg);
137 }
138 return e;
139 }
140
get_laser_track_size(GF_ISOFile * mp4,u32 * size)141 GF_Err get_laser_track_size(GF_ISOFile *mp4, u32 *size)
142 {
143 GF_Err e = GF_OK;
144 u32 j;
145 u32 track_id, trackNum;
146
147 *size = 0;
148 track_id = gf_isom_get_track_id(mp4, 1);
149 trackNum = gf_isom_get_track_by_id(mp4, track_id);
150 for (j=0; j<gf_isom_get_sample_count(mp4, trackNum); j++) {
151 GF_ISOSample *samp = gf_isom_get_sample_info(mp4, trackNum, j+1, NULL, NULL);
152 *size += samp->dataLength;
153 gf_isom_sample_del(&samp);
154 }
155 return e;
156 }
157
encode_laser(GF_LoadCompare * lc,char * item_path,GF_ISOFile * mp4,GF_SMEncodeOptions * opts)158 GF_Err encode_laser(GF_LoadCompare *lc, char *item_path, GF_ISOFile *mp4, GF_SMEncodeOptions *opts)
159 {
160 GF_Err e = GF_OK;
161 GF_SceneLoader load;
162 GF_SceneManager *ctx;
163 GF_SceneGraph *sg;
164 GF_StatManager *statsman = NULL;
165
166 memset(&load, 0, sizeof(GF_SceneLoader));
167 sg = gf_sg_new();
168 ctx = gf_sm_new(sg);
169 load.ctx = ctx;
170 load.fileName = item_path;
171
172 e = gf_sm_load_init(&load);
173 if (e) {
174 fprintf(stderr, "Error loading file %s\n", item_path);
175 } else {
176 e = gf_sm_load_run(&load);
177 if (e) {
178 fprintf(stderr, "Error loading file %s\n", item_path);
179 } else {
180 if (opts->auto_qant) {
181 if (lc->verbose) fprintf(stdout, "Analysing Scene for Automatic Quantization\n");
182 statsman = gf_sm_stats_new();
183 e = gf_sm_stats_for_scene(statsman, ctx);
184 if (!e) {
185 GF_SceneStatistics *stats = gf_sm_stats_get(statsman);
186 if (opts->resolution > (s32)stats->frac_res_2d) {
187 if (lc->verbose) fprintf(stdout, " Given resolution %d is (unnecessarily) too high, using %d instead.\n", opts->resolution, stats->frac_res_2d);
188 opts->resolution = stats->frac_res_2d;
189 } else if (stats->int_res_2d + opts->resolution <= 0) {
190 if (lc->verbose) fprintf(stdout, " Given resolution %d is too low, using %d instead.\n", opts->resolution, stats->int_res_2d - 1);
191 opts->resolution = 1 - stats->int_res_2d;
192 }
193 opts->coord_bits = stats->int_res_2d + opts->resolution;
194 if (lc->verbose) fprintf(stdout, " Coordinates & Lengths encoded using ");
195 if (opts->resolution < 0) {
196 if (lc->verbose) fprintf(stdout, "only the %d most significant bits (of %d).\n", opts->coord_bits, stats->int_res_2d);
197 } else {
198 if (lc->verbose) fprintf(stdout, "a %d.%d representation\n", stats->int_res_2d, opts->resolution);
199 }
200
201 if (lc->verbose) fprintf(stdout, " Matrix Scale & Skew Coefficients ");
202 if (opts->coord_bits < stats->scale_int_res_2d) {
203 opts->scale_bits = stats->scale_int_res_2d - opts->coord_bits;
204 if (lc->verbose) fprintf(stdout, "encoded using a %d.8 representation\n", stats->scale_int_res_2d);
205 } else {
206 opts->scale_bits = 0;
207 if (lc->verbose) fprintf(stdout, "not encoded.\n");
208 }
209 }
210 gf_sm_stats_del(statsman);
211 }
212
213 e = gf_sm_encode_to_file(ctx, mp4, opts);
214 if (e) {
215 fprintf(stderr, "Error while encoding mp4 file\n");
216 } else {
217 e = gf_isom_set_brand_info(mp4, GF_ISOM_BRAND_MP42, 1);
218 if (!e) e = gf_isom_modify_alternate_brand(mp4, GF_ISOM_BRAND_ISOM, 1);
219 }
220
221 gf_sm_load_done(&load);
222 }
223 }
224 gf_sm_del(ctx);
225 gf_sg_del(sg);
226
227 return e;
228 }
229
create_laser_mp4(GF_LoadCompare * lc,char * item_name,char * item_path,u32 * size)230 GF_Err create_laser_mp4(GF_LoadCompare *lc, char *item_name, char *item_path, u32 *size)
231 {
232 char mp4_path[100], *ext;
233 GF_Err e = GF_OK;
234 GF_ISOFile *mp4;
235
236 *size = 0;
237
238 strcpy(mp4_path, item_name);
239 ext = strrchr(mp4_path, '.');
240 strcpy(ext, ".mp4");
241 mp4 = gf_isom_open(mp4_path, GF_ISOM_WRITE_EDIT, NULL);
242 if (!mp4) {
243 if (lc->verbose) fprintf(stdout, "Could not open file %s for writing\n", mp4_path);
244 e = GF_IO_ERR;
245 } else {
246 GF_SMEncodeOptions opts;
247 memset(&opts, 0, sizeof(GF_SMEncodeOptions));
248 opts.auto_qant = 1;
249 opts.resolution = 8;
250 e = encode_laser(lc, item_path, mp4, &opts);
251 if (e) {
252 if (lc->verbose) fprintf(stdout, "Could not encode MP4 file from %s\n", item_path);
253 gf_isom_delete(mp4);
254 } else {
255 gf_isom_close(mp4);
256
257 mp4 = gf_isom_open(mp4_path, GF_ISOM_OPEN_READ, NULL);
258 if (!mp4) {
259 if (lc->verbose) fprintf(stdout, "Could not open file %s for reading\n", mp4_path);
260 e = GF_IO_ERR;
261 } else {
262 e = get_laser_track_size(mp4, size);
263 if (e) {
264 if (lc->verbose) fprintf(stdout, "Could not get MP4 file size\n");
265 }
266 gf_isom_close(mp4);
267 }
268 }
269 }
270 return e;
271 }
272
273
get_mp4_loadtime(GF_LoadCompare * lc,char * item_name,char * item_path,u32 * loadtime)274 GF_Err get_mp4_loadtime(GF_LoadCompare *lc, char *item_name, char *item_path, u32 *loadtime)
275 {
276 char mp4_path[100], *ext;
277 GF_Err e = GF_OK;
278 GF_ISOFile *mp4;
279
280 *loadtime = 0;
281
282 strcpy(mp4_path, item_name);
283 ext = strrchr(mp4_path, '.');
284 strcpy(ext, ".mp4");
285 mp4 = gf_isom_open(mp4_path, GF_ISOM_OPEN_READ, NULL);
286 if (!mp4) {
287 if (lc->verbose) fprintf(stdout, "Could not open file %s for reading\n", mp4_path);
288 e = GF_IO_ERR;
289 } else {
290 e = load_mp4(lc, mp4, loadtime);
291 if (e) {
292 if (lc->verbose) fprintf(stdout, "Could not get MP4 file load time\n");
293 }
294 }
295 gf_isom_close(mp4);
296 return e;
297 }
298
decode_svg(GF_LoadCompare * lc,char * item_name,char * item_path,char * svg_out_path)299 GF_Err decode_svg(GF_LoadCompare *lc, char *item_name, char *item_path, char *svg_out_path)
300 {
301 GF_SceneManager *ctx;
302 GF_SceneLoader load;
303 GF_ISOFile *mp4;
304 GF_Err e = GF_OK;
305 char mp4_path[256];
306 char *ext;
307
308 strcpy(mp4_path, item_name);
309 ext = strrchr(mp4_path, '.');
310 strcpy(ext, ".mp4");
311 mp4 = gf_isom_open(mp4_path, GF_ISOM_OPEN_READ, NULL);
312 if (!mp4) {
313 if (lc->verbose) fprintf(stdout, "Could not open file %s\n", mp4_path);
314 e = GF_IO_ERR;
315 } else {
316 GF_SceneGraph *sg;
317 sg = gf_sg_new();
318 ctx = gf_sm_new(sg);
319 memset(&load, 0, sizeof(GF_SceneLoader));
320 load.isom = mp4;
321 load.ctx = ctx;
322 e = gf_sm_load_init(&load);
323 if (e) {
324 fprintf(stderr, "Error loading MP4 file\n");
325 } else {
326 e = gf_sm_load_run(&load);
327 if (e) {
328 fprintf(stderr, "Error loading MP4 file\n");
329 } else {
330 gf_sm_load_done(&load);
331
332 ext = strrchr(svg_out_path, '.');
333 ext[0] = 0;
334 e = gf_sm_dump(ctx, svg_out_path, GF_SM_DUMP_SVG);
335 if (e) {
336 fprintf(stderr, "Error dumping SVG from MP4 file\n");
337 }
338 }
339 }
340 gf_sm_del(ctx);
341 gf_sg_del(sg);
342 gf_isom_close(mp4);
343 }
344 return e;
345 }
346
libxml_load_svg(GF_LoadCompare * lc,char * item_path,u32 * loadtime)347 GF_Err libxml_load_svg(GF_LoadCompare *lc, char *item_path, u32 *loadtime)
348 {
349 GF_Err e = GF_OK;
350 u32 i, starttime, endtime;
351
352 u32 nb;
353 if (lc->spread_repeat) nb = 1;
354 else nb = lc->nbloads ;
355
356 *loadtime = 0;
357
358 for (i = 0; i<nb; i++) {
359 void *p;
360 GF_SceneGraph *sg;
361 sg = gf_sg_new();
362
363 starttime = gf_sys_clock();
364
365 p = DANAE_NewSVGParser(item_path, sg);
366 DANAE_SVGParser_Parse(p);
367 DANAE_SVGParser_Terminate();
368
369 endtime = gf_sys_clock();
370 if (lc->verbose) fprintf(stdout, "LibXML single parsing: %d\n", endtime-starttime);
371 *loadtime += endtime-starttime;
372
373 gf_sg_del(sg);
374 }
375 return e;
376 }
377
get_size(GF_LoadCompare * lc,char * item_name,char * item_path,u32 * size)378 GF_Err get_size(GF_LoadCompare *lc, char *item_name, char *item_path, u32 *size)
379 {
380 GF_Err e = GF_OK;
381 FILE *file = NULL;
382
383 *size = 0;
384
385 file = gf_fopen(item_path, "rt");
386 if (!file) {
387 if (lc->verbose) fprintf(stdout, "Could not open file %s\n", item_path);
388 e = GF_IO_ERR;
389 } else {
390 fseek(file, 0, SEEK_END);
391 *size = (u32)ftell(file);
392 gf_fclose(file);
393 if (*size == 0) {
394 if (lc->verbose) fprintf(stdout, "File %s has a size of 0\n", item_path);
395 e = GF_IO_ERR;
396 }
397 }
398 return e;
399 }
400
get_decoded_svg_loadtime_and_size(GF_LoadCompare * lc,char * item_name,char * item_path,u32 * loadtime,u32 * size)401 GF_Err get_decoded_svg_loadtime_and_size(GF_LoadCompare *lc, char *item_name, char *item_path, u32 *loadtime, u32 *size)
402 {
403 GF_Err e = GF_OK;
404 char svg_out_name[256];
405 char *ext;
406
407 strcpy(svg_out_name, item_name);
408 ext = strrchr(svg_out_name, '.');
409 strcpy(ext, "_out.svg");
410
411 *size = 0;
412 *loadtime = 0;
413
414 e = decode_svg(lc, item_name, item_path, svg_out_name);
415 if (!e) {
416 e = get_size(lc, svg_out_name, svg_out_name, size);
417 if (e) {
418 return e;
419 }
420 e = gpacctx_load_file(lc, svg_out_name, loadtime);
421 }
422 return e;
423 }
424
create_gz_file(GF_LoadCompare * lc,char * item_name,char * item_path,u32 * size)425 GF_Err create_gz_file(GF_LoadCompare *lc, char *item_name, char *item_path, u32 *size)
426 {
427 char gz_path[256];
428 GF_Err e = GF_OK;
429 FILE *file = NULL;
430 void *gz = NULL;
431 u32 read;
432
433 *size = 0;
434
435 strcpy(gz_path, item_name);
436 strcat(gz_path, "z");
437 gz = gzopen(gz_path, "wb");
438 file = gf_fopen(item_path, "rt");
439
440 if (!gz || !file) {
441 if (lc->verbose) fprintf(stdout, "Could not open file %s or %s\n", item_path, gz_path);
442 e = GF_IO_ERR;
443 } else {
444 char buffer[100];
445 while ((read = fread(buffer, 1, 100, file))) gzwrite(gz, buffer, read);
446 gf_fclose(file);
447 gzclose(gz);
448 file = gf_fopen(gz_path, "rb");
449 fseek(file, 0, SEEK_END);
450 *size = (u32)ftell(file);
451 gf_fclose(file);
452 if (*size == 0) {
453 if (lc->verbose) fprintf(stdout, "File %s has a size of 0\n", gz_path);
454 e = GF_IO_ERR;
455 }
456 }
457 return e;
458 }
459
get_gz_loadtime(GF_LoadCompare * lc,char * item_name,char * item_path,u32 * loadtime,Bool useLibXML)460 GF_Err get_gz_loadtime(GF_LoadCompare *lc, char *item_name, char *item_path, u32 *loadtime, Bool useLibXML)
461 {
462 char gz_path[256];
463 GF_Err e = GF_OK;
464 *loadtime = 0;
465
466 strcpy(gz_path, item_name);
467 strcat(gz_path, "z");
468
469 if (useLibXML) {
470 e = libxml_load_svg(lc, gz_path, loadtime);
471 } else {
472 e = gpacctx_load_file(lc, gz_path, loadtime);
473 }
474 return e;
475 }
476
print_load_data(GF_LoadCompare * lc,LoadData * ld)477 void print_load_data(GF_LoadCompare *lc, LoadData *ld)
478 {
479 if (lc->verbose) fprintf(stdout, "Processing %s\n", ld->filename);
480 fprintf(lc->out, "%s\t", ld->filename);
481
482 if (lc->verbose) fprintf(stdout, "File Size %d\n", ld->size);
483 fprintf(lc->out, "%d\t", ld->size);
484
485 if (lc->verbose) fprintf(stdout, "GPAC XML Load Time %d\n", ld->gpacxml_loadtime);
486 fprintf(lc->out, "%d\t", ld->gpacxml_loadtime);
487
488 if (lc->verbose) fprintf(stdout, "LibXML Load Time %d \n", ld->libxml_loadtime);
489 fprintf(lc->out, "%d\t", ld->libxml_loadtime);
490
491 if (lc->verbose) fprintf(stdout, "GZ Size %d\n", ld->gz_size);
492 fprintf(lc->out, "%d\t", ld->gz_size);
493
494 if (lc->verbose) fprintf(stdout, "GZ Load Time %d\n", ld->gpacxml_gz_loadtime);
495 fprintf(lc->out, "%d\t", ld->gpacxml_gz_loadtime);
496
497 if (lc->verbose) fprintf(stdout, "LibXML GZ Load Time %d\n", ld->libxml_gz_loadtime);
498 fprintf(lc->out, "%d\t", ld->libxml_gz_loadtime);
499
500 if (lc->verbose) fprintf(stdout, "MP4 Track Size %d\n", ld->track_size);
501 fprintf(lc->out, "%d\t", ld->track_size);
502
503 if (lc->verbose) fprintf(stdout, "MP4 Track Load Time %d\n", ld->track_loadtime);
504 fprintf(lc->out, "%d\t", ld->track_loadtime);
505
506 if (lc->verbose) fprintf(stdout, "Decoded Size %d\n", ld->decoded_size);
507 fprintf(lc->out, "%d\t", ld->decoded_size);
508
509 if (lc->verbose) fprintf(stdout, "Decoded Load Time %d \n", ld->decoded_loadtime);
510 fprintf(lc->out, "%d\t", ld->decoded_loadtime);
511
512 if (lc->verbose) fprintf(stdout, "Done %s\n", ld->filename);
513 fprintf(lc->out, "\n");
514 fflush(lc->out);
515 }
516
loadcompare_one(void * cbck,char * item_name,char * item_path,GF_FileEnumInfo * file_info)517 Bool loadcompare_one(void *cbck, char *item_name, char *item_path, GF_FileEnumInfo *file_info)
518 {
519 GF_Err e;
520 GF_LoadCompare *lc = cbck;
521 u32 loadtime;
522 LoadData *ld;
523
524 if (lc->repeat_index == 0) {
525 GF_SAFEALLOC(ld, sizeof(LoadData));
526 gf_list_add(lc->data, ld);
527 strcpy(ld->filename, item_name);
528
529 e = get_size(lc, item_name, item_path, &ld->size);
530 if (e) return 1;
531
532 e = create_gz_file(lc, item_name, item_path, &ld->gz_size);
533 if (e) return 1;
534
535 e = create_laser_mp4(lc, item_name, item_path, &ld->track_size);
536 if (e) return 1;
537
538 } else {
539 LoadData *tmp;
540 u32 pos = 0;
541 ld = NULL;
542 while (tmp = gf_list_enum(lc->data, &pos)) {
543 if (!strcmp(tmp->filename, item_name)) {
544 ld = tmp;
545 break;
546 }
547 }
548 if (ld == NULL) return 1;
549 }
550
551
552 if (lc->type == SVG) {
553 /* GPAC XML loader */
554 e = gpacctx_load_file(lc, item_path, &loadtime);
555 if (e) return 1;
556 ld->gpacxml_loadtime += loadtime;
557
558 e = get_gz_loadtime(lc, item_name, item_path, &loadtime, 0);
559 if (e) return 1;
560 ld->gpacxml_gz_loadtime += loadtime;
561
562 /* LibXML and LibXML GZ loadings */
563 e = libxml_load_svg(lc, item_path, &loadtime);
564 if (e) return 1;
565 ld->libxml_loadtime += loadtime;
566
567 e = get_gz_loadtime(lc, item_name, item_path, &loadtime, 1);
568 if (e) return 1;
569 ld->libxml_gz_loadtime += loadtime;
570
571 /* MP4 Loading */
572 e = get_mp4_loadtime(lc, item_name, item_path, &loadtime);
573 if (e) return 1;
574 ld->track_loadtime += loadtime;
575
576 /* e = get_decoded_svg_loadtime_and_size(lc, item_name, item_path, &loadtime, &ld->decoded_size);
577 if (e) return 1;
578 ld->decoded_loadtime += loadtime;*/
579
580 } else if (lc->type == XMT) {
581 e = gpacctx_load_file(lc, item_path, &loadtime);
582 if (e) return 1;
583 ld->gpacxml_loadtime += loadtime;
584 }
585
586 if (!lc->spread_repeat) {
587 print_load_data(lc, ld);
588 gf_free(ld);
589 }
590 return 0;
591 }
592
usage()593 void usage()
594 {
595 fprintf(stdout, "Compare LASeR and SVG encoding size and loading time\n");
596 fprintf(stdout, "usage: (-out output_result) (-single input.svg | -dir dir) (-nloads X) (-verbose X)\n");
597 fprintf(stdout, "defaults are: stdout, dir=. and X = 1");
598 }
599
main(int argc,char ** argv)600 int main(int argc, char **argv)
601 {
602 u32 i;
603 GF_LoadCompare lc;
604 Bool single = 0;
605 char *out = NULL;
606 char in[256] = ".";
607
608 fprintf(stdout, "LASeR and SVG Comparison tool\n");
609
610 memset(&lc, 0, sizeof(GF_LoadCompare));
611 lc.nbloads = 1;
612 lc.out = stdout;
613
614 for (i = 1; i < (u32) argc ; i++) {
615 char *arg = argv[i];
616 if (!stricmp(arg, "-out")) {
617 out = argv[i+1];
618 i++;
619 } else if (!stricmp(arg, "-single")) {
620 single = 1;
621 strcpy(in, argv[i+1]);
622 i++;
623 } else if (!stricmp(arg, "-dir")) {
624 strcpy(in, argv[i+1]);
625 i++;
626 } else if (!stricmp(arg, "-nloads")) {
627 lc.nbloads = (u32)atoi(argv[i+1]);
628 i++;
629 } else if (!stricmp(arg, "-regenerate")) {
630 lc.regenerate = 1;
631 } else if (!stricmp(arg, "-xmt")) {
632 lc.type = XMT;
633 } else if (!stricmp(arg, "-svg")) {
634 lc.type = SVG;
635 } else if (!stricmp(arg, "-spread_repeat")) {
636 lc.spread_repeat = 1;
637 } else if (!stricmp(arg, "-verbose")) {
638 lc.verbose = (u32)atoi(argv[i+1]);
639 i++;
640 } else {
641 usage();
642 return -1;
643 }
644 }
645
646 gf_sys_init(GF_MemTrackerNone);
647 if (out) lc.out = gf_fopen(out, "wt");
648 if (!lc.out) {
649 fprintf(stderr, "Cannot open output file %s\n", out);
650 return -1;
651 }
652
653 if (lc.type == SVG) {
654 fprintf(lc.out,"File Name\tSVG Size\tSVG Load Time\tLibXML Load Time\tSVGZ Size\tSVGZ Load Time\tLibXML GZ Load Time\tMP4 Size\tMP4 Load Time\tDecoded SVG Size\tDecoded SVG Load Time\n");
655 } else if (lc.type == XMT) {
656 fprintf(lc.out,"File Name\tXMT Size\tXMT Load Time\tBT Size\tBT Load Time\n");
657 }
658
659 lc.data = gf_list_new();
660
661 if (single) {
662 LoadData *ld;
663 char *tmp = strrchr(in, GF_PATH_SEPARATOR);
664 loadcompare_one(&lc, tmp+1, in);
665 ld = gf_list_get(lc.data, 0);
666 print_load_data(&lc, ld);
667 gf_free(ld);
668 } else {
669 if (lc.spread_repeat) {
670 for (lc.repeat_index = 0; lc.repeat_index < lc.nbloads; lc.repeat_index ++) {
671 if (lc.verbose) fprintf(stdout, "Loop %d\n", lc.repeat_index);
672 if (lc.type == SVG) {
673 gf_enum_directory(in, 0, loadcompare_one, &lc, "svg");
674 } else if (lc.type == XMT) {
675 gf_enum_directory(in, 0, loadcompare_one, &lc, "xmt");
676 }
677 }
678 for (i=0; i<gf_list_count(lc.data); i++) {
679 LoadData *ld = gf_list_get(lc.data, i);
680 print_load_data(&lc, ld);
681 gf_free(ld);
682 }
683 } else {
684 if (lc.type == SVG) {
685 gf_enum_directory(in, 0, loadcompare_one, &lc, "svg");
686 } else if (lc.type == XMT) {
687 gf_enum_directory(in, 0, loadcompare_one, &lc, "xmt");
688 }
689 }
690 }
691 gf_list_del(lc.data);
692
693 if (lc.out) gf_fclose(lc.out);
694 gf_sys_close();
695 return 0;
696 }
697
698