Commit message: fixed #1782 (fuzz)
CVE: CVE-2021-33361
CWE: CWE-787
Vulnerability description: Memory leak in the afra_box_read function in MP4Box in GPAC 1.0.1 allows attackers to read memory via a crafted file.

Project: gpac
File: main.c

u32 parse_dump_udta(char *code, u32 opt)
{
	char *sep;
	sep = strchr(code, ':');
	if (sep) {
		sep[0] = 0;
		dump_udta_track = atoi(code);
		sep[0] = ':';
		code = sep + 1;
	}

	if (strlen(code) == 4) {
		dump_udta_type = GF_4CC(code[0], code[1], code[2], code[3]);
	} else if (strlen(code) == 8) {
		// hex representation on 8 chars
		u32 hex1, hex2, hex3, hex4;
		if (sscanf(code, "%02x%02x%02x%02x", &hex1, &hex2, &hex3, &hex4) != 4) {
			M4_LOG(GF_LOG_ERROR, ("udta code is either a 4CC or 8 hex chars for non-printable 4CC\n"));
			return 2;
		}
		dump_udta_type = GF_4CC(hex1, hex2, hex3, hex4);
	} else {
		M4_LOG(GF_LOG_ERROR, ("udta code is either a 4CC or 8 hex chars for non-printable 4CC\n"));
		return 2;
	}
	return 0;
}

Project: gpac

GF_Err afrt_box_read(GF_Box *s, GF_BitStream *bs)
{
	unsigned int i;
	GF_AdobeFragmentRunTableBox *ptr = (GF_AdobeFragmentRunTableBox *)s;

	ISOM_DECREASE_SIZE(ptr, 5)
	ptr->timescale = gf_bs_read_u32(bs);

	ptr->quality_entry_count = gf_bs_read_u8(bs);
	if (ptr->size < ptr->quality_entry_count)
		return GF_ISOM_INVALID_FILE;

	for (i=0; i<ptr->quality_entry_count; i++) {
		int j=0;
		u32 tmp_strsize=(u32)ptr->size-8;
		char *tmp_str = (char*) gf_malloc(tmp_strsize);
		if (!tmp_str) return GF_OUT_OF_MEM;
		while (tmp_strsize) {
			tmp_str[j] = gf_bs_read_u8(bs);
			tmp_strsize--;
			if (!tmp_str[j])
				break;
			j++;
		}
		ISOM_DECREASE_SIZE(ptr, j)
		gf_list_insert(ptr->quality_segment_url_modifiers, tmp_str, i);
	}

	ptr->fragment_run_entry_count = gf_bs_read_u32(bs);
	if (ptr->size / 16 < ptr->fragment_run_entry_count)
		return GF_ISOM_INVALID_FILE;
	for (i=0; i<ptr->fragment_run_entry_count; i++) {
		GF_AdobeFragmentRunEntry *fre = gf_malloc(sizeof(GF_AdobeFragmentRunEntry));
		if (!fre) return GF_OUT_OF_MEM;
		ISOM_DECREASE_SIZE(ptr, 16)
		fre->first_fragment = gf_bs_read_u32(bs);
		fre->first_fragment_timestamp = gf_bs_read_u64(bs);
		fre->fragment_duration = gf_bs_read_u32(bs);
		if (!fre->fragment_duration) {
			ISOM_DECREASE_SIZE(ptr, 1)
			fre->discontinuity_indicator = gf_bs_read_u8(bs);
		}
		gf_list_insert(ptr->fragment_run_entry_table, fre, i);
	}

	return GF_OK;
}

Project: gpac

GF_DashSegmenterInput *set_dash_input(GF_DashSegmenterInput *dash_inputs, char *name, u32 *nb_dash_inputs)
{
	GF_DashSegmenterInput *di;
	Bool skip_rep_id = GF_FALSE;
	char *other_opts = NULL;
	char *sep = gf_url_colon_suffix(name);

	dash_inputs = gf_realloc(dash_inputs, sizeof(GF_DashSegmenterInput) * (*nb_dash_inputs + 1) );
	memset(&dash_inputs[*nb_dash_inputs], 0, sizeof(GF_DashSegmenterInput) );
	di = &dash_inputs[*nb_dash_inputs];
	(*nb_dash_inputs)++;

	if (sep) {
		char *opts, *first_opt;
		first_opt = sep;
		opts = sep+1;
		while (opts) {
			sep = gf_url_colon_suffix(opts);
			if (sep && !strncmp(sep, "://", 3) && strncmp(sep, ":@", 2)) sep = gf_url_colon_suffix(sep+3);
			if (sep) sep[0] = 0;

			if (!strnicmp(opts, "id=", 3)) {
				if (!stricmp(opts+3, "NULL"))
					skip_rep_id = GF_TRUE;
				else
					di->representationID = gf_strdup(opts+3);
				/*we allow the same repID to be set to force muxed representations*/
			}
			else if (!strnicmp(opts, "dur=", 4)) gf_parse_lfrac(opts+4, &di->media_duration);
			else if (!strnicmp(opts, "period=", 7)) di->periodID = gf_strdup(opts+7);
			else if (!strnicmp(opts, "BaseURL=", 8)) {
				di->baseURL = (char **)gf_realloc(di->baseURL, (di->nb_baseURL+1)*sizeof(char *));
				di->baseURL[di->nb_baseURL] = gf_strdup(opts+8);
				di->nb_baseURL++;
			} else if (!strnicmp(opts, "bandwidth=", 10)) di->bandwidth = atoi(opts+10);
			else if (!strnicmp(opts, "role=", 5)) {
				di->roles = gf_realloc(di->roles, sizeof (char *) * (di->nb_roles+1));
				di->roles[di->nb_roles] = gf_strdup(opts+5);
				di->nb_roles++;
			} else if (!strnicmp(opts, "desc", 4)) {
				u32 *nb_descs=NULL;
				char ***descs=NULL;
				u32 opt_offset=0;
				u32 len;
				if (!strnicmp(opts, "desc_p=", 7)) {
					nb_descs = &di->nb_p_descs;
					descs = &di->p_descs;
					opt_offset = 7;
				} else if (!strnicmp(opts, "desc_as=", 8)) {
					nb_descs = &di->nb_as_descs;
					descs = &di->as_descs;
					opt_offset = 8;
				} else if (!strnicmp(opts, "desc_as_c=", 8)) {
					nb_descs = &di->nb_as_c_descs;
					descs = &di->as_c_descs;
					opt_offset = 10;
				} else if (!strnicmp(opts, "desc_rep=", 8)) {
					nb_descs = &di->nb_rep_descs;
					descs = &di->rep_descs;
					opt_offset = 9;
				}
				if (opt_offset) {
					(*nb_descs)++;
					opts += opt_offset;
					len = (u32) strlen(opts);
					(*descs) = (char **)gf_realloc((*descs), (*nb_descs)*sizeof(char *));
					(*descs)[(*nb_descs)-1] = (char *)gf_malloc((len+1)*sizeof(char));
					memcpy((*descs)[(*nb_descs)-1], opts, len);
					(*descs)[(*nb_descs)-1][len] = 0;
				}

			}
			else if (!strnicmp(opts, "xlink=", 6)) di->xlink = gf_strdup(opts+6);
			else if (!strnicmp(opts, "sscale", 6)) di->sscale = GF_TRUE;
			else if (!strnicmp(opts, "pdur=", 5)) gf_parse_frac(opts+5, &di->period_duration);
			else if (!strnicmp(opts, "period_duration=", 16)) gf_parse_frac(opts+16, &di->period_duration);
			else if (!strnicmp(opts, "ddur=", 5)) gf_parse_frac(opts+5, &di->dash_duration);
			else if (!strnicmp(opts, "duration=", 9)) gf_parse_frac(opts+9, &di->dash_duration);
			else if (!strnicmp(opts, "asID=", 5)) di->asID = atoi(opts+5);
			else if (!strnicmp(opts, "sn=", 3)) di->startNumber = atoi(opts+3);
			else if (!strnicmp(opts, "tpl=", 4)) di->seg_template = gf_strdup(opts+4);
			else if (!strnicmp(opts, "hls=", 4)) di->hls_pl = gf_strdup(opts+4);
			else if (!strnicmp(opts, "trackID=", 8)) di->track_id = atoi(opts+8);
			else if (!strnicmp(opts, "@", 1)) {
				Bool old_syntax = (opts[1]=='@') ? GF_TRUE : GF_FALSE;
				if (sep) sep[0] = ':';
				di->filter_chain = gf_strdup(opts + (old_syntax ? 2 : 1) );
				sep = NULL;
				if (!old_syntax && (strstr(di->filter_chain, "@@")!=NULL)) {
					skip_rep_id = GF_TRUE;
				}
			} else {
				gf_dynstrcat(&other_opts, opts, ":");
			}

			if (!sep) break;
			sep[0] = ':';
			opts = sep+1;
		}
		first_opt[0] = '\0';
	}
	di->file_name = name;
	di->source_opts = other_opts;

	if (!skip_rep_id && !di->representationID) {
		char szRep[100];
		sprintf(szRep, "%d", *nb_dash_inputs);
		di->representationID = gf_strdup(szRep);
	}

	return dash_inputs;
}

Project: gpac
File: main.c

static GF_Err do_scene_encode()
{
	GF_Err e;
	FILE *logs = NULL;
	if (do_scene_log) {
		char alogfile[GF_MAX_PATH];
		strcpy(alogfile, inName);
		if (strchr(alogfile, '.')) {
			while (alogfile[strlen(alogfile)-1] != '.') alogfile[strlen(alogfile)-1] = 0;
			alogfile[strlen(alogfile)-1] = 0;
		}
		strcat(alogfile, "_enc.logs");
		logs = gf_fopen(alogfile, "wt");
	}
	strcpy(outfile, outName ? outName : inName);
	if (strchr(outfile, '.')) {
		while (outfile[strlen(outfile)-1] != '.') outfile[strlen(outfile)-1] = 0;
		outfile[strlen(outfile)-1] = 0;
	}
	strcat(outfile, ".mp4");
	file = gf_isom_open(outfile, GF_ISOM_WRITE_EDIT, NULL);
	smenc_opts.mediaSource = mediaSource ? mediaSource : outfile;
	e = EncodeFile(inName, file, &smenc_opts, logs);
	if (logs) gf_fclose(logs);
	if (e) return e;
	do_save = GF_TRUE;
	if (do_saf) {
		do_save = GF_FALSE;
		open_edit = GF_FALSE;
	}
	return GF_OK;
}

Project: gpac
File: main.c

static Bool create_new_track_action(char *arg_val, u32 act_type, u32 dump_type)
{
	TrackAction *tka;
	char *param = arg_val;
	tracks = (TrackAction *)gf_realloc(tracks, sizeof(TrackAction) * (nb_track_act+1));
	if (!tracks) return GF_FALSE;

	tka = & tracks[nb_track_act];
	nb_track_act++;

	memset(tka, 0, sizeof(TrackAction) );
	tka->act_type = act_type;
	tka->dump_type = dump_type;
	if (act_type != TRAC_ACTION_RAW_EXTRACT) {
		open_edit = GF_TRUE;
		do_save = GF_TRUE;
	}

	if ((act_type==TRAC_ACTION_SET_ID) || (act_type==TRAC_ACTION_SWAP_ID)) {
		if (sscanf(param, "%d:%u", &tka->trackID, &tka->newTrackID) != 2) {
			M4_LOG(GF_LOG_ERROR, ("Bad format for -set-track-id - expecting \"id1:id2\" got \"%s\"\n", param));
			return GF_FALSE;
		}
		return GF_TRUE;
	}
	if (act_type==TRAC_ACTION_SET_PAR) {
		char *ext;
		ext = strchr(param, '=');
		if (!ext) {
			M4_LOG(GF_LOG_ERROR, ("Bad format for track par - expecting tkID=none or tkID=PAR_NUM:PAR_DEN got %s\n", param));
			return GF_FALSE;
		}
		ext[0] = 0;
		tka->trackID = atoi(param);
		ext[0] = '=';

		if (!stricmp(ext+1, "none"))
			tka->par_num = tka->par_den = 0;
		else if (!stricmp(ext+1, "auto")) {
			tka->par_num = tka->par_den = -1;
			tka->force_par = 1;
		}
		else if (!stricmp(ext+1, "force")) {
			tka->par_num = tka->par_den = 1;
			tka->force_par = 1;
		}
		else {
			if (ext[1]=='w') {
				tka->rewrite_bs = 1;
				ext++;
			}
			if (sscanf(ext+1, "%d:%d", &tka->par_num, &tka->par_den) != 2) {
				M4_LOG(GF_LOG_ERROR, ("Bad format for track par - expecting tkID=PAR_NUM:PAR_DEN got %s\n", param));
				return GF_FALSE;
			}
		}
		return GF_TRUE;
	}
	if (act_type==TRAC_ACTION_SET_CLAP) {
		char *ext = strchr(param, '=');
		if (!ext) {
			M4_LOG(GF_LOG_ERROR, ("Bad format for track clap - expecting tkID=none or tkID=Wn,Wd,Hn,Hd,HOn,HOd,VOn,VOd got %s\n", param));
			return GF_FALSE;
		}
		ext[0] = 0;
		tka->trackID = atoi(param);
		ext[0] = '=';
		if (stricmp(ext + 1, "none")) {
			if (sscanf(ext + 1, "%d,%d,%d,%d,%d,%d,%d,%d", &tka->clap_wnum, &tka->clap_wden, &tka->clap_hnum, &tka->clap_hden, &tka->clap_honum, &tka->clap_hoden, &tka->clap_vonum, &tka->clap_voden) != 8) {

				M4_LOG(GF_LOG_ERROR, ("Bad format for track clap - expecting tkID=none or tkID=Wn,Wd,Hn,Hd,HOn,HOd,VOn,VOd got %s\n", param));
				return GF_FALSE;
			}
		}
		return GF_TRUE;
	}

	if (act_type==TRAC_ACTION_SET_MX) {
		char *ext = strchr(param, '=');
		if (!ext) {
			M4_LOG(GF_LOG_ERROR, ("Bad format for track matrix - expecting ID=none or ID=M1:M2:M3:M4:M5:M6:M7:M8:M9 got %s\n", param));
			return GF_FALSE;
		}
		ext[0] = 0;
		tka->trackID = atoi(param);
		ext[0] = '=';
		if (!stricmp(ext + 1, "none")) {
			memset(tka->mx, 0, sizeof(s32)*9);
			tka->mx[0] = tka->mx[4] = tka->mx[8] = 1;
		} else {
			s32 res;
			if (strstr(ext+1, "0x")) {
				res = sscanf(ext + 1, "0x%d:0x%d:0x%d:0x%d:0x%d:0x%d:0x%d:0x%d:0x%d", &tka->mx[0], &tka->mx[1], &tka->mx[2], &tka->mx[3], &tka->mx[4], &tka->mx[5], &tka->mx[6], &tka->mx[7], &tka->mx[8]);
			} else {
				res = sscanf(ext + 1, "%d:%d:%d:%d:%d:%d:%d:%d:%d", &tka->mx[0], &tka->mx[1], &tka->mx[2], &tka->mx[3], &tka->mx[4], &tka->mx[5], &tka->mx[6], &tka->mx[7], &tka->mx[8]);
			}
			if (res != 9) {
				M4_LOG(GF_LOG_ERROR, ("Bad format for track matrix - expecting ID=none or ID=M1:M2:M3:M4:M5:M6:M7:M8:M9 got %s\n", param));
				return GF_FALSE;
			}
		}
		return GF_TRUE;
	}
	if (act_type==TRAC_ACTION_SET_EDITS) {
		char *ext = strchr(param, '=');
		if (!ext) {
			M4_LOG(GF_LOG_ERROR, ("Bad format for track edits - expecting ID=EDITS got %s\n", param));
			return GF_FALSE;
		}
		ext[0] = 0;
		tka->trackID = atoi(param);
		ext[0] = '=';
		tka->string = gf_strdup(ext+1);
		return GF_TRUE;
	}
	if (act_type==TRAC_ACTION_SET_LANGUAGE) {
		char *ext = strchr(param, '=');
		if (!strnicmp(param, "all=", 4)) {
			strncpy(tka->lang, param + 4, 10-1);
		}
		else if (!ext) {
			strncpy(tka->lang, param, 10-1);
		} else {
			strncpy(tka->lang, ext + 1, 10-1);
			ext[0] = 0;
			tka->trackID = atoi(param);
			ext[0] = '=';
		}
		return GF_TRUE;
	}
	if ((act_type==TRAC_ACTION_SET_KIND) || (act_type==TRAC_ACTION_REM_KIND)) {
		char *ext;
		char *scheme_start = NULL;

		//extract trackID
		if (!strnicmp(param, "all=", 4)) {
			scheme_start = param + 4;
		} else {
			ext = strchr(param, '=');
			if (ext) {
				ext[0] = 0;
				if (sscanf(param, "%d", &tka->trackID) == 1) {
					scheme_start = ext + 1;
				} else {
					scheme_start = param;
				}
				ext[0] = '=';
			} else {
				scheme_start = param;
			}
		}

		//extract scheme and value - if not, remove kind
		if (!scheme_start || !scheme_start[0]) {
			M4_LOG(GF_LOG_ERROR, ("Missing kind scheme - expecting ID=schemeURI=value got %s\n", param));
			return GF_FALSE;
		} else {
			ext = strchr(scheme_start, '=');
			if (!ext) {
				tka->kind_scheme = gf_strdup(scheme_start);
			} else {
				ext[0] = 0;
				tka->kind_scheme = gf_strdup(scheme_start);
				ext[0] = '=';
				tka->kind_value = gf_strdup(ext + 1);
			}
		}
		return GF_TRUE;
	}
	if (act_type==TRAC_ACTION_SET_DELAY) {
		char *ext = strchr(param, '=');
		if (!ext) {
			M4_LOG(GF_LOG_ERROR, ("Bad format for track delay - expecting tkID=DLAY got %s\n", param));
			return GF_FALSE;
		}
		ext[0] = 0;
		tka->trackID = atoi(param);
		ext[0] = '=';
		if (sscanf(ext+1, "%d/%u", &tka->delay.num, &tka->delay.den) != 2) {
			tka->delay.num = atoi(ext + 1);
			tka->delay.den = 1000;
		}
		return GF_TRUE;
	}
	if (act_type==TRAC_ACTION_REFERENCE) {
		char *ext = strchr(param, '=');
		if (!ext) ext = strchr(param, ':');
		if (!ext) {
			M4_LOG(GF_LOG_ERROR, ("Bad format for track reference - expecting tkID:XXXX:refID got %s\n", param));
			return GF_FALSE;
		}
		ext[0] = 0;
		tka->trackID = atoi(param);
		ext[0] = '=';

		char *ext2 = strchr(ext, ':');
		if (!ext2) {
			M4_LOG(GF_LOG_ERROR, ("Bad format for track reference - expecting tkID:XXXX:refID got %s\n", param));
			return GF_FALSE;
		}
		ext2[0] = 0;
		strncpy(tka->lang, ext+1, 9);
		ext2[0] = ':';
		tka->newTrackID = (s32) atoi(ext2 + 1);
		return GF_TRUE;
	}
	if (act_type==TRAC_ACTION_SET_HANDLER_NAME) {
		char *ext = strchr(param, '=');
		if (!ext) {
			M4_LOG(GF_LOG_ERROR, ("Bad format for track name - expecting tkID=name got %s\n", param));
			return GF_FALSE;
		}
		ext[0] = 0;
		tka->trackID = atoi(param);
		ext[0] = '=';
		tka->hdl_name = ext + 1;
		return GF_TRUE;
	}
	if (act_type==TRAC_ACTION_SET_KMS_URI) {
		char *ext = strchr(param, '=');

		if (!strnicmp(param, "all=", 4)) {
			tka->kms = param + 4;
		} else if (!ext) {
			tka->kms = param;
		} else {
			tka->kms = ext + 1;
			ext[0] = 0;
			tka->trackID = atoi(param);
			ext[0] = '=';
		}
		return GF_TRUE;
	}
	if ((act_type==TRAC_ACTION_SET_TIME) || (act_type==TRAC_ACTION_SET_MEDIA_TIME)) {
		struct tm time;
		char *ext = strchr(arg_val, '=');
		if (ext) {
			ext[0] = 0;
			tka->trackID = atoi(arg_val);
			ext[0] = '=';
			arg_val = ext+1;
		}
		memset(&time, 0, sizeof(struct tm));
		sscanf(arg_val, "%d/%d/%d-%d:%d:%d", &time.tm_mday, &time.tm_mon, &time.tm_year, &time.tm_hour, &time.tm_min, &time.tm_sec);
		time.tm_isdst = 0;
		time.tm_year -= 1900;
		time.tm_mon -= 1;
		tka->time = 2082758400;
		tka->time += mktime(&time);
		return GF_TRUE;
	}

	while (param) {
		param = gf_url_colon_suffix(param);
		if (param) {
			*param = 0;
			param++;
#ifndef GPAC_DISABLE_MEDIA_EXPORT
			if (!strncmp("vttnomerge", param, 10)) {
				tka->dump_type |= GF_EXPORT_WEBVTT_NOMERGE;
			} else if (!strncmp("layer", param, 5)) {
				tka->dump_type |= GF_EXPORT_SVC_LAYER;
			} else if (!strncmp("full", param, 4)) {
				tka->dump_type |= GF_EXPORT_NHML_FULL;
			} else if (!strncmp("embedded", param, 8)) {
				tka->dump_type |= GF_EXPORT_WEBVTT_META_EMBEDDED;
			} else if (!strncmp("output=", param, 7)) {
				tka->out_name = gf_strdup(param+7);
			} else if (!strncmp("src=", param, 4)) {
				tka->src_name = gf_strdup(param+4);
			} else if (!strncmp("str=", param, 4)) {
				tka->string = gf_strdup(param+4);
			} else if (!strncmp("box=", param, 4)) {
				tka->src_name = gf_strdup(param+4);
				tka->sample_num = 1;
			} else if (!strncmp("type=", param, 4)) {
				tka->udta_type = GF_4CC(param[5], param[6], param[7], param[8]);
			} else if (tka->dump_type == GF_EXPORT_RAW_SAMPLES) {
				tka->sample_num = atoi(param);
			}
#endif
		}
	}
	if (arg_val) {
		if (!strcmp(arg_val, "*")) {
			tka->trackID = (u32) -1;
		} else {
			if (act_type==TRAC_ACTION_RAW_EXTRACT) {
				if (!strncmp(arg_val, "video", 5)) {
					arg_val += 5;
					tka->dump_track_type = 1;
				}
				else if (!strncmp(arg_val, "audio", 5)) {
					arg_val += 5;
					tka->dump_track_type = 2;
				}
			}
			if (arg_val[0])
				tka->trackID = atoi(arg_val);
		}
	}
	return GF_TRUE;
}

Project: gpac
File: main.c

u32 mp4box_parse_args(int argc, char **argv)
{
	u32 i;
	/*parse our args*/
	for (i = 1; i < (u32)argc; i++) {
		char *arg = argv[i];
		/*input file(s)*/
		if ((arg[0] != '-') || !stricmp(arg, "--")) {
			char *arg_val = arg;
			if (!stricmp(arg, "--")) {
				if (i+1==(u32)argc) {
					M4_LOG(GF_LOG_ERROR, ("Missing arg for `--` - please check usage\n"));
					return 2;
				}
				has_next_arg = GF_TRUE;
				arg_val = argv[i + 1];
				i++;
			}
			if (argc < 3) {
				M4_LOG(GF_LOG_ERROR, ("Error - only one input file found as argument, please check usage\n"));
				return 2;
			}
			else if (inName) {
				if (dash_duration) {
					if (!nb_dash_inputs) {
						dash_inputs = set_dash_input(dash_inputs, inName, &nb_dash_inputs);
					}
					dash_inputs = set_dash_input(dash_inputs, arg_val, &nb_dash_inputs);
				}
				else {
					M4_LOG(GF_LOG_ERROR, ("Error - 2 input names specified, please check usage\n"));
					return 2;
				}
			}
			else {
				inName = arg_val;
			}
		}
		//all deprecated options
		else if (!stricmp(arg, "-grab-ts") || !stricmp(arg, "-atsc") || !stricmp(arg, "-rtp")) {
			M4_LOG(GF_LOG_ERROR, ("Deprecated fuctionnality `%s` - use gpac application\n", arg));
			return 2;
		}
		else if (!stricmp(arg, "-write-buffer")) {
			M4_LOG(GF_LOG_WARNING, ("`%s` option deprecated, use `-bs-cache-size`", arg));
			gf_opts_set_key("temp", "bs-cache-size", argv[i + 1]);
			i++;
		}
		else if (!stricmp(arg, "-pssh-moof")) {
			M4_LOG(GF_LOG_ERROR, ("`-pssh-moof` option deprecated , use `-pssh` option\n"));
			return 2;
		}
		else if (!stricmp(arg, "-tag-list")) {
			M4_LOG(GF_LOG_ERROR, ("`-tag-list` option deprecated, use `-h tags`\n"));
			return 2;
		}
		else if (!stricmp(arg, "-aviraw")) {
			M4_LOG(GF_LOG_ERROR, ("`-aviraw` option deprecated, use `-raw`\n"));
			return 2;
		}
		else if (!stricmp(arg, "-avi")) {
			M4_LOG(GF_LOG_ERROR, ("`-avi` option deprecated, use `-mux`\n"));
			return 2;
		}
		else if (!strncmp(arg, "-p=", 3)) {
			continue;
		}

		//parse argument
		else if (mp4box_parse_single_arg(argc, argv, arg, &i)) {
			if (arg_parse_res)
				return mp4box_cleanup(arg_parse_res);
		}
		//not a MP4Box arg
		else {
			u32 res = gf_sys_is_gpac_arg(arg);
			if (res==0) {
				PrintHelp(arg, GF_FALSE, GF_TRUE);
				return 2;
			} else if (res==2) {
				i++;
			}
		}
		//live scene encoder does not use the unified parsing and should be moved as a scene encoder filter
		if (live_scene) return 0;
	}
	return 0;
}

Project: gpac
File: main.c

void PrintMetaUsage()
{
	u32 i=0;
	gf_sys_format_help(helpout, help_flags, "# Meta and HEIF Options\n"
	"IsoMedia files can be used as generic meta-data containers, for examples storing XML information and sample images for a movie. The resulting file may not always contain a movie as is the case with some HEIF files or MPEG-21 files.\n"
	"  \n"
	"These information can be stored at the file root level, as is the case for HEIF/IFF and MPEG-21 file formats, or at the movie or track level for a regular movie."
	"  \n  \n");
	while (m4b_meta_args[i].name) {
		GF_GPACArg *arg = (GF_GPACArg *) &m4b_meta_args[i];
		i++;
		gf_sys_print_arg(helpout, help_flags, arg, "mp4box-extract");
	}
}

Project: gpac
File: main.c

u32 parse_pssh(char *arg_val, u32 opt)
{
	if (!strcmp(arg_val, "f")) pssh_mode = GF_DASH_PSSH_MOOF;
	else if (!strcmp(arg_val, "v")) pssh_mode = GF_DASH_PSSH_MOOV;
	else if (!strcmp(arg_val, "m")) pssh_mode = GF_DASH_PSSH_MPD;
	else if (!strcmp(arg_val, "mf") || !strcmp(arg_val, "fm")) pssh_mode = GF_DASH_PSSH_MOOF_MPD;
	else if (!strcmp(arg_val, "mv") || !strcmp(arg_val, "vm")) pssh_mode = GF_DASH_PSSH_MOOV_MPD;
	else pssh_mode = GF_DASH_PSSH_MOOV;
	return 0;
}

Project: gpac

u32 parse_compress(char *arg_val, u32 opt)
{
	compress_moov = opt ? 2 : 1;
	open_edit = GF_TRUE;
	return 0;
}

Project: gpac
File: main.c

u32 parse_dash_profile(char *arg_val, u32 opt)
{
	if (!stricmp(arg_val, "live") || !stricmp(arg_val, "simple")) dash_profile = GF_DASH_PROFILE_LIVE;
	else if (!stricmp(arg_val, "onDemand")) dash_profile = GF_DASH_PROFILE_ONDEMAND;
	else if (!stricmp(arg_val, "hbbtv1.5:live") || !stricmp(arg_val, "hbbtv1.5.live"))
		dash_profile = GF_DASH_PROFILE_HBBTV_1_5_ISOBMF_LIVE;
	else if (!stricmp(arg_val, "dashavc264:live") || !stricmp(arg_val, "dashavc264.live"))
		dash_profile = GF_DASH_PROFILE_AVC264_LIVE;
	else if (!stricmp(arg_val, "dashavc264:onDemand") || !stricmp(arg_val, "dashavc264.onDemand"))
		dash_profile = GF_DASH_PROFILE_AVC264_ONDEMAND;
	else if (!stricmp(arg_val, "dashif.ll")) dash_profile = GF_DASH_PROFILE_DASHIF_LL;
	else if (!stricmp(arg_val, "main")) dash_profile = GF_DASH_PROFILE_MAIN;
	else if (!stricmp(arg_val, "full")) dash_profile = GF_DASH_PROFILE_FULL;
	else {
		M4_LOG(GF_LOG_ERROR, ("Unrecognized DASH profile \"%s\" - please check usage\n", arg_val));
		return 2;
	}
	return 0;
}

Project: gpac
File: main.c

void PrintCICP()
{
	u32 i;
	gf_sys_format_help(helpout, help_flags, "# Video CICP (ISO/IEC 23091-2) Constants\n");
	gf_sys_format_help(helpout, help_flags, "CICP Color Primaries:\n");
	for (i=0; i<GF_CICP_PRIM_LAST; i++) {
		const char *name = gf_cicp_color_primaries_name(i);
		if (!name || !strcmp(name, "unknwon")) continue;
		gf_sys_format_help(helpout, help_flags, " - `%s` (value %d)\n", name, i);
	}
	gf_sys_format_help(helpout, help_flags, "  \nCICP Color Transfer Characteristics:\n");
	for (i=0; i<GF_CICP_TRANSFER_LAST; i++) {
		const char *name = gf_cicp_color_transfer_name(i);
		if (!name) continue;
		gf_sys_format_help(helpout, help_flags, " - `%s` (value %d)\n", name, i);
	}
	gf_sys_format_help(helpout, help_flags, "  \nCICP Color Matrix Coefficients:\n");
	for (i=0; i<GF_CICP_MX_LAST; i++) {
		const char *name = gf_cicp_color_matrix_name(i);
		if (!name) continue;
		gf_sys_format_help(helpout, help_flags, " - `%s` (value %d)\n", name, i);
	}
}

Project: gpac
File: main.c

u32 parse_brand(char *b, u32 opt)
{
	open_edit = GF_TRUE;
	switch (opt) {
	case 0: //-brand
		major_brand = GF_4CC(b[0], b[1], b[2], b[3]);
		if (b[4] == ':') {
			if (!strncmp(b+5, "0x", 2))
				sscanf(b+5, "0x%x", &minor_version);
			else
				minor_version = atoi(b + 5);
		}
		break;
	case 1: //-ab
		brand_add = (u32*)gf_realloc(brand_add, sizeof(u32) * (nb_alt_brand_add + 1));
		if (!brand_add) return 2;
		brand_add[nb_alt_brand_add] = GF_4CC(b[0], b[1], b[2], b[3]);
		nb_alt_brand_add++;
		break;
	case 2: //-rb
		brand_rem = (u32*)gf_realloc(brand_rem, sizeof(u32) * (nb_alt_brand_rem + 1));
		if (!brand_rem) return 2;
		brand_rem[nb_alt_brand_rem] = GF_4CC(b[0], b[1], b[2], b[3]);
		nb_alt_brand_rem++;
		break;
	}
	return 0;
}

Project: gpac
File: main.c

static GF_Err xml_bs_to_bin(char *inName, char *outName, u32 dump_std)
{
	GF_Err e;
	GF_XMLNode *root;
	u8 *data = NULL;
	u32 data_size;

	GF_DOMParser *dom = gf_xml_dom_new();
	e = gf_xml_dom_parse(dom, inName, NULL, NULL);
	if (e) {
		gf_xml_dom_del(dom);
		M4_LOG(GF_LOG_ERROR, ("Failed to parse XML file: %s\n", gf_error_to_string(e)));
		return e;
	}
	root = gf_xml_dom_get_root_idx(dom, 0);
	if (!root) {
		gf_xml_dom_del(dom);
		return GF_OK;
	}

	e = gf_xml_parse_bit_sequence(root, inName, &data, &data_size);
	gf_xml_dom_del(dom);

	if (e) {
		M4_LOG(GF_LOG_ERROR, ("Failed to parse binary sequence: %s\n", gf_error_to_string(e)));
		return e;
	}

	if (dump_std) {
		gf_fwrite(data, data_size, stdout);
	} else {
		FILE *t;
		char szFile[GF_MAX_PATH];
		if (outName) {
			strcpy(szFile, outName);
		} else {
			strcpy(szFile, inName);
			strcat(szFile, ".bin");
		}
		t = gf_fopen(szFile, "wb");
		if (!t) {
			M4_LOG(GF_LOG_ERROR, ("Failed to open file %s\n", szFile));
			e = GF_IO_ERR;
		} else {
			if (gf_fwrite(data, data_size, t) != data_size) {
				M4_LOG(GF_LOG_ERROR, ("Failed to write output to file %s\n", szFile));
				e = GF_IO_ERR;
			}
			gf_fclose(t);
		}
	}
	gf_free(data);
	return e;
}

Project: gpac
File: main.c

static u32 PrintHelpForArgs(char *arg_name, MP4BoxArg *args, GF_GPACArg *_args, u32 search_type)
{
	u32 res=0;
	u32 i=0;
	u32 alen = (u32) strlen(arg_name);

	while (1) {
		u32 flags=0;
		GF_GPACArg *arg;
		GF_GPACArg an_arg;
		Bool do_match = GF_FALSE;
		if (args) {
			if (!args[i].name)
				break;
			arg = (GF_GPACArg *) &args[i];
		} else {
			if (!_args[i].name)
				break;
			arg = &_args[i];
		}

		if (args == m4b_imp_fileopt_args) {
			flags = GF_PRINTARG_COLON;
			if (!strncmp(arg_name, arg->name, alen) && ((arg->name[alen]==0) || (arg->name[alen]=='=')))
				do_match = GF_TRUE;
		}
		else if (!strcmp(arg_name, arg->name))
			do_match = GF_TRUE;
		else if ((alen < (u32) strlen(arg->name)) && (arg->name[alen]==' ') && !strncmp(arg_name, arg->name, alen))
			do_match = GF_TRUE;

		if (arg_name[0] == '@')
			do_match = GF_TRUE;

		if ((search_type==SEARCH_ARG_EXACT) && !do_match) {
			i++;
			continue;
		}
		if ((search_type==SEARCH_ARG_CLOSE) && !gf_sys_word_match(arg_name, arg->name)) {
			i++;
			continue;
		}
		if ((search_type==SEARCH_DESC) && !strstr_nocase(arg->description, arg_name, alen)) {
			i++;
			continue;
		}

		an_arg = *arg;
		if (search_type!=SEARCH_ARG_EXACT) {
			an_arg.description = NULL;
			an_arg.type = GF_ARG_BOOL;
		}
		gf_sys_print_arg(helpout, flags, (GF_GPACArg *) &an_arg, "");
		res++;
		i++;
	}
	return res;
}

Project: gpac
File: main.c

void PrintExtractUsage()
{
	u32 i=0;
	gf_sys_format_help(helpout, help_flags, "# Extracting Options\n"
	"MP4Box can be used to extract media tracks from MP4 files. If you need to convert these tracks however, please check the [filters doc](Filters).\n"
	"  \n"
	"Options:\n"
	);
	while (m4b_extr_args[i].name) {
		GF_GPACArg *arg = (GF_GPACArg *) &m4b_extr_args[i];
		i++;
		gf_sys_print_arg(helpout, help_flags, arg, "mp4box-extract");
	}
}

Project: gpac
File: main.c

void PrintDumpUsage()
{
	u32 i=0;
	gf_sys_format_help(helpout, help_flags, "# File Dumping\n"
	"  \n"
	"MP4Box has many dump functionalities, from simple track listing to more complete reporting of special tracks.\n"
	"  \n"
	"Options:\n"
	);
	while (m4b_dump_args[i].name) {
		GF_GPACArg *arg = (GF_GPACArg *) &m4b_dump_args[i];
		i++;
		gf_sys_print_arg(helpout, help_flags, arg, "mp4box-extract");
	}
}

Project: gpac
File: main.c

u32 parse_boxpatch(char *arg_val, u32 opt)
{
	box_patch_filename = arg_val;
	char *sep = strchr(box_patch_filename, '=');
	if (sep) {
		sep[0] = 0;
		box_patch_trackID = atoi(box_patch_filename);
		sep[0] = '=';
		box_patch_filename = sep+1;
	}
	open_edit = GF_TRUE;
	return 0;
}

Project: gpac
File: main.c

void PrintLiveUsage()
{
	u32 i=0;
	gf_sys_format_help(helpout, help_flags, "# Live Scene Encoder Options\n"
	        "The options shall be specified as òpt_name=opt_val.\n"
	        "Options:\n"
	        "\n"
	);
	while (m4b_liveenc_args[i].name) {
		GF_GPACArg *arg = (GF_GPACArg *) &m4b_liveenc_args[i];
		i++;
		gf_sys_print_arg(helpout, help_flags, arg, "mp4box-extract");
	}

	gf_sys_format_help(helpout, help_flags, "  \n"
		"Runtime options:\n"
		"- q: quits\n"
		"- u: inputs some commands to be sent\n"
		"- U: same as u but signals the updates as critical\n"
		"- e: inputs some commands to be sent without being aggregated\n"
		"- E: same as e but signals the updates as critical\n"
		"- f: forces RAP sending\n"
		"- F: forces RAP regeneration and sending\n"
		"- p: dumps current scene\n"
	);
}

Project: gpac
File: main.c

Bool mp4box_check_isom_fileopt(char *opt)
{
	GF_GPACArg *arg = NULL;
	u32 i=0;

	while (m4b_imp_fileopt_args[i].name) {
		arg = (GF_GPACArg *) &m4b_imp_fileopt_args[i];
		i++;
		if (!stricmp(arg->name, opt)) break;
		arg = NULL;
	}
	if (!arg) {
		fprintf(stderr, "Option %s not described in doc, please report to GPAC devs!\n", opt);
		return GF_FALSE;
	}
	if (arg->description[0] != '`')
		return GF_FALSE;
	const char *d = arg->description+1;
	while (d[0] != '`') {
		if (d[0]=='S') return GF_TRUE;
		if (d[0]=='C') return GF_TRUE;
		d++;
	}
	return GF_FALSE;
}

Project: gpac
File: main.c

u32 parse_dsap(char *arg_val, u32 opt)
{
	dump_saps = atoi(arg_val);
	dump_saps_mode = opt;
	return 0;
}

Project: gpac
File: main.c

static u32 do_add_cat(int argc, char **argv)
{
	GF_Err e;
	u32 i, ipass, nb_pass = 1;
	char *mux_args=NULL;
	GF_FilterSession *fs = NULL;
	if (nb_add) {

		GF_ISOOpenMode open_mode = GF_ISOM_OPEN_EDIT;
		if (force_new) {
			open_mode = (do_flat || (force_new==2)) ? GF_ISOM_OPEN_WRITE : GF_ISOM_WRITE_EDIT;
		} else {
			FILE *test = gf_fopen(inName, "rb");
			if (!test) {
				open_mode = (do_flat) ? GF_ISOM_OPEN_WRITE : GF_ISOM_WRITE_EDIT;
				if (!outName) outName = inName;
			} else {
				gf_fclose(test);
				if (! gf_isom_probe_file(inName) ) {
					open_mode = (do_flat) ? GF_ISOM_OPEN_WRITE : GF_ISOM_WRITE_EDIT;
					if (!outName) outName = inName;
				}
			}
		}
		open_edit = do_flat ? GF_FALSE : GF_TRUE;
		file = gf_isom_open(inName, open_mode, NULL);
		if (!file) {
			M4_LOG(GF_LOG_ERROR, ("Cannot open destination file %s: %s\n", inName, gf_error_to_string(gf_isom_last_error(NULL)) ));
			return mp4box_cleanup(1);
		}

		if (freeze_box_order)
			gf_isom_freeze_order(file);

		if (do_flat) {
			if (major_brand)
				gf_isom_set_brand_info(file, major_brand, minor_version);
			for (i=0; i<nb_alt_brand_add; i++) {
				gf_isom_modify_alternate_brand(file, brand_add[i], GF_TRUE);
				do_save = GF_TRUE;
			}

			if (!major_brand && !nb_alt_brand_add && has_add_image) {
				gf_isom_modify_alternate_brand(file, GF_ISOM_BRAND_MIF1, GF_TRUE);
			}
		}
	}

	if (file && keep_utc && open_edit) {
		gf_isom_keep_utc_times(file, 1);
	}

	if (do_flat && interleaving_time) {
		char szSubArg[100];
		gf_isom_set_storage_mode(file, GF_ISOM_STORE_FASTSTART);
		do_flat = 2;
		nb_pass = 2;
		fs = gf_fs_new_defaults(0);
		if (!fs) {
			M4_LOG(GF_LOG_ERROR, ("Error creating filter session\n"));
			gf_isom_delete(file);
			return mp4box_cleanup(1);
		}

		//mux args
		gf_dynstrcat(&mux_args, "mp4mx:importer:store=fstart", ":");

		sprintf(szSubArg, "file=%p", file);
		gf_dynstrcat(&mux_args, szSubArg, ":");
		sprintf(szSubArg, "cdur=%g", interleaving_time);
		gf_dynstrcat(&mux_args, szSubArg, ":");
	}

	for (ipass=0; ipass<nb_pass; ipass++) {
		u32 tk_idx = 1;
		for (i=0; i<(u32) argc; i++) {
			char *margs=NULL;
			if (!strcmp(argv[i], "-add")) {
				char *src = argv[i+1];

				while (src) {
					char *loc_src = src;
					char *sep = NULL;
					while (1) {
						char *opt_sep;
						sep = strchr(loc_src, '+');
						if (!sep) break;

						sep[0] = 0;
						if (strstr(src, "://"))
							break;

						opt_sep = gf_url_colon_suffix(src);
						if (opt_sep)
							opt_sep[0] = 0;
						if (gf_file_exists(src)) {
							if (opt_sep)
								opt_sep[0] = ':';
							break;
						}
						if (opt_sep)
							opt_sep[0] = ':';

						sep[0] = '+';
						loc_src = sep+1;
					}

					e = import_file(file, src, import_flags, import_fps, agg_samples, fs, (fs && (ipass==0)) ? &margs : NULL, tk_idx);
					tk_idx++;

					if (margs) {
						gf_dynstrcat(&mux_args, margs, ":");
						gf_free(margs);
					}

					if (e) {
						M4_LOG(GF_LOG_ERROR, ("Error importing %s: %s\n", argv[i+1], gf_error_to_string(e)));
						gf_isom_delete(file);
						if (fs)
							gf_fs_del(fs);
						return mp4box_cleanup(1);
					}
					if (sep) {
						sep[0] = '+';
						src = sep+1;
					} else {
						break;
					}
				}
				i++;
			} else if (!strcmp(argv[i], "-cat") || !strcmp(argv[i], "-catx") || !strcmp(argv[i], "-catpl")) {
				if (nb_pass == 2) {
					M4_LOG(GF_LOG_ERROR, ("Cannot cat files when using -newfs mode\n"));
					return mp4box_cleanup(1);
				}
				if (!file) {
					u8 open_mode = GF_ISOM_OPEN_EDIT;
					if (force_new) {
						open_mode = (do_flat) ? GF_ISOM_OPEN_WRITE : GF_ISOM_WRITE_EDIT;
					} else {
						FILE *test = gf_fopen(inName, "rb");
						if (!test) {
							open_mode = (do_flat) ? GF_ISOM_OPEN_WRITE : GF_ISOM_WRITE_EDIT;
							if (!outName) outName = inName;
						}
						else gf_fclose(test);
					}

					open_edit = GF_TRUE;
					file = gf_isom_open(inName, open_mode, NULL);
					if (!file) {
						M4_LOG(GF_LOG_ERROR, ("Cannot open destination file %s: %s\n", inName, gf_error_to_string(gf_isom_last_error(NULL)) ));
						return mp4box_cleanup(1);
					}
				}

				e = cat_isomedia_file(file, argv[i+1], import_flags, import_fps, agg_samples, force_cat, align_cat, !strcmp(argv[i], "-catx") ? GF_TRUE : GF_FALSE, !strcmp(argv[i], "-catpl") ? GF_TRUE : GF_FALSE);
				if (e) {
					M4_LOG(GF_LOG_ERROR, ("Error appending %s: %s\n", argv[i+1], gf_error_to_string(e)));
					gf_isom_delete(file);
					return mp4box_cleanup(1);
				}
				i++;
			}
		}
		if ((nb_pass == 2) && !ipass) {
			GF_Filter *mux_filter = gf_fs_load_filter(fs, mux_args, NULL);
			gf_free(mux_args);
			if (!mux_filter) {
				M4_LOG(GF_LOG_ERROR, ("Error loadin isobmff mux filter\n"));
				gf_isom_delete(file);
				gf_fs_del(fs);
				return mp4box_cleanup(1);
			}

			e = gf_fs_run(fs);
			if (e==GF_EOS) e = GF_OK;

			if (!e) e = gf_fs_get_last_connect_error(fs);
			if (!e) e = gf_fs_get_last_process_error(fs);

			if (e) {
				M4_LOG(GF_LOG_ERROR, ("Error importing sources: %s\n", gf_error_to_string(e)));
				gf_isom_delete(file);
				gf_fs_del(fs);
				return mp4box_cleanup(1);
			}
		}
	}
	if (fs) {
		gf_fs_print_non_connected(fs);
		if (fs_dump_flags & 1) gf_fs_print_stats(fs);
		if (fs_dump_flags & 2) gf_fs_print_connections(fs);
		gf_fs_del(fs);
	}

	/*unless explicitly asked, remove all systems tracks*/
#ifndef GPAC_DISABLE_AV_PARSERS
	if (!keep_sys_tracks) remove_systems_tracks(file);
#endif
	do_save = GF_TRUE;

	return 0;
}

Project: gpac
File: main.c

static GF_Err do_export_tracks()
{
	GF_Err e;
	u32 i;
	char szFile[GF_MAX_PATH+24];
	GF_MediaExporter mdump;
	for (i=0; i<nb_track_act; i++) {
		u32 j;
		TrackAction *tka = &tracks[i];
		if (tka->act_type != TRAC_ACTION_RAW_EXTRACT) continue;
		memset(&mdump, 0, sizeof(mdump));
		mdump.file = file;
		mdump.flags = tka->dump_type;
		mdump.trackID = tka->trackID;
		mdump.sample_num = tka->sample_num;
		if (tka->out_name) {
			mdump.out_name = tka->out_name;
		} else if (outName) {
			mdump.out_name = outName;
			mdump.flags |= GF_EXPORT_MERGE;
			/*don't infer extension on user-given filename*/
			mdump.flags |= GF_EXPORT_NO_FILE_EXT;
		} else if (mdump.trackID) {
			sprintf(szFile, "%s_track%d", outfile, mdump.trackID);
			mdump.out_name = szFile;
		} else {
			sprintf(szFile, "%s_export", outfile);
			mdump.out_name = szFile;
		}
		if (tka->trackID==(u32) -1) {
			for (j=0; j<gf_isom_get_track_count(file); j++) {
				mdump.trackID = gf_isom_get_track_id(file, j+1);
				sprintf(szFile, "%s_track%d", outfile, mdump.trackID);
				mdump.out_name = szFile;
				mdump.print_stats_graph = fs_dump_flags;
				e = gf_media_export(&mdump);
				if (e) return e;
			}
		} else {
			mdump.print_stats_graph = fs_dump_flags;
			e = gf_media_export(&mdump);
			if (e) return e;
		}
	}
	return GF_OK;
}

Project: gpac
File: main.c

u32 parse_dnal(char *arg_val, u32 opt)
{
	dump_nal = atoi(arg_val);
	dump_nal_type = opt;
	return 0;
}

Project: gpac

GF_Err asrt_box_read(GF_Box *s, GF_BitStream *bs)
{
	unsigned int i;
	GF_AdobeSegmentRunTableBox *ptr = (GF_AdobeSegmentRunTableBox *)s;

	ISOM_DECREASE_SIZE(ptr, 1)
	ptr->quality_entry_count = gf_bs_read_u8(bs);
	if (ptr->size < ptr->quality_entry_count)
		return GF_ISOM_INVALID_FILE;

	for (i=0; i<ptr->quality_entry_count; i++) {
		int j=0;
		u32 tmp_strsize=(u32)ptr->size;
		char *tmp_str = (char*) gf_malloc(tmp_strsize);
		if (!tmp_str) return GF_OUT_OF_MEM;
		while (tmp_strsize) {
			tmp_str[j] = gf_bs_read_u8(bs);
			tmp_strsize--;
			if (!tmp_str[j])
				break;
			j++;
		}
		ISOM_DECREASE_SIZE(ptr, j)
		gf_list_insert(ptr->quality_segment_url_modifiers, tmp_str, i);
	}

	ISOM_DECREASE_SIZE(ptr, 4)
	ptr->segment_run_entry_count = gf_bs_read_u32(bs);
	if (ptr->size / 8 < ptr->segment_run_entry_count)
		return GF_ISOM_INVALID_FILE;

	for (i=0; i<ptr->segment_run_entry_count; i++) {
		GF_AdobeSegmentRunEntry *sre = gf_malloc(sizeof(GF_AdobeSegmentRunEntry));
		if (!sre) return GF_OUT_OF_MEM;
		ISOM_DECREASE_SIZE(ptr, 8)
		sre->first_segment = gf_bs_read_u32(bs);
		sre->fragment_per_segment = gf_bs_read_u32(bs);
		gf_list_insert(ptr->segment_run_entry_table, sre, i);
	}

	return GF_OK;
}

Project: gpac

void PrintDASHUsage()
{
	u32 i=0;
	gf_sys_format_help(helpout, help_flags, "# DASH Options\n"
		"Also see:\n"
		"- the [dasher `gpac -h dash`](dasher) filter documentation\n"
		"- [[DASH wiki|DASH-intro]].\n"
		"\n"
		"# Specifying input files\n"
		"Input media files to dash can use the following modifiers\n"
		"- #trackID=N: only use the track ID N from the source file\n"
		"- #N: only use the track ID N from the source file (mapped to [-tkid](mp4dmx))\n"
		"- #video: only use the first video track from the source file\n"
		"- #audio: only use the first audio track from the source file\n"
		"- :id=NAME: set the representation ID to NAME. Reserved value `NULL` disables representation ID for multiplexed inputs. If not set, a default value is computed and all selected tracks from the source will be in the same output mux.\n"
		"- :dur=VALUE: process VALUE seconds (fraction) from the media. If VALUE is longer than media duration, last sample duration is extended.\n"
		"- :period=NAME: set the representation's period to NAME. Multiple periods may be used. Periods appear in the MPD in the same order as specified with this option\n"
		"- :BaseURL=NAME: set the BaseURL. Set multiple times for multiple BaseURLs\nWarning: This does not modify generated files location (see segment template).\n"
		"- :bandwidth=VALUE: set the representation's bandwidth to a given value\n"
		"- :pdur=VALUE: sets the duration of the associated period to VALUE seconds (fraction) (alias for period_duration:VALUE). This is only used when no input media is specified (remote period insertion), eg `:period=X:xlink=Z:pdur=Y`\n"
		"- :ddur=VALUE: override target DASH segment duration to VALUE seconds (fraction) for this input (alias for duration:VALUE)\n"
		"- :xlink=VALUE: set the xlink value for the period containing this element. Only the xlink declared on the first rep of a period will be used\n"
		"- :asID=VALUE: set the AdaptationSet ID to NAME\n"
		"- :role=VALUE: set the role of this representation (cf DASH spec). Media with different roles belong to different adaptation sets.\n"
		"- :desc_p=VALUE: add a descriptor at the Period level. Value must be a properly formatted XML element.\n"
		"- :desc_as=VALUE: add a descriptor at the AdaptationSet level. Value must be a properly formatted XML element. Two input files with different values will be in different AdaptationSet elements.\n"
		"- :desc_as_c=VALUE: add a descriptor at the AdaptationSet level. Value must be a properly formatted XML element. Value is ignored while creating AdaptationSet elements.\n"
		"- :desc_rep=VALUE: add a descriptor at the Representation level. Value must be a properly formatted XML element. Value is ignored while creating AdaptationSet elements.\n"
		"- :sscale: force movie timescale to match media timescale of the first track in the segment.\n"
		"- :trackID=N: only use the track ID N from the source file\n"
		"- @f1[:args][@fN:args][@@fK:args]: set a filter chain to insert between the source and the dasher. Each filter in the chain is formatted as a regular filter, see [filter doc `gpac -h doc`](filters_general). If several filters are set:\n"
		"  - they will be chained in the given order if separated by a single `@`\n"
		"  - a new filter chain will be created if separated by a double `@@`. In this case, no representation ID is assigned to the source.\n"
		"EX source.mp4:@enc:c=avc:b=1M@@enc:c=avc:b=500k\n"
		"This will load a filter chain with two encoders connected to the source and to the dasher.\n"
		"EX source.mp4:@enc:c=avc:b=1M@enc:c=avc:b=500k\n"
		"This will load a filter chain with the second encoder connected to the output of the first (!!).\n"
		"\n"
		"Note: `@f` must be placed after all other options.\n"
		"\n"
		"# Options\n"
		);


	while (m4b_dash_args[i].name) {
		GF_GPACArg *arg = (GF_GPACArg *) &m4b_dash_args[i];
		i++;
		gf_sys_print_arg(helpout, help_flags, arg, "mp4box-dash");
	}
}

Project: gpac
File: main.c

u32 parse_help(char *arg_val, u32 opt)
{
	if (!arg_val) PrintUsage();
	else if (opt) PrintHelp(arg_val, GF_TRUE, GF_FALSE);
	else if (!strcmp(arg_val, "general")) PrintGeneralUsage();
	else if (!strcmp(arg_val, "extract")) PrintExtractUsage();
	else if (!strcmp(arg_val, "split")) PrintSplitUsage();
	else if (!strcmp(arg_val, "dash")) PrintDASHUsage();
	else if (!strcmp(arg_val, "dump")) PrintDumpUsage();
	else if (!strcmp(arg_val, "import")) PrintImportUsage();
	else if (!strcmp(arg_val, "format")) {
		M4_LOG(GF_LOG_WARNING, ("deprecated, see [filters documentation](Filters)\n"));
	}
	else if (!strcmp(arg_val, "hint")) PrintHintUsage();
	else if (!strcmp(arg_val, "encode")) PrintEncodeUsage();
	else if (!strcmp(arg_val, "crypt")) PrintEncryptUsage();
	else if (!strcmp(arg_val, "meta")) PrintMetaUsage();
	else if (!strcmp(arg_val, "swf")) PrintSWFUsage();
#if !defined(GPAC_DISABLE_STREAMING) && !defined(GPAC_DISABLE_SENG)
	else if (!strcmp(arg_val, "rtp")) {
		M4_LOG(GF_LOG_WARNING, ("RTP streaming deprecated in MP4Box, use gpac application\n"));
	}
	else if (!strcmp(arg_val, "live")) PrintLiveUsage();
#endif
	else if (!strcmp(arg_val, "core")) PrintCoreUsage();
	else if (!strcmp(arg_val, "tags")) PrintTags();
	else if (!strcmp(arg_val, "cicp")) PrintCICP();
	else if (!strcmp(arg_val, "all")) {
		PrintGeneralUsage();
		PrintExtractUsage();
		PrintDASHUsage();
		PrintSplitUsage();
		PrintDumpUsage();
		PrintImportUsage();
		PrintHintUsage();
		PrintEncodeUsage();
		PrintEncryptUsage();
		PrintMetaUsage();
		PrintSWFUsage();
#if !defined(GPAC_DISABLE_STREAMING) && !defined(GPAC_DISABLE_SENG)
		PrintLiveUsage();
#endif
		PrintCoreUsage();
		PrintTags();
		PrintCICP();
	} else if (!strcmp(arg_val, "opts")) {
		PrintHelp("@", GF_FALSE, GF_FALSE);
	} else {
		PrintHelp(arg_val, GF_FALSE, GF_FALSE);
	}
	return 1;
}

Project: gpac
File: main.c

static GF_Err do_compress_top_boxes(char *inName, char *outName)
{
	FILE *in, *out;
	u8 *buf;
	u32 buf_alloc, comp_size;
	s32 bytes_comp=0;
	s32 bytes_uncomp=0;
	GF_Err e = GF_OK;
	u64 source_size, dst_size;
	u32 orig_box_overhead;
	u32 final_box_overhead;
	u32 nb_added_box_bytes=0;
	Bool has_mov = GF_FALSE;
	Bool replace_all = !strcmp(compress_top_boxes, "*");
	GF_BitStream *bs_in, *bs_out;

	if (!outName) {
		M4_LOG(GF_LOG_ERROR, ("Missing output file name\n"));
		return GF_BAD_PARAM;
	}

	in = gf_fopen(inName, "rb");
	if (!in) return GF_URL_ERROR;
	out = gf_fopen(outName, "wb");
	if (!out) return GF_IO_ERR;

	buf_alloc = 4096;
	buf = gf_malloc(buf_alloc);

	bs_in = gf_bs_from_file(in, GF_BITSTREAM_READ);
	source_size = gf_bs_get_size(bs_in);

	bs_out = gf_bs_from_file(out, GF_BITSTREAM_WRITE);

	orig_box_overhead = 0;
	final_box_overhead = 0;
	while (gf_bs_available(bs_in)) {
		u32 size = gf_bs_read_u32(bs_in);
		u32 type = gf_bs_read_u32(bs_in);
		const char *b4cc = gf_4cc_to_str(type);
		const u8 *replace = (const u8 *) strstr(compress_top_boxes, b4cc);
		if (!strcmp(b4cc, "moov")) has_mov = GF_TRUE;

		if (!replace && !replace_all) {
			gf_bs_write_u32(bs_out, size);
			gf_bs_write_u32(bs_out, type);

			size-=8;
			while (size) {
				u32 nbytes = size;
				if (nbytes>buf_alloc) nbytes=buf_alloc;
				gf_bs_read_data(bs_in, buf, nbytes);
				gf_bs_write_data(bs_out, buf, nbytes);
				size-=nbytes;
			}
			continue;
		}
		orig_box_overhead += size;

		size-=8;

		if (size>buf_alloc) {
			buf_alloc = size;
			buf = gf_realloc(buf, buf_alloc);
		}
		gf_bs_read_data(bs_in, buf, size);

		replace+=5;

		comp_size = buf_alloc;

		e = gf_gz_compress_payload(&buf, size, &comp_size);
		if (e) break;

		if (comp_size>buf_alloc) {
			buf_alloc = comp_size;
		}
		bytes_uncomp += size;
		bytes_comp += comp_size;

		//write size
		gf_bs_write_u32(bs_out, comp_size+8);
		//write type
		gf_bs_write_data(bs_out, replace, 4);
		//write data
		gf_bs_write_data(bs_out, buf, comp_size);

		final_box_overhead += 8+comp_size;
	}
	dst_size = gf_bs_get_position(bs_out);

	if (buf) gf_free(buf);
	gf_bs_del(bs_in);
	gf_bs_del(bs_out);
	gf_fclose(in);
	gf_fclose(out);
	if (e) {
		M4_LOG(GF_LOG_ERROR, ("Error compressing: %s\n", gf_error_to_string(e)));
		return e;
	}

	if (has_mov) {
		u32 i, nb_tracks, nb_samples;
		GF_ISOFile *mov;
		Double rate, new_rate, duration;

		mov = gf_isom_open(inName, GF_ISOM_OPEN_READ, NULL);
		duration = (Double) gf_isom_get_duration(mov);
		duration /= gf_isom_get_timescale(mov);

		nb_samples = 0;
		nb_tracks = gf_isom_get_track_count(mov);
		for (i=0; i<nb_tracks; i++) {
			nb_samples += gf_isom_get_sample_count(mov, i+1);
		}
		gf_isom_close(mov);

		rate = (Double) source_size;
		rate /= duration;
		rate /= 1000;

		new_rate = (Double) dst_size;
		new_rate /= duration;
		new_rate /= 1000;


		fprintf(stderr, "Log format:\nname\torig\tcomp\tgain\tadded_bytes\torate\tcrate\tsamples\tduration\tobbps\tcbbps\n");
		fprintf(stdout, "%s\t%d\t%d\t%g\t%d\t%g\t%g\t%d\t%g\t%g\t%g\n", inName, bytes_uncomp, bytes_comp, ((Double)(bytes_uncomp-bytes_comp)*100)/bytes_uncomp, nb_added_box_bytes, rate, new_rate, nb_samples, duration, ((Double)orig_box_overhead)/nb_samples, ((Double)final_box_overhead)/nb_samples );

		fprintf(stderr, "%s Compressing top-level boxes saved %d bytes out of %d (reduced by %g %%) additional bytes %d original rate %g kbps new rate %g kbps, orig %g box bytes/sample final %g bytes/sample\n", inName, bytes_uncomp-bytes_comp, bytes_uncomp, ((Double)(bytes_uncomp-bytes_comp)*100)/bytes_uncomp, nb_added_box_bytes, rate, new_rate, ((Double)orig_box_overhead)/nb_samples, ((Double)final_box_overhead)/nb_samples );

	} else {
		fprintf(stderr, "Log format:\nname\torig\tcomp\tgain\tadded_bytes\n");
		fprintf(stdout, "%s\t%d\t%d\t%g\t%d\n", inName, bytes_uncomp, bytes_comp, ((Double) (bytes_uncomp - bytes_comp)*100)/(bytes_uncomp), nb_added_box_bytes);

		fprintf(stderr, "%s Compressing top-level boxes saved %d bytes out of %d (reduced by %g %%) additional bytes %d\n", inName, bytes_uncomp-bytes_comp, bytes_uncomp, ((Double)(bytes_uncomp-bytes_comp)*100)/bytes_uncomp, nb_added_box_bytes);

	}
	return GF_OK;
}

Project: gpac

GF_Err afra_box_read(GF_Box *s, GF_BitStream *bs)
{
	unsigned int i;
	GF_AdobeFragRandomAccessBox *ptr = (GF_AdobeFragRandomAccessBox *)s;

	ISOM_DECREASE_SIZE(ptr, 9)
	ptr->long_ids = gf_bs_read_int(bs, 1);
	ptr->long_offsets = gf_bs_read_int(bs, 1);
	ptr->global_entries = gf_bs_read_int(bs, 1);
	ptr->reserved = gf_bs_read_int(bs, 5);
	ptr->time_scale = gf_bs_read_u32(bs);

	ptr->entry_count = gf_bs_read_u32(bs);
	if (ptr->size / ( (ptr->long_offsets ? 16 : 12) ) < ptr->entry_count)
		return GF_ISOM_INVALID_FILE;

	for (i=0; i<ptr->entry_count; i++) {
		GF_AfraEntry *ae = gf_malloc(sizeof(GF_AfraEntry));
		if (!ae) return GF_OUT_OF_MEM;
		gf_list_insert(ptr->local_access_entries, ae, i);

		ISOM_DECREASE_SIZE(ptr, 8)
		ae->time = gf_bs_read_u64(bs);
		if (ptr->long_offsets) {
			ISOM_DECREASE_SIZE(ptr, 8)
			ae->offset = gf_bs_read_u64(bs);
		} else {
			ISOM_DECREASE_SIZE(ptr, 4)
			ae->offset = gf_bs_read_u32(bs);
		}
	}

	if (ptr->global_entries) {
		ISOM_DECREASE_SIZE(ptr, 4)
		ptr->global_entry_count = gf_bs_read_u32(bs);
		for (i=0; i<ptr->global_entry_count; i++) {
			GF_GlobalAfraEntry *ae = gf_malloc(sizeof(GF_GlobalAfraEntry));
			if (!ae) return GF_OUT_OF_MEM;
			gf_list_insert(ptr->global_access_entries, ae, i);

			ISOM_DECREASE_SIZE(ptr, 8)
			ae->time = gf_bs_read_u64(bs);
			if (ptr->long_ids) {
				ISOM_DECREASE_SIZE(ptr, 8)
				ae->segment = gf_bs_read_u32(bs);
				ae->fragment = gf_bs_read_u32(bs);
			} else {
				ISOM_DECREASE_SIZE(ptr, 4)
				ae->segment = gf_bs_read_u16(bs);
				ae->fragment = gf_bs_read_u16(bs);
			}
			if (ptr->long_offsets) {
				ISOM_DECREASE_SIZE(ptr, 16)
				ae->afra_offset = gf_bs_read_u64(bs);
				ae->offset_from_afra = gf_bs_read_u64(bs);
			} else {
				ISOM_DECREASE_SIZE(ptr, 8)
				ae->afra_offset = gf_bs_read_u32(bs);
				ae->offset_from_afra = gf_bs_read_u32(bs);
			}
		}
	}

	return GF_OK;
}

Project: gpac
File: main.c

static Bool PrintHelpArg(char *arg_name, u32 search_type, GF_FilterSession *fs)
{
	Bool first=GF_TRUE;
	GF_GPACArg an_arg;
	u32 i, count;
	u32 res = 0;
	u32 alen = (u32) strlen(arg_name);
	res += PrintHelpForArgs(arg_name, m4b_gen_args, NULL, search_type);
	res += PrintHelpForArgs(arg_name, m4b_split_args, NULL, search_type);
	res += PrintHelpForArgs(arg_name, m4b_dash_args, NULL, search_type);
	res += PrintHelpForArgs(arg_name, m4b_imp_args, NULL, search_type);
	res += PrintHelpForArgs(arg_name, m4b_imp_fileopt_args, NULL, search_type);
	res += PrintHelpForArgs(arg_name, m4b_senc_args, NULL, search_type);
	res += PrintHelpForArgs(arg_name, m4b_crypt_args, NULL, search_type);
	res += PrintHelpForArgs(arg_name, m4b_hint_args, NULL, search_type);
	res += PrintHelpForArgs(arg_name, m4b_extr_args, NULL, search_type);
	res += PrintHelpForArgs(arg_name, m4b_dump_args, NULL, search_type);
	res += PrintHelpForArgs(arg_name, m4b_meta_args, NULL, search_type);
	res += PrintHelpForArgs(arg_name, m4b_swf_args, NULL, search_type);
	res += PrintHelpForArgs(arg_name, m4b_liveenc_args, NULL, search_type);
	res += PrintHelpForArgs(arg_name, m4b_usage_args, NULL, search_type);
	res += PrintHelpForArgs(arg_name, NULL, (GF_GPACArg *) gf_sys_get_options(), search_type);

	if (!fs) return res;

	memset(&an_arg, 0, sizeof(GF_GPACArg));
	count = gf_fs_filters_registers_count(fs);
	for (i=0; i<count; i++) {
		u32 j=0;
		const GF_FilterRegister *reg = gf_fs_get_filter_register(fs, i);

		while (reg->args) {
			u32 len;
			const GF_FilterArgs *arg = &reg->args[j];
			if (!arg || !arg->arg_name) break;
			j++;
			if ((search_type==SEARCH_ARG_EXACT) && strcmp(arg->arg_name, arg_name)) continue;

			if ((search_type==SEARCH_ARG_CLOSE) && !gf_sys_word_match(arg->arg_name, arg_name)) continue;

			if (search_type==SEARCH_DESC) {
				if (!strstr_nocase(arg->arg_desc, arg_name, alen)) continue;
			}

			an_arg.name = arg->arg_name;
			if (search_type==SEARCH_ARG_EXACT) {
				an_arg.description = arg->arg_desc;
				switch (arg->arg_type) {
				case GF_PROP_BOOL:
					an_arg.type = GF_ARG_BOOL;
					break;
				case GF_PROP_UINT:
				case GF_PROP_SINT:
					an_arg.type = GF_ARG_INT;
					break;
				case GF_PROP_DOUBLE:
					an_arg.type = GF_ARG_DOUBLE;
					break;
				case GF_PROP_STRING_LIST:
				case GF_PROP_UINT_LIST:
				case GF_PROP_SINT_LIST:
				case GF_PROP_VEC2I_LIST:
					an_arg.type = GF_ARG_STRINGS;
					break;
				case GF_PROP_4CC:
					an_arg.type = GF_ARG_4CC;
					break;
				case GF_PROP_4CC_LIST:
					an_arg.type = GF_ARG_4CCS;
					break;
				default:
					an_arg.type = GF_ARG_STRING;
					break;
				}
				if (first) {
					first = GF_FALSE;
					gf_sys_format_help(helpout, 0, "\nGlobal filter session arguments. Syntax is `--arg` or `--arg=VAL`. `[F]` indicates filter name. See `gpac -h` and `gpac -h F` for more info.\n");
				}
				fprintf(helpout, "[%s]", reg->name);
				len = (u32)strlen(reg->name);
				while (len<10) {
					len++;
					fprintf(helpout, " ");
				}
				fprintf(helpout, " ");
			}

			gf_sys_print_arg(helpout, GF_PRINTARG_ADD_DASH, &an_arg, "TEST");
			res++;
		}
	}
	if (res) return GF_TRUE;
	return GF_FALSE;
}

Project: gpac
File: main.c

u32 parse_comp_box(char *arg_val, u32 opt)
{
	compress_top_boxes = arg_val;
	size_top_box = opt;
	return 0;
}

Project: gpac
File: main.c

Bool mp4box_parse_single_arg(int argc, char **argv, char *arg, u32 *arg_index)
{
	if (mp4box_parse_single_arg_class(argc, argv, arg, arg_index, m4b_gen_args)) return GF_TRUE;
	if (mp4box_parse_single_arg_class(argc, argv, arg, arg_index, m4b_split_args)) return GF_TRUE;
	if (mp4box_parse_single_arg_class(argc, argv, arg, arg_index, m4b_dash_args)) return GF_TRUE;
	if (mp4box_parse_single_arg_class(argc, argv, arg, arg_index, m4b_imp_args)) return GF_TRUE;
	if (mp4box_parse_single_arg_class(argc, argv, arg, arg_index, m4b_senc_args)) return GF_TRUE;
	if (mp4box_parse_single_arg_class(argc, argv, arg, arg_index, m4b_crypt_args)) return GF_TRUE;
	if (mp4box_parse_single_arg_class(argc, argv, arg, arg_index, m4b_hint_args)) return GF_TRUE;
	if (mp4box_parse_single_arg_class(argc, argv, arg, arg_index, m4b_extr_args)) return GF_TRUE;
	if (mp4box_parse_single_arg_class(argc, argv, arg, arg_index, m4b_dump_args)) return GF_TRUE;
	if (mp4box_parse_single_arg_class(argc, argv, arg, arg_index, m4b_meta_args)) return GF_TRUE;
	if (mp4box_parse_single_arg_class(argc, argv, arg, arg_index, m4b_swf_args)) return GF_TRUE;
	if (mp4box_parse_single_arg_class(argc, argv, arg, arg_index, m4b_liveenc_args)) return GF_TRUE;
	if (mp4box_parse_single_arg_class(argc, argv, arg, arg_index, m4b_usage_args)) return GF_TRUE;

	return GF_FALSE;
}

Project: gpac
File: main.c

u32 parse_base_url(char *arg_val, u32 opt)
{
	mpd_base_urls = gf_realloc(mpd_base_urls, (nb_mpd_base_urls + 1)*sizeof(char**));
	if (!mpd_base_urls) return 2;
	mpd_base_urls[nb_mpd_base_urls] = arg_val;
	nb_mpd_base_urls++;
	return 0;
}

Project: gpac
File: main.c

u32 parse_cryp(char *arg_val, u32 opt)
{
	open_edit = GF_TRUE;
	if (!opt) {
		crypt = 1;
		drm_file = arg_val;
		open_edit = GF_TRUE;
		return 0;
	}
	crypt = 2;
	if (arg_val && get_file_type_by_ext(arg_val) != 1) {
		drm_file = arg_val;
		return 0;
	}
	return 3;
}

Project: gpac
File: main.c

u32 parse_store_mode(char *arg_val, u32 opt)
{
	do_save = GF_TRUE;
	if ((opt == 0) || (opt == 1)) {
		interleaving_time = atof(arg_val) / 1000;
		if (!interleaving_time) do_flat = 2;
		open_edit = GF_TRUE;
		no_inplace = GF_TRUE;
		if (opt==1) old_interleave = 1;
	} else if (opt==2) {
		interleaving_time = atof(arg_val);
		do_frag = GF_TRUE;
	} else {
		force_new = 2;
		interleaving_time = 0.5;
		do_flat = 1;
	}
	return 0;
}

Project: gpac
File: main.c

static GF_Err do_dash()
{
	GF_Err e;
	u32 i;
	Bool del_file = GF_FALSE;
	char szMPD[GF_MAX_PATH], *sep;
	char szStateFile[GF_MAX_PATH];
	Bool dyn_state_file = GF_FALSE;
	u32 do_abort = 0;
	GF_DASHSegmenter *dasher=NULL;

	if (crypt) {
		M4_LOG(GF_LOG_ERROR, ("MP4Box cannot use -crypt and -dash in the same pass. Please encrypt your content first, or specify encryption filters on dash sources.\n"));
		return GF_BAD_PARAM;
	}

	strcpy(outfile, outName ? outName : gf_url_get_resource_name(inName) );
	sep = strrchr(outfile, '.');
	if (sep) sep[0] = 0;
	if (!outName) strcat(outfile, "_dash");
	strcpy(szMPD, outfile);
	if (outName && sep) {
		sep[0] = '.';
		strcat(szMPD, sep);
	} else {
		strcat(szMPD, ".mpd");
	}

	if ((dash_subduration>0) && (dash_duration > dash_subduration)) {
		M4_LOG(GF_LOG_WARNING, ("Warning: -subdur parameter (%g s) should be greater than segment duration (%g s), using segment duration instead\n", dash_subduration, dash_duration));
		dash_subduration = dash_duration;
	}

	if (dash_mode && dash_live)
		M4_LOG(GF_LOG_INFO, ("Live DASH-ing - press 'q' to quit, 's' to save context and quit\n"));

	if (!dash_ctx_file && dash_live) {
		u32 r1;
		u64 add = (u64) (intptr_t) &dasher;
		add ^= gf_net_get_utc();
		r1 = (u32) add ^ (u32) (add/0xFFFFFFFF);
		r1 ^= gf_rand();
		sprintf(szStateFile, "%s/dasher_%X.xml", gf_get_default_cache_directory(), r1 );
		dash_ctx_file = szStateFile;
		dyn_state_file = GF_TRUE;
	} else if (dash_ctx_file) {
		if (force_new)
			gf_file_delete(dash_ctx_file);
	}

	if (dash_profile==GF_DASH_PROFILE_AUTO)
		dash_profile = dash_mode ? GF_DASH_PROFILE_LIVE : GF_DASH_PROFILE_FULL;

	if (!dash_mode) {
		time_shift_depth = 0;
		mpd_update_time = 0;
	} else if ((dash_profile>=GF_DASH_PROFILE_MAIN) && !use_url_template && !mpd_update_time) {
		/*use a default MPD update of dash_duration sec*/
		mpd_update_time = (Double) (dash_subduration ? dash_subduration : dash_duration);
		M4_LOG(GF_LOG_INFO, ("Using default MPD refresh of %g seconds\n", mpd_update_time));
	}

	if (file && do_save) {
		gf_isom_close(file);
		file = NULL;
		del_file = GF_TRUE;
	}

	/*setup dash*/
	dasher = gf_dasher_new(szMPD, dash_profile, NULL, dash_scale, dash_ctx_file);
	if (!dasher) {
		return mp4box_cleanup(1);
	}
	e = gf_dasher_set_info(dasher, dash_title, cprt, dash_more_info, dash_source, NULL);
	if (e) {
		M4_LOG(GF_LOG_ERROR, ("DASH Error: %s\n", gf_error_to_string(e)));
		gf_dasher_del(dasher);
		return e;
	}

	gf_dasher_set_start_date(dasher, dash_start_date);
	gf_dasher_set_location(dasher, dash_source);
	for (i=0; i < nb_mpd_base_urls; i++) {
		e = gf_dasher_add_base_url(dasher, mpd_base_urls[i]);
		if (e) {
			M4_LOG(GF_LOG_ERROR, ("DASH Error: %s\n", gf_error_to_string(e)));
			gf_dasher_del(dasher);
			return e;
		}
	}

	if (segment_timeline && !use_url_template) {
		M4_LOG(GF_LOG_WARNING, ("DASH Warning: using -segment-timeline with no -url-template. Forcing URL template.\n"));
		use_url_template = GF_TRUE;
	}

	e = gf_dasher_enable_url_template(dasher, (Bool) use_url_template, seg_name, seg_ext, init_seg_ext);
	if (!e) e = gf_dasher_enable_segment_timeline(dasher, segment_timeline);
	if (!e) e = gf_dasher_enable_single_segment(dasher, single_segment);
	if (!e) e = gf_dasher_enable_single_file(dasher, single_file);
	if (!e) e = gf_dasher_set_switch_mode(dasher, bitstream_switching_mode);
	if (!e) e = gf_dasher_set_durations(dasher, dash_duration, interleaving_time, dash_subduration);
	if (!e) e = gf_dasher_enable_rap_splitting(dasher, seg_at_rap, frag_at_rap);
	if (!e) e = gf_dasher_set_segment_marker(dasher, segment_marker);
	if (!e) e = gf_dasher_enable_sidx(dasher, (subsegs_per_sidx>=0) ? 1 : 0, (u32) subsegs_per_sidx, daisy_chain_sidx, use_ssix);
	if (!e) e = gf_dasher_set_dynamic_mode(dasher, dash_mode, mpd_update_time, time_shift_depth, mpd_live_duration);
	if (!e) e = gf_dasher_set_min_buffer(dasher, min_buffer);
	if (!e) e = gf_dasher_set_ast_offset(dasher, ast_offset_ms);
	if (!e) e = gf_dasher_enable_memory_fragmenting(dasher, memory_frags);
	if (!e) e = gf_dasher_set_initial_isobmf(dasher, initial_moof_sn, initial_tfdt);
	if (!e) e = gf_dasher_configure_isobmf_default(dasher, no_fragments_defaults, pssh_mode, samplegroups_in_traf, single_traf_per_moof, tfdt_per_traf, mvex_after_traks, sdtp_in_traf);
	if (!e) e = gf_dasher_enable_utc_ref(dasher, insert_utc);
	if (!e) e = gf_dasher_enable_real_time(dasher, frag_real_time);
	if (!e) e = gf_dasher_set_content_protection_location_mode(dasher, cp_location_mode);
	if (!e) e = gf_dasher_set_profile_extension(dasher, dash_profile_extension);
	if (!e) e = gf_dasher_enable_cached_inputs(dasher, no_cache);
	if (!e) e = gf_dasher_enable_loop_inputs(dasher, ! no_loop);
	if (!e) e = gf_dasher_set_split_mode(dasher, dash_split_mode);
	if (!e) e = gf_dasher_set_last_segment_merge(dasher, merge_last_seg);
	if (!e) e = gf_dasher_set_hls_clock(dasher, hls_clock);
	if (!e && dash_cues) e = gf_dasher_set_cues(dasher, dash_cues, strict_cues);
	if (!e) e = gf_dasher_print_session_info(dasher, fs_dump_flags);
	if (!e)  e = gf_dasher_keep_source_utc(dasher, keep_utc);

	for (i=0; i < nb_dash_inputs; i++) {
		if (!e) e = gf_dasher_add_input(dasher, &dash_inputs[i]);
	}
	if (e) {
		M4_LOG(GF_LOG_ERROR, ("DASH Setup Error: %s\n", gf_error_to_string(e)));
		gf_dasher_del(dasher);
		return e;
	}

	dash_cumulated_time=0;

	while (1) {
		if (run_for && (dash_cumulated_time >= run_for)) {
			M4_LOG(GF_LOG_INFO, ("Done running, computing static MPD\n"));
			do_abort = 3;
		}

		dash_prev_time=gf_sys_clock();
		if (do_abort>=2) {
			e = gf_dasher_set_dynamic_mode(dasher, GF_DASH_DYNAMIC_LAST, 0, time_shift_depth, mpd_live_duration);
		}

		if (!e) e = gf_dasher_process(dasher);
		if (!dash_live && (e==GF_EOS) ) {
			M4_LOG(GF_LOG_INFO, ("Nothing to dash, too early ...\n"));
			e = GF_OK;
		}

		if (do_abort)
			break;

		//this happens when reading file while writing them (local playback of the live session ...)
		if (dash_live && (e==GF_IO_ERR) ) {
			M4_LOG(GF_LOG_WARNING, ("Error dashing file (%s) but continuing ...\n", gf_error_to_string(e) ));
			e = GF_OK;
		}

		if (e) break;

		if (dash_live) {
			u64 ms_in_session=0;
			u32 slept = gf_sys_clock();
			u32 sleep_for = gf_dasher_next_update_time(dasher, &ms_in_session);
			M4_LOG(GF_LOG_INFO, ("Next generation scheduled in %u ms (DASH time "LLU" ms)\r", sleep_for, ms_in_session));
			if (run_for && (ms_in_session>=run_for)) {
				dash_cumulated_time = 1+run_for;
				continue;
			}

			while (1) {
				if (gf_prompt_has_input()) {
					char c = (char) gf_prompt_get_char();
					if (c=='X') {
						do_abort = 1;
						break;
					}
					if (c=='q') {
						do_abort = 2;
						break;
					}
					if (c=='s') {
						do_abort = 3;
						break;
					}
				}

				if (dash_mode == GF_DASH_DYNAMIC_DEBUG) {
					break;
				}
				if (!sleep_for) break;

				gf_sleep(sleep_for/10);
				sleep_for = gf_dasher_next_update_time(dasher, NULL);
				if (sleep_for<=1) {
					dash_now_time=gf_sys_clock();
					dash_cumulated_time+=(dash_now_time-dash_prev_time);
					M4_LOG(GF_LOG_INFO, ("Slept for %d ms before generation, dash cumulated time %d\n", dash_now_time - slept, dash_cumulated_time));
					break;
				}
			}
		} else {
			break;
		}
	}

	gf_dasher_del(dasher);

	if (!run_for && dash_ctx_file && (do_abort==3) && (dyn_state_file) && !gf_sys_is_test_mode() ) {
		char szName[1024];
		M4_LOG(GF_LOG_INFO, ("Enter file name to save dash context:\n"));
		if (scanf("%1023s", szName) == 1) {
			gf_file_move(dash_ctx_file, szName);
		}
	}
	if (e) M4_LOG(GF_LOG_ERROR, ("Error DASHing file: %s\n", gf_error_to_string(e)));
	if (file) gf_isom_delete(file);
	if (del_file)
		gf_file_delete(inName);

	return e;
}

Project: gpac
File: main.c

u32 parse_sdp_ext(char *arg_val, u32 param)
{
	char *id;
	sdp_lines = gf_realloc(sdp_lines, sizeof(SDPLine) * (nb_sdp_ex + 1));
	if (!sdp_lines) return 2;
	id = strchr(arg_val, ':');
	if (id) {
		id[0] = 0;
		if (sscanf(arg_val, "%u", &sdp_lines[0].trackID) == 1) {
			id[0] = ':';
			sdp_lines[nb_sdp_ex].line = id + 1;
		}
		else {
			id[0] = ':';
			sdp_lines[nb_sdp_ex].line = arg_val;
			sdp_lines[nb_sdp_ex].trackID = 0;
		}
	}
	else {
		sdp_lines[nb_sdp_ex].line = arg_val;
		sdp_lines[nb_sdp_ex].trackID = 0;
	}
	open_edit = GF_TRUE;
	nb_sdp_ex++;
	return GF_FALSE;
}

Project: gpac
File: main.c

static void set_sdp_ext()
{
	u32 i, j;
	for (i=0; i<nb_sdp_ex; i++) {
		if (sdp_lines[i].trackID) {
			u32 track = gf_isom_get_track_by_id(file, sdp_lines[i].trackID);
			if (gf_isom_get_media_type(file, track)!=GF_ISOM_MEDIA_HINT) {
				s32 ref_count;
				u32 k, count = gf_isom_get_track_count(file);
				for (j=0; j<count; j++) {
					if (gf_isom_get_media_type(file, j+1)!=GF_ISOM_MEDIA_HINT) continue;
					ref_count = gf_isom_get_reference_count(file, j+1, GF_ISOM_REF_HINT);
					if (ref_count<0) continue;
					for (k=0; k<(u32) ref_count; k++) {
						u32 refTk;
						if (gf_isom_get_reference(file, j+1, GF_ISOM_REF_HINT, k+1, &refTk)) continue;
						if (refTk==track) {
							track = j+1;
							j=count;
							break;
						}
					}
				}
			}
			gf_isom_sdp_add_track_line(file, track, sdp_lines[i].line);
			do_save = GF_TRUE;
		} else {
			gf_isom_sdp_add_line(file, sdp_lines[i].line);
			do_save = GF_TRUE;
		}
	}
}

Project: gpac
File: main.c

u32 parse_dashlive(char *arg, char *arg_val, u32 opt)
{
	dash_mode = opt ? GF_DASH_DYNAMIC_DEBUG : GF_DASH_DYNAMIC;
	dash_live = 1;
	if (arg[10] == '=') {
		dash_ctx_file = arg + 11;
	}
	dash_duration = atof(arg_val);
	return 0;
}

Project: gpac
File: main.c

void PrintSWFUsage()
{
	u32 i=0;
	gf_sys_format_help(helpout, help_flags, "# SWF Importer Options\n"
	        "\n"
	        "MP4Box can import simple Macromedia Flash files (\".SWF\")\n"
	        "You can specify a SWF input file with \'-bt\', \'-xmt\' and \'-mp4\' options\n"
	        "  \n"
	        "Options:\n"
	);
	while (m4b_swf_args[i].name) {
		GF_GPACArg *arg = (GF_GPACArg *) &m4b_swf_args[i];
		i++;
		gf_sys_print_arg(helpout, help_flags, arg, "mp4box-extract");
	}
}

Project: gpac
File: main.c

u32 parse_rap_ref(char *arg_val, u32 opt)
{
	if (arg_val) {
		if (sscanf(arg_val, "%d", &trackID) == 1) {
			parse_track_action(arg_val, opt ? TRAC_ACTION_REM_NON_REFS : TRAC_ACTION_REM_NON_RAP);
		}
	}
	hint_flags |= GP_RTP_PCK_SIGNAL_RAP;
	seg_at_rap = 1;
	return 0;
}

Project: gpac
File: main.c

u32 parse_track_dump(char *arg, u32 dump_type)
{
	if (!create_new_track_action(arg, TRAC_ACTION_RAW_EXTRACT, dump_type))
		return 2;
	track_dump_type = dump_type;
	return 0;
}

Project: gpac

static GF_Err do_itunes_tag()
{
	GF_Err e;
	char *itunes_data = NULL;
	char *tags = itunes_tags;

	if (gf_file_exists(itunes_tags)) {
		u32 len;
		e = gf_file_load_data(itunes_tags, (u8 **) &itunes_data, &len);
		if (e) return e;;
		tags = itunes_data;
	}

	while (tags) {
		char *val;
		Bool clear = GF_FALSE;
		Bool is_wma = GF_FALSE;
		u32 tlen, tagtype=0, itag = 0;
		s32 tag_idx=-1;
		char *sep = itunes_data ? strchr(tags, '\n') : gf_url_colon_suffix(tags);
		while (sep) {
			char *eq = strchr(sep+1, '=');
			if (eq) eq[0] = 0;
			s32 next_tag_idx = gf_itags_find_by_name(sep+1);
			if ((next_tag_idx<0) && strlen(sep+1)==4)
				next_tag_idx = 0;

			if (eq) eq[0] = '=';
			if (next_tag_idx>=0) {
				sep[0] = 0;
				break;
			}
			sep = itunes_data ? strchr(sep+1, '\n') : gf_url_colon_suffix(sep+1);
		}
		val = strchr(tags, '=');
		if (val) val[0] = 0;
		if (!strcmp(tags, "clear") || !strcmp(tags, "reset")) {
			clear = GF_TRUE;
		} else if (!strncmp(tags, "WM/", 3) ) {
			is_wma = GF_TRUE;
		} else {
			tag_idx = gf_itags_find_by_name(tags);
			if (tag_idx<0) {
				if (strlen(tags)==4) {
					itag = GF_4CC(tags[0], tags[1], tags[2], tags[3]);
					tagtype = GF_ITAG_STR;
				} else if (strlen(tags)==3) {
					itag = GF_4CC(0xA9, tags[0], tags[1], tags[2]);
					tagtype = GF_ITAG_STR;
				}
			}
		}
		if (val) {
			val[0] = '=';
			val++;
		}
		if (!itag && !clear && !is_wma) {
			if (tag_idx<0) {
				M4_LOG(GF_LOG_WARNING, ("Invalid iTune tag name \"%s\" - ignoring\n", tags));
				break;
			}
			itag = gf_itags_get_itag(tag_idx);
			tagtype = gf_itags_get_type(tag_idx);
		}
		if (!val || (val[0]==':') || !val[0] || !stricmp(val, "NULL") ) val = NULL;

		tlen = val ? (u32) strlen(val) : 0;
		if (clear) {
			e = gf_isom_apple_set_tag(file, GF_ISOM_ITUNE_RESET, NULL, 0, 0, 0);
		}
		else if (is_wma) {
			if (val) val[-1] = 0;
			e = gf_isom_wma_set_tag(file, tags, val);
			if (val) val[-1] = '=';
		}
		else if (val && (tagtype==GF_ITAG_FILE)) {
			u32 flen = (u32) strlen(val);
			u8 *d=NULL;
			while (flen && val[flen-1]=='\n') flen--;
			val[flen] = 0;
			e = gf_file_load_data(val, (u8 **) &d, &tlen);
			val[flen] = '\n';

			if (!e)
				e = gf_isom_apple_set_tag(file, itag, d, tlen, 0, 0);

			if (d) gf_free(d);
		} else {
			e = gf_isom_apple_set_tag(file, itag, (u8 *) val, tlen, 0, 0);
		}
		if (e) {
			M4_LOG(GF_LOG_ERROR, ("Error assigning tag %s: %s\n", tags, gf_error_to_string(e) ));
		}

		do_save = GF_TRUE;

		if (sep) {
			sep[0] = itunes_data ? '\n' : ':';
			tags = sep+1;
		} else {
			tags = NULL;
		}
	}
	if (itunes_data) gf_free(itunes_data);
	return GF_OK;
}

Project: gpac

u32 parse_fps(char *arg_val, u32 opt)
{
	u32 ticks, dts_inc;
	if (!strcmp(arg_val, "auto")) {
		M4_LOG(GF_LOG_WARNING, ("Warning, fps=auto option is deprecated\n"));
	}
	else if ((sscanf(arg_val, "%u-%u", &ticks, &dts_inc)==2) || (sscanf(arg_val, "%u/%u", &ticks, &dts_inc)==2) ) {
		if (!dts_inc) dts_inc = 1;
		import_fps.num = ticks;
		import_fps.den = dts_inc;
	} else {
		gf_parse_frac(arg_val, &import_fps);
	}
	return 0;
}

Project: gpac

u32 parse_split(char *arg_val, u32 opt)
{
	switch (opt) {
	case 0://-split
		split_duration = atof(arg_val);
		if (split_duration < 0) split_duration = 0;
		split_size = 0;
		break;
	case 1: //-split-rap, -splitr
		split_duration = -1;
		split_size = -1;
		break;
	case 2: //-split-size, -splits
		split_size = (u32)atoi(arg_val);
		split_duration = 0;
		break;
	case 3: //-split-chunk, -splitx
	case 4: //-splitz
	case 5: //-splitg
	case 6: //-splitf
		adjust_split_end = opt-3;
		if (!strstr(arg_val, ":") && !strstr(arg_val, "-")) {
			M4_LOG(GF_LOG_ERROR, ("Chunk extraction usage: \"-split* start:end\" expressed in seconds\n"));
			return 2;
		}
		if (strstr(arg_val, "end")) {
			if (strstr(arg_val, "end-")) {
				Double dur_end=0;
				sscanf(arg_val, "%lf:end-%lf", &split_start, &dur_end);
				split_duration = -2 - dur_end;
			} else {
				sscanf(arg_val, "%lf:end", &split_start);
				split_duration = -2;
			}
		} else {
			split_range_str = arg_val;
		}
		split_size = 0;
		break;
	}
	return 0;
}

Project: gpac
File: main.c

u32 parse_sdtp(char *arg_val, u32 opt)
{
	if (!stricmp(arg_val, "both")) sdtp_in_traf = 2;
	else if (!stricmp(arg_val, "sdtp")) sdtp_in_traf = 1;
	else sdtp_in_traf = 0;
	return 0;
}

Project: gpac
File: main.c

u32 parse_track_action(char *arg, u32 act_type)
{
	if (!create_new_track_action(arg, act_type, 0)) {
		return 2;
	}
	return 0;
}

Project: gpac
File: main.c

u32 mp4box_parse_single_arg_class(int argc, char **argv, char *arg, u32 *arg_index, MP4BoxArg *arg_class)
{
	MP4BoxArg *arg_desc = NULL;
	char *arg_val = NULL;
	u32 i=0;
	while (arg_class[i].name) {
		arg_desc = (MP4BoxArg *) &arg_class[i];
		i++;

#ifdef TEST_ARGS
		char *sep = strchr(arg_desc->name, ' ');
		if (sep) {
			M4_LOG(GF_LOG_ERROR, ("Invalid arg %s, space not allowed\n", arg_desc->name));
			exit(1);
		}
#endif
		if (!strcmp(arg_desc->name, arg+1))
			break;
		if (arg_desc->altname && !strcmp(arg_desc->altname, arg+1))
			break;

		if (arg_desc->parse_flags & ARG_IS_FUN2) {
			if (!strncmp(arg_desc->name, arg+1, strlen(arg_desc->name) ))
				break;
		}
		arg_desc = NULL;
	}
	if (!arg_desc)
		return GF_FALSE;

	if (arg_desc->parse_flags & ARG_OPEN_EDIT) open_edit = GF_TRUE;
	if (arg_desc->parse_flags & ARG_NEED_SAVE) do_save = GF_TRUE;
	if (arg_desc->parse_flags & ARG_NO_INPLACE) no_inplace = GF_TRUE;

	if (arg_desc->type != GF_ARG_BOOL) {
		Bool has_next = GF_TRUE;
		if (*arg_index + 1 == (u32) argc)
			has_next = GF_FALSE;
		else if (argv[*arg_index + 1][0] == '-') {
			s32 v;
			if (sscanf(argv[*arg_index + 1], "%d", &v)!=1)
				has_next = GF_FALSE;
		}
		if (!has_next && ! (arg_desc->parse_flags & ARG_EMPTY) ) {
			M4_LOG(GF_LOG_ERROR, ("Missing argument value for %s - please check usage\n", arg));
			arg_parse_res = 2;
			return GF_TRUE;
		}

		if (has_next && (arg_desc->parse_flags & ARG_EMPTY) && (arg_desc->type==GF_ARG_INT)) {
			s32 ival;
			if (sscanf(argv[*arg_index + 1], "%d", &ival) != 1) {
				has_next = GF_FALSE;
				arg_val = NULL;
			}
		}
		if (has_next) {
			has_next_arg = GF_TRUE;
			*arg_index += 1;
			arg_val = argv[*arg_index];
		}
	}
	if (!arg_desc->arg_ptr) return GF_TRUE;

	if (arg_desc->parse_flags & (ARG_IS_FUN|ARG_IS_FUN2) ) {
		u32 res;
		if (arg_desc->parse_flags & ARG_PUSH_SYSARGS)
			gf_sys_set_args(argc, (const char**) argv);

		if (arg_desc->parse_flags & ARG_IS_FUN) {
			parse_arg_fun fun = (parse_arg_fun) arg_desc->arg_ptr;
			res = fun(arg_val, arg_desc->argv_val);
		} else {
			parse_arg_fun2 fun2 = (parse_arg_fun2) arg_desc->arg_ptr;
			res = fun2(arg, arg_val, arg_desc->argv_val);
		}
		//rewind, not our arg
		if ((res==3) && argv) {
			*arg_index -= 1;
			res = 0;
		}
		arg_parse_res = res;
		return GF_TRUE;
	}

	if (arg_desc->parse_flags & ARG_INT_INC) {
		* (u32 *) arg_desc->arg_ptr += 1;
		return GF_TRUE;
	}

	if (arg_desc->type == GF_ARG_BOOL) {
		if (!arg_desc->parse_flags) {
			if (arg_desc->argv_val) {
				* (u32 *) arg_desc->arg_ptr = arg_desc->argv_val;
			} else {
				* (Bool *) arg_desc->arg_ptr = GF_TRUE;
			}
		} else if (arg_desc->parse_flags & ARG_BOOL_REV) {
			* (Bool *) arg_desc->arg_ptr = GF_FALSE;
		} else if (arg_desc->parse_flags & ARG_HAS_VALUE) {
			* (u32 *) arg_desc->arg_ptr = 0;
		} else if (arg_desc->parse_flags & ARG_BIT_MASK) {
			* (u32 *) arg_desc->arg_ptr |= arg_desc->argv_val;
		} else if (arg_desc->parse_flags & ARG_BIT_MASK_REM) {
			* (u32 *) arg_desc->arg_ptr &= ~arg_desc->argv_val;
		} else if (arg_desc->argv_val) {
			* (u32 *) arg_desc->arg_ptr = arg_desc->argv_val;
		} else {
			* (u32 *) arg_desc->arg_ptr = GF_TRUE;
		}
		return GF_TRUE;
	}

	if (arg_desc->type == GF_ARG_STRING) {
		if (arg_desc->parse_flags & ARG_IS_4CC) {
			u32 alen = arg_val ? (u32) strlen(arg_val) : 0;
			if ((alen<3) || (alen>4)) {
				M4_LOG(GF_LOG_ERROR, ("Value for %s must be a 4CC, %s is not - please check usage\n", arg, arg_val));
				arg_parse_res = 2;
				return GF_TRUE;
			}
			* (u32 *) arg_desc->arg_ptr = GF_4CC(arg_val[0], arg_val[1], arg_val[2], arg_val[3]);
			return GF_TRUE;
		}

		* (char **) arg_desc->arg_ptr = arg_val;
		return GF_TRUE;
	}
	if (!arg_val) {
		M4_LOG(GF_LOG_ERROR, ("Missing value for %s - please check usage\n", arg));
		arg_parse_res = 2;
		return GF_TRUE;
	}

	if (arg_desc->type == GF_ARG_DOUBLE) {
		Double v = atof(arg_val);
		if (arg_desc->parse_flags & ARG_DIV_1000) {
			v /= 1000;
		}
		if ((arg_desc->parse_flags & ARG_NON_ZERO) && !v) {
			M4_LOG(GF_LOG_ERROR, ("Value for %s shall not be 0 - please check usage\n", arg));
			arg_parse_res = 2;
			return GF_TRUE;
		}
		* (Double *) arg_desc->arg_ptr = v;
		return GF_TRUE;
	}

	if (arg_desc->type != GF_ARG_INT) {
		M4_LOG(GF_LOG_ERROR, ("Unsupported argument type for %s - please report to gpac devs\n", arg));
		arg_parse_res = 2;
		return GF_TRUE;
	}
	if (arg_desc->parse_flags & ARG_64BITS) {
		u64 v;
		sscanf(arg_val, LLU, &v);
		if (arg_desc->parse_flags & ARG_DIV_1000) {
			v /= 1000;
		}
		if ((arg_desc->parse_flags & ARG_NON_ZERO) && !v) {
			M4_LOG(GF_LOG_ERROR, ("Value for %s shall not be 0 - please check usage\n", arg));
			arg_parse_res = 2;
			return GF_TRUE;
		}
		* (u64 *) arg_desc->arg_ptr = v;
	} else {
		u32 v = atoi(arg_val);
		if (arg_desc->parse_flags & ARG_DIV_1000) {
			v /= 1000;
		}
		if ((arg_desc->parse_flags & ARG_NON_ZERO) && !v) {
			M4_LOG(GF_LOG_ERROR, ("Value for %s shall not be 0 - please check usage\n", arg));
			arg_parse_res = 2;
			return GF_TRUE;
		}
		* (s32 *) arg_desc->arg_ptr = v;
	}
	return GF_TRUE;
}

Project: gpac
File: main.c

static u32 convert_mpd()
{
	GF_Err e;
	Bool remote = GF_FALSE;
	GF_MPD *mpd;
	char *mpd_base_url = NULL;
	if (!strnicmp(inName, "http://", 7) || !strnicmp(inName, "https://", 8)) {
#if !defined(GPAC_DISABLE_CORE_TOOLS)
		e = gf_dm_wget(inName, "tmp_main.m3u8", 0, 0, &mpd_base_url);
		if (e != GF_OK) {
			M4_LOG(GF_LOG_ERROR, ("Cannot retrieve M3U8 (%s): %s\n", inName, gf_error_to_string(e)));
			if (mpd_base_url) gf_free(mpd_base_url);
			return mp4box_cleanup(1);
		}
		remote = GF_TRUE;
#else
		gf_free(mpd_base_url);
		M4_LOG(GF_LOG_ERROR, ("HTTP Downloader disabled in this build\n"));
		return mp4box_cleanup(1);
#endif

		if (outName)
			strcpy(outfile, outName);
		else {
			const char *sep = gf_file_basename(inName);
			char *ext = gf_file_ext_start(sep);
			if (ext) ext[0] = 0;
			sprintf(outfile, "%s.mpd", sep);
			if (ext) ext[0] = '.';
		}
	} else {
		if (outName)
			strcpy(outfile, outName);
		else {
			char *dst = strdup(inName);
			char *ext = strstr(dst, ".m3u8");
			if (ext) ext[0] = 0;
			sprintf(outfile, "%s.mpd", dst);
			gf_free(dst);
		}
	}

	mpd = gf_mpd_new();
	if (!mpd) {
		e = GF_OUT_OF_MEM;
		M4_LOG(GF_LOG_ERROR, ("[DASH] Error: MPD creation problem %s\n", gf_error_to_string(e)));
		mp4box_cleanup(1);
	}
	FILE *f = gf_fopen(remote ? "tmp_main.m3u8" : inName, "r");
	u32 manif_type = 0;
	if (f) {
		char szDATA[1000];
		s32 read;
		szDATA[999]=0;
		read = (s32) gf_fread(szDATA, 999, f);
		if (read<0) read = 0;
		szDATA[read]=0;
		gf_fclose(f);
		if (strstr(szDATA, "SmoothStreamingMedia"))
			manif_type = 2;
		else if (strstr(szDATA, "#EXTM3U"))
			manif_type = 1;
	}

	if (manif_type==1) {
		e = gf_m3u8_to_mpd(remote ? "tmp_main.m3u8" : inName, mpd_base_url ? mpd_base_url : inName, outfile, 0, "video/mp2t", GF_TRUE, use_url_template, segment_timeline, NULL, mpd, GF_TRUE, GF_TRUE);
	} else if (manif_type==2) {
		e = gf_mpd_smooth_to_mpd(remote ? "tmp_main.m3u8" : inName, mpd, mpd_base_url ? mpd_base_url : inName);
	} else {
		e = GF_NOT_SUPPORTED;
	}
	if (!e)
		gf_mpd_write_file(mpd, outfile);

	if (mpd)
		gf_mpd_del(mpd);
	if (mpd_base_url)
		gf_free(mpd_base_url);

	if (remote) {
		gf_file_delete("tmp_main.m3u8");
	}
	if (e != GF_OK) {
		M4_LOG(GF_LOG_ERROR, ("Error converting %s (%s) to MPD (%s): %s\n", (manif_type==1) ? "HLS" : "Smooth",  inName, outfile, gf_error_to_string(e)));
		return mp4box_cleanup(1);
	} else {
		M4_LOG(GF_LOG_INFO, ("Done converting %s (%s) to MPD (%s)\n", (manif_type==1) ? "HLS" : "Smooth",  inName, outfile));
		return mp4box_cleanup(0);
	}
}

Project: gpac

u32 parse_gendoc(char *name, u32 opt)
{
	u32 i=0;
	//gen MD
	if (!opt) {
		help_flags = GF_PRINTARG_MD | GF_PRINTARG_IS_APP;
		helpout = gf_fopen("mp4box-gen-opts.md", "w");

		fprintf(helpout, "[**HOME**](Home) » [**MP4Box**](MP4Box) » General");
		fprintf(helpout, "<!-- automatically generated - do not edit, patch gpac/applications/mp4box/main.c -->\n");
		fprintf(helpout, "# Syntax\n");
		gf_sys_format_help(helpout, help_flags, "MP4Box [option] input [option] [other_dash_inputs]\n"
			"  \n"
		);
		PrintGeneralUsage();
		PrintEncryptUsage();
		fprintf(helpout, "# Help Options\n");
		while (m4b_usage_args[i].name) {
			GF_GPACArg *g_arg = (GF_GPACArg *) &m4b_usage_args[i];
			i++;
			gf_sys_print_arg(helpout, help_flags, g_arg, "mp4box-general");
		}

		gf_fclose(helpout);

		helpout = gf_fopen("mp4box-import-opts.md", "w");
		fprintf(helpout, "[**HOME**](Home) » [**MP4Box**](MP4Box) » Media Import");
		fprintf(helpout, "<!-- automatically generated - do not edit, patch gpac/applications/mp4box/main.c -->\n");
		PrintImportUsage();
		gf_fclose(helpout);

		helpout = gf_fopen("mp4box-dash-opts.md", "w");
		fprintf(helpout, "[**HOME**](Home) » [**MP4Box**](MP4Box) » Media DASH");
		fprintf(helpout, "<!-- automatically generated - do not edit, patch gpac/applications/mp4box/main.c -->\n");
		PrintDASHUsage();
		gf_fclose(helpout);

		helpout = gf_fopen("mp4box-dump-opts.md", "w");
		fprintf(helpout, "[**HOME**](Home) » [**MP4Box**](MP4Box) » Media Dump and Export");
		fprintf(helpout, "<!-- automatically generated - do not edit, patch gpac/applications/mp4box/main.c -->\n");
		PrintExtractUsage();
		PrintDumpUsage();
		PrintSplitUsage();
		gf_fclose(helpout);

		helpout = gf_fopen("mp4box-meta-opts.md", "w");
		fprintf(helpout, "[**HOME**](Home) » [**MP4Box**](MP4Box) » Meta and HEIF/IFF");
		fprintf(helpout, "<!-- automatically generated - do not edit, patch gpac/applications/mp4box/main.c -->\n");
		PrintMetaUsage();
		gf_fclose(helpout);


		helpout = gf_fopen("mp4box-scene-opts.md", "w");
		fprintf(helpout, "[**HOME**](Home) » [**MP4Box**](MP4Box) » Scene Description");
		fprintf(helpout, "<!-- automatically generated - do not edit, patch gpac/applications/mp4box/main.c -->\n");
		PrintEncodeUsage();
#if !defined(GPAC_DISABLE_STREAMING) && !defined(GPAC_DISABLE_SENG)
		PrintLiveUsage();
#endif
		PrintSWFUsage();
		gf_fclose(helpout);

		helpout = gf_fopen("mp4box-other-opts.md", "w");
		fprintf(helpout, "[**HOME**](Home) » [**MP4Box**](MP4Box) » Other Features");
		fprintf(helpout, "<!-- automatically generated - do not edit, patch gpac/applications/mp4box/main.c -->\n");
		PrintHintUsage();
		PrintTags();
		gf_fclose(helpout);
	}
	//gen man
	else {
		help_flags = GF_PRINTARG_MAN;
		helpout = gf_fopen("mp4box.1", "w");


		fprintf(helpout, ".TH MP4Box 1 2019 MP4Box GPAC\n");
		fprintf(helpout, ".\n.SH NAME\n.LP\nMP4Box \\- GPAC command-line media packager\n.SH SYNOPSIS\n.LP\n.B MP4Box\n.RI [options] \\ [file] \\ [options]\n.br\n.\n");

		PrintGeneralUsage();
		PrintExtractUsage();
		PrintDASHUsage();
		PrintSplitUsage();
		PrintDumpUsage();
		PrintImportUsage();
		PrintHintUsage();
		PrintEncodeUsage();
		PrintEncryptUsage();
		PrintMetaUsage();
		PrintSWFUsage();
		PrintTags();
#if !defined(GPAC_DISABLE_STREAMING) && !defined(GPAC_DISABLE_SENG)
		PrintLiveUsage();
#endif

		fprintf(helpout, ".SH EXAMPLES\n.TP\nBasic and advanced examples are available at https://wiki.gpac.io/MP4Box\n");
		fprintf(helpout, ".SH MORE\n.LP\nAuthors: GPAC developers, see git repo history (-log)\n"
		".br\nFor bug reports, feature requests, more information and source code, visit https://github.com/gpac/gpac\n"
		".br\nbuild: %s\n"
		".br\nCopyright: %s\n.br\n"
		".SH SEE ALSO\n"
		".LP\ngpac(1), MP4Client(1)\n", gf_gpac_version(), gf_gpac_copyright());

		gf_fclose(helpout);
	}
	return 1;
}

Project: gpac
File: main.c

u32 parse_file_info(char *arg_val, u32 opt)
{
	print_info = opt ? 2 : 1;
	if (arg_val) {
		if (sscanf(arg_val, "%u", &info_track_id) == 1) {
			char szTk[20];
			sprintf(szTk, "%u", info_track_id);
			if (strcmp(szTk, arg_val)) info_track_id = 0;
		}
		if (!info_track_id) return 3;
	}
	return 0;
}

Project: gpac

static void PrintSplitUsage()
{
	u32 i=0;
	gf_sys_format_help(helpout, help_flags, "  \n"
		"# File splitting\n"
		"MP4Box can split input files by size, duration or extract a given part of the file to new IsoMedia file(s).\n"
		"This requires that at most one track in the input file has non random-access points (typically one video track at most).\n"
		"Splitting will ignore all MPEG-4 Systems tracks and hint tracks, but will try to split private media tracks.\n"
		"The input file must have enough random access points in order to be split. If this is not the case, you will have to re-encode the content.\n"
		"You can add media to a file and split it in the same pass. In this case, the destination file (the one which would be obtained without splitting) will not be stored.\n"
		"  \n"
		"Time ranges are specified as follows:\n"
		"- `S-E`: `S` start and `E` end times, formatted as `HH:MM:SS.ms`, `MM:SS.ms` or time in seconds (int, double, fraction)\n"
		"- `S:E`: `S` start time and `E` end times in seconds (int, double, fraction)\n"
		"- `S:end` or `S:end-N`: `S` start time in seconds (int, double), `N` number of seconds (int, double) before the end\n"
		"  \n"
		"MP4Box splitting runs a filter session using the `reframer` filter as follows:\n"
		"- `splitrange` option of the reframer is always set\n"
		"- source is demuxed with `alltk` option set\n"
		"- start and end ranges are passed to `xs` and `xe` options of the reframer\n"
		"- for `-splitz`, options `xadjust` and `xround=after` are enforced\n"
		"- for `-splitg`, options `xadjust` and `xround=before` are enforced\n"
		"- for `-splitf`, option `xround=seek` is enforced and `propbe_ref`set if not specified at prompt\n"
		"- for `-splitx`, option `xround=closest` and `propbe_ref` are enforced if not specified at prompt\n"
		"  \n"
		"The output file(s) storage mode can be specified using -flat, -newfs, -inter and -frag\n"
		"  \n"
	);

	i=0;
	while (m4b_split_args[i].name) {
		GF_GPACArg *arg = (GF_GPACArg *) &m4b_split_args[i];
		i++;
		gf_sys_print_arg(helpout, help_flags, arg, "mp4box-split");
	}

}

Project: gpac
File: main.c

static u32 do_raw_cat()
{
	char chunk[4096];
	FILE *fin, *fout;
	s64 to_copy, done;
	fin = gf_fopen(raw_cat, "rb");
	if (!fin) return mp4box_cleanup(1);

	fout = gf_fopen(inName, "a+b");
	if (!fout) {
		gf_fclose(fin);
		return mp4box_cleanup(1);
	}
	gf_fseek(fin, 0, SEEK_END);
	to_copy = gf_ftell(fin);
	gf_fseek(fin, 0, SEEK_SET);
	done = 0;
	while (1) {
		u32 nb_bytes = (u32) gf_fread(chunk, 4096, fin);
		gf_fwrite(chunk, nb_bytes, fout);
		done += nb_bytes;
		fprintf(stderr, "Appending file %s - %02.2f done\r", raw_cat, 100.0*done/to_copy);
		if (done >= to_copy) break;
	}
	gf_fclose(fin);
	gf_fclose(fout);
	return mp4box_cleanup(0);
}

Project: gpac
File: main.c

static Bool strstr_nocase(const char *text, const char *subtext, u32 subtext_len)
{
	if (!*text || !subtext || !subtext_len)
		return GF_FALSE;

	while (*text) {
		if (tolower(*text) == *subtext) {
			if (!strnicmp(text, subtext, subtext_len))
				return GF_TRUE;

		}
		text++;
	}
	return GF_FALSE;
}

Project: gpac
File: main.c

static u32 do_import_sub()
{
	/* We import the subtitle file,
	   i.e. we parse it and store the content as samples of a 3GPP Timed Text track in an ISO file,
	   possibly for later export (e.g. when converting SRT to TTXT, ...) */
#ifndef GPAC_DISABLE_MEDIA_IMPORT
	GF_Err e;
	GF_MediaImporter import;
	/* Prepare the importer */
	file = gf_isom_open("ttxt_convert", GF_ISOM_OPEN_WRITE, NULL);
	if (timescale && file) gf_isom_set_timescale(file, timescale);

	memset(&import, 0, sizeof(GF_MediaImporter));
	import.dest = file;
	import.in_name = inName;
	/* Start the import */
	e = gf_media_import(&import);
	if (e) {
		M4_LOG(GF_LOG_ERROR, ("Error importing %s: %s\n", inName, gf_error_to_string(e)));
		gf_isom_delete(file);
		gf_file_delete("ttxt_convert");
		return mp4box_cleanup(1);
	}
	/* Prepare the export */
	strcpy(outfile, inName);
	if (strchr(outfile, '.')) {
		while (outfile[strlen(outfile)-1] != '.') outfile[strlen(outfile)-1] = 0;
		outfile[strlen(outfile)-1] = 0;
	}
#ifndef GPAC_DISABLE_ISOM_DUMP
	/* Start the export of the track #1, in the appropriate dump type, indicating it's a conversion */
	dump_isom_timed_text(file, gf_isom_get_track_id(file, 1),
						  dump_std ? NULL : (outName ? outName : outfile), outName ? GF_TRUE : GF_FALSE,
						  GF_TRUE,
						  (import_subtitle==2) ? GF_TEXTDUMPTYPE_SVG : (dump_srt ? GF_TEXTDUMPTYPE_SRT : GF_TEXTDUMPTYPE_TTXT));
#endif
	/* Clean the importer */
	gf_isom_delete(file);
	gf_file_delete("ttxt_convert");
	if (e) {
		M4_LOG(GF_LOG_ERROR, ("Error converting %s: %s\n", inName, gf_error_to_string(e)));
		return mp4box_cleanup(1);
	}
	return mp4box_cleanup(0);
#else
	M4_LOG(GF_LOG_ERROR, ("Feature not supported\n"));
	return mp4box_cleanup(1);
#endif
}

Project: gpac
File: main.c

static GF_Err do_tsel_act()
{
	u32 i;
	GF_Err e;
	for (i=0; i<nb_tsel_acts; i++) {
		switch (tsel_acts[i].act_type) {
		case TSEL_ACTION_SET_PARAM:
			e = gf_isom_set_track_switch_parameter(file,
			                                       gf_isom_get_track_by_id(file, tsel_acts[i].trackID),
			                                       tsel_acts[i].refTrackID ? gf_isom_get_track_by_id(file, tsel_acts[i].refTrackID) : 0,
			                                       tsel_acts[i].is_switchGroup ? 1 : 0,
			                                       &tsel_acts[i].switchGroupID,
			                                       tsel_acts[i].criteria, tsel_acts[i].nb_criteria);
			if (e == GF_BAD_PARAM) {
				u32 alternateGroupID, nb_groups;
				gf_isom_get_track_switch_group_count(file, gf_isom_get_track_by_id(file, tsel_acts[i].trackID), &alternateGroupID, &nb_groups);
				if (alternateGroupID) {
					M4_LOG(GF_LOG_ERROR, ("Error - for adding more tracks to group, using: -group-add -refTrack=ID1:[criteria:]trackID=ID2\n"));
				} else {
					M4_LOG(GF_LOG_ERROR, ("Error - for creating a new grouping information, using -group-add -trackID=ID1:[criteria:]trackID=ID2\n"));
				}
			}
			if (e) return e;
			do_save = GF_TRUE;
			break;
		case TSEL_ACTION_REMOVE_TSEL:
			e = gf_isom_reset_track_switch_parameter(file, gf_isom_get_track_by_id(file, tsel_acts[i].trackID), 0);
			if (e) return e;
			do_save = GF_TRUE;
			break;
		case TSEL_ACTION_REMOVE_ALL_TSEL_IN_GROUP:
			e = gf_isom_reset_track_switch_parameter(file, gf_isom_get_track_by_id(file, tsel_acts[i].trackID), 1);
			if (e) return e;
			do_save = GF_TRUE;
			break;
		default:
			break;
		}
	}
	return GF_OK;
}

Project: gpac
File: main.c

void PrintHintUsage()
{
	u32 i=0;
	gf_sys_format_help(helpout, help_flags, "# Hinting Options\n"
		"IsoMedia hinting consists in creating special tracks in the file that contain transport protocol specific information and optionally multiplexing information. These tracks are then used by the server to create the actual packets being sent over the network, in other words they provide the server with hints on how to build packets, hence their names `hint tracks`.\n"
		"MP4Box supports creation of hint tracks for RTSP servers supporting these such as QuickTime Streaming Server, DarwinStreaming Server or 3GPP-compliant RTSP servers.\n"
		"Note: GPAC streaming tools [rtp output](rtpout) and [rtsp server](rtspout) do not use hint tracks, they use on-the-fly packetization "
		"from any media sources, not just MP4\n"
		"  \n"
		"Options:\n"
	);
	while (m4b_hint_args[i].name) {
		GF_GPACArg *arg = (GF_GPACArg *) &m4b_hint_args[i];
		i++;
		gf_sys_print_arg(helpout, help_flags, arg, "mp4box-hint");
	}
}

Project: gpac
File: main.c

void PrintTags()
{
	u32 i = 0;

	gf_sys_format_help(helpout, help_flags, "# Tagging support\n"
	"Tags are specified as a colon-separated list `tag_name=tag_value[:tag2=val2]`\n"
	"Setting a tag with no value or value `NULL` removes the tag.\n"
	"Special tag value `clear` (or `reset`) removes all tags.\n"
	"Unsupported tags can be added using their four character code as a tag name, and string value will be assumed.\n"
	"If the tag name length is 3, the prefix 0xA9 is used to create the four character code.\n"
	"  \n"
	"Tags can also be loaded from a text file using `-itags filename`. The file must be in UTF8 with:\n"
	"- lines starting with `tag_name=value` specify the start of a tag\n"
	"- other lines specify the remainder of the last declared tag\n"
	"  \n"
	"If tag name starts with `WM/`, the tag is added to `Xtra` box (WMA tag, string only).\n"
	"  \n"
	"Supported tag names, values, types, aliases:\n"
	);

	while (1) {
		s32 type = gf_itags_get_type(i);
		if (type<0) break;
		const char *name = gf_itags_get_name(i);
		u32 itag = gf_itags_get_itag(i);
		gf_sys_format_help(helpout, help_flags | GF_PRINTARG_HIGHLIGHT_FIRST , "%s", name);
		gf_sys_format_help(helpout, help_flags, " (%s) ", gf_4cc_to_str(itag) );
		switch (type) {
		case GF_ITAG_STR:
			gf_sys_format_help(helpout, help_flags, "string"); break;
		case GF_ITAG_INT8:
		case GF_ITAG_INT16:
		case GF_ITAG_INT32:
		case GF_ITAG_INT64:
			gf_sys_format_help(helpout, help_flags, "integer"); break;
		case GF_ITAG_FRAC6:
		case GF_ITAG_FRAC8:
			gf_sys_format_help(helpout, help_flags, "fraction (syntax: `A/B` or `A`, B will be 0)"); break;
		case GF_ITAG_BOOL:
			gf_sys_format_help(helpout, help_flags, "bool (`yes` or `no`)"); break;
		case GF_ITAG_ID3_GENRE:
			gf_sys_format_help(helpout, help_flags, "string (ID3 genre tag)"); break;
		case GF_ITAG_FILE:
			gf_sys_format_help(helpout, help_flags, "file path"); break;
		}
		name = gf_itags_get_alt_name(i);
		if (name) {
			gf_sys_format_help(helpout, help_flags, " (`alias` %s)", name);
		}

		gf_sys_format_help(helpout, help_flags, "\n");
		i++;
	}
}

Project: gpac
File: main.c

static Bool parse_tsel_args(char *opts, TSELActionType act)
{
	GF_ISOTrackID refTrackID = 0;
	Bool has_switch_id;
	u32 switch_id = 0;
	u32 criteria[30];
	u32 nb_criteria = 0;
	TSELAction *tsel_act;
	char szSlot[1024];

	has_switch_id = 0;

	if (!opts) return 0;
	while (1) {
		char *next;
		if (!opts || !opts[0]) return 0;
		if (opts[0]==':') opts += 1;
		strcpy(szSlot, opts);
		next = gf_url_colon_suffix(szSlot);
		if (next) next[0] = 0;


		if (!strnicmp(szSlot, "refTrack=", 9)) refTrackID = atoi(szSlot+9);
		else if (!strnicmp(szSlot, "switchID=", 9)) {
			if (atoi(szSlot+9)<0) {
				switch_id = 0;
				has_switch_id = 0;
			} else {
				switch_id = atoi(szSlot+9);
				has_switch_id = 1;
			}
		}
		else if (!strnicmp(szSlot, "switchID", 8)) {
			switch_id = 0;
			has_switch_id = 1;
		}
		else if (!strnicmp(szSlot, "criteria=", 9)) {
			u32 j=9;
			nb_criteria = 0;
			while (j+3<strlen(szSlot)) {
				criteria[nb_criteria] = GF_4CC(szSlot[j], szSlot[j+1], szSlot[j+2], szSlot[j+3]);
				j+=5;
				nb_criteria++;
			}
		}
		else if (!strnicmp(szSlot, "trackID=", 8) || !strchr(szSlot, '=') ) {
			tsel_acts = gf_realloc(tsel_acts, sizeof(TSELAction) * (nb_tsel_acts + 1));
			if (!tsel_acts) return 2;

			tsel_act = &tsel_acts[nb_tsel_acts];
			nb_tsel_acts++;

			memset(tsel_act, 0, sizeof(TSELAction));
			tsel_act->act_type = act;
			tsel_act->trackID = strchr(szSlot, '=') ? atoi(szSlot+8) : atoi(szSlot);
			tsel_act->refTrackID = refTrackID;
			tsel_act->switchGroupID = switch_id;
			tsel_act->is_switchGroup = has_switch_id;
			tsel_act->nb_criteria = nb_criteria;
			memcpy(tsel_act->criteria, criteria, sizeof(u32)*nb_criteria);

			if (!refTrackID)
				refTrackID = tsel_act->trackID;

			open_edit = GF_TRUE;
		}
		opts += strlen(szSlot);
	}
	return 0;
}

Project: gpac

GF_Err HintFile(GF_ISOFile *file, u32 MTUSize, u32 max_ptime, u32 rtp_rate, u32 base_flags, Bool copy_data, Bool interleave, Bool regular_iod, Bool single_group, Bool hint_no_offset)
{
	GF_ESD *esd;
	GF_InitialObjectDescriptor *iod;
	u32 i, val, res, streamType;
	u32 sl_mode, prev_ocr, single_ocr, nb_done, tot_bw, bw, flags, spec_type;
	GF_Err e;
	char szPayload[30];
	GF_RTPHinter *hinter;
	Bool copy, has_iod, single_av;
	u8 init_payt = BASE_PAYT;
	u32 mtype;
	GF_SDP_IODProfile iod_mode = GF_SDP_IOD_NONE;
	u32 media_group = 0;
	u8 media_prio = 0;

	tot_bw = 0;
	prev_ocr = 0;
	single_ocr = 1;

	has_iod = 1;
	iod = (GF_InitialObjectDescriptor *) gf_isom_get_root_od(file);
	if (!iod) has_iod = 0;
	else {
		if (!gf_list_count(iod->ESDescriptors)) has_iod = 0;
		gf_odf_desc_del((GF_Descriptor *) iod);
	}

	spec_type = gf_isom_guess_specification(file);
	single_av = single_group ? 1 : gf_isom_is_single_av(file);

	/*first make sure we use a systems track as base OCR*/
	for (i=0; i<gf_isom_get_track_count(file); i++) {
		res = gf_isom_get_media_type(file, i+1);
		if ((res==GF_ISOM_MEDIA_SCENE) || (res==GF_ISOM_MEDIA_OD)) {
			if (gf_isom_is_track_in_root_od(file, i+1)) {
				gf_isom_set_default_sync_track(file, i+1);
				break;
			}
		}
	}

	nb_done = 0;
	for (i=0; i<gf_isom_get_track_count(file); i++) {
		sl_mode = base_flags;
		copy = copy_data;
		/*skip emty tracks (mainly MPEG-4 interaction streams...*/
		if (!gf_isom_get_sample_count(file, i+1)) continue;
		if (!gf_isom_is_track_enabled(file, i+1)) {
			M4_LOG(GF_LOG_INFO, ("Track ID %d disabled - skipping hint\n", gf_isom_get_track_id(file, i+1) ));
			continue;
		}

		mtype = gf_isom_get_media_type(file, i+1);
		switch (mtype) {
		case GF_ISOM_MEDIA_VISUAL:
			if (single_av) {
				media_group = 2;
				media_prio = 2;
			}
			break;
        case GF_ISOM_MEDIA_AUXV:
            if (single_av) {
                media_group = 2;
                media_prio = 3;
            }
            break;
        case GF_ISOM_MEDIA_PICT:
            if (single_av) {
                media_group = 2;
                media_prio = 4;
            }
            break;
		case GF_ISOM_MEDIA_AUDIO:
			if (single_av) {
				media_group = 2;
				media_prio = 1;
			}
			break;
		case GF_ISOM_MEDIA_HINT:
			continue;
		default:
			/*no hinting of systems track on isma*/
			if (spec_type==GF_ISOM_BRAND_ISMA) continue;
		}
		mtype = gf_isom_get_media_subtype(file, i+1, 1);
		if ((mtype==GF_ISOM_SUBTYPE_MPEG4) || (mtype==GF_ISOM_SUBTYPE_MPEG4_CRYP) ) mtype = gf_isom_get_mpeg4_subtype(file, i+1, 1);

		if (!single_av) {
			/*one media per group only (we should prompt user for group selection)*/
			media_group ++;
			media_prio = 1;
		}

		streamType = 0;
		esd = gf_isom_get_esd(file, i+1, 1);
		if (esd && esd->decoderConfig) {
			streamType = esd->decoderConfig->streamType;
			if (!prev_ocr) {
				prev_ocr = esd->OCRESID;
				if (!esd->OCRESID) prev_ocr = esd->ESID;
			} else if (esd->OCRESID && prev_ocr != esd->OCRESID) {
				single_ocr = 0;
			}
			/*OD MUST BE WITHOUT REFERENCES*/
			if (streamType==1) copy = 1;
		}
		gf_odf_desc_del((GF_Descriptor *) esd);

		if (!regular_iod && gf_isom_is_track_in_root_od(file, i+1)) {
			/*single AU - check if base64 would fit in ESD (consider 33% overhead of base64), otherwise stream*/
			if (gf_isom_get_sample_count(file, i+1)==1) {
				GF_ISOSample *samp = gf_isom_get_sample(file, i+1, 1, &val);
				if (streamType && samp) {
					res = gf_hinter_can_embbed_data(samp->data, samp->dataLength, streamType);
				} else {
					/*not a system track, we shall hint it*/
					res = 0;
				}
				if (samp) gf_isom_sample_del(&samp);
				if (res) continue;
			}
		}
		if (interleave) sl_mode |= GP_RTP_PCK_USE_INTERLEAVING;

		hinter = gf_hinter_track_new(file, i+1, MTUSize, max_ptime, rtp_rate, sl_mode, init_payt, copy, media_group, media_prio, &e);

		if (!hinter) {
			if (e) {
				M4_LOG(nb_done ? GF_LOG_WARNING : GF_LOG_ERROR, ("Cannot create hinter (%s)\n", gf_error_to_string(e) ));
				if (!nb_done) return e;
			}
			continue;
		}

		if (hint_no_offset)
			gf_hinter_track_force_no_offsets(hinter);

		bw = gf_hinter_track_get_bandwidth(hinter);
		tot_bw += bw;
		flags = gf_hinter_track_get_flags(hinter);

		//set extraction mode for AVC/SVC
		gf_isom_set_nalu_extract_mode(file, i+1, GF_ISOM_NALU_EXTRACT_LAYER_ONLY);

		gf_hinter_track_get_payload_name(hinter, szPayload);
		M4_LOG(GF_LOG_INFO, ("Hinting track ID %d - Type \"%s:%s\" (%s) - BW %d kbps\n", gf_isom_get_track_id(file, i+1), gf_4cc_to_str(mtype), gf_4cc_to_str(mtype), szPayload, bw));
		if (flags & GP_RTP_PCK_SYSTEMS_CAROUSEL) M4_LOG(GF_LOG_INFO, ("\tMPEG-4 Systems stream carousel enabled\n"));
		e = gf_hinter_track_process(hinter);

		if (!e) e = gf_hinter_track_finalize(hinter, has_iod);
		gf_hinter_track_del(hinter);

		if (e) {
			M4_LOG(GF_LOG_ERROR, ("Error while hinting (%s)\n", gf_error_to_string(e)));
			if (!nb_done) return e;
		}
		init_payt++;
		nb_done ++;
	}

	if (has_iod) {
		iod_mode = GF_SDP_IOD_ISMA;
		if (regular_iod) iod_mode = GF_SDP_IOD_REGULAR;
	} else {
		iod_mode = GF_SDP_IOD_NONE;
	}
	gf_hinter_finalize(file, iod_mode, tot_bw);

	if (!single_ocr)
		M4_LOG(GF_LOG_WARNING, ("Warning: at least 2 timelines found in the file\nThis may not be supported by servers/players\n\n"));

	return GF_OK;
}

Project: gpac
File: main.c

static GF_Err do_dump_iod()
{
	GF_Err e = GF_OK;
	GF_InitialObjectDescriptor *iod = (GF_InitialObjectDescriptor *)gf_isom_get_root_od(file);
	if (!iod) {
		M4_LOG(GF_LOG_WARNING, ("File %s has no IOD\n", inName));
	} else {
		char szName[GF_MAX_PATH+10];
		FILE *iodf;
		sprintf(szName, "%s.iod", outfile);
		iodf = gf_fopen(szName, "wb");
		if (!iodf) {
			M4_LOG(GF_LOG_ERROR, ("Cannot open destination %s\n", szName));
			e = GF_IO_ERR;
		} else {
			u8 *desc;
			u32 size;
			GF_BitStream *bs = gf_bs_from_file(iodf, GF_BITSTREAM_WRITE);
			if (gf_odf_desc_write((GF_Descriptor *)iod, &desc, &size)==GF_OK) {
				gf_fwrite(desc, size, iodf);
				gf_free(desc);
			} else {
				M4_LOG(GF_LOG_ERROR, ("Error writing IOD %s\n", szName));
				e = GF_IO_ERR;
			}
			gf_bs_del(bs);
			gf_fclose(iodf);
		}
		gf_odf_desc_del((GF_Descriptor*)iod);
	}
	return e;
}

Project: gpac
File: main.c

void PrintEncodeUsage()
{
	u32 i=0;
	gf_sys_format_help(helpout, help_flags, "# MPEG-4 Scene Encoding Options\n"
		"## General considerations\n"
		"MP4Box supports encoding and decoding of of BT, XMT, VRML and (partially) X3D formats int MPEG-4 BIFS, and encoding and decoding of XSR and SVG into MPEG-4 LASeR\n"
		"Any media track specified through a `MuxInfo` element will be imported in the resulting MP4 file.\n"
		"See https://wiki.gpac.io/MPEG-4-BIFS-Textual-Format and related pages.\n"
		"## Scene Random Access\n"
		"MP4Box can encode BIFS or LASeR streams and insert random access points at a given frequency. This is useful when packaging content for broadcast, where users will not turn in the scene at the same time. In MPEG-4 terminology, this is called the __scene carousel__."
		"## BIFS Chunk Processing\n"
		"The BIFS chunk encoding mode alows encoding single BIFS access units from an initial context and a set of commands.\n"
		"The generated AUs are raw BIFS (not SL-packetized), in files called FILE-ESID-AUIDX.bifs, with FILE the basename of the input file.\n"
		"Commands with a timing of 0 in the input will modify the carousel version only (i.e. output context).\n"
		"Commands with a timing different from 0 in the input will generate new AUs.\n"
		"  \n"
		"Options:\n"
	);

	while (m4b_senc_args[i].name) {
		GF_GPACArg *arg = (GF_GPACArg *) &m4b_senc_args[i];
		i++;
		gf_sys_print_arg(helpout, help_flags, arg, "mp4box-senc");
	}
}

Project: gpac

int mp4boxMain(int argc, char **argv)
{
	u32 i, j;
	const char *gpac_profile = "0";
	GF_Err e = GF_OK;

#ifdef TEST_ARGS
	i=0;
	mp4box_parse_single_arg(argc, argv, "", &i);
#endif

	for (i = 1; i < (u32) argc ; i++) {
		if (!strcmp(argv[i], "-mem-track") || !strcmp(argv[i], "-mem-track-stack")) {
#ifdef GPAC_MEMORY_TRACKING
            mem_track = !strcmp(argv[i], "-mem-track-stack") ? GF_MemTrackerBackTrace : GF_MemTrackerSimple;
#else
			M4_LOG(GF_LOG_WARNING, ("WARNING - GPAC not compiled with Memory Tracker - ignoring \"%s\"\n", argv[i]));
#endif
			break;
		}
		else if (!strcmp(argv[i], "-p")) {
			if (i+1<(u32) argc)
				gpac_profile = argv[i+1];
			else {
				M4_LOG(GF_LOG_ERROR, ("Bad argument for -p, expecting profile name but no more args\n"));
				return 1;
			}
		}
		else if (!strncmp(argv[i], "-p=", 3))
			gpac_profile = argv[i]+3;
	}

#ifdef _TWO_DIGIT_EXPONENT
	_set_output_format(_TWO_DIGIT_EXPONENT);
#endif

	/*init libgpac*/
	gf_sys_init(mem_track, gpac_profile);
	if (argc < 2) {
		M4_LOG(GF_LOG_ERROR, ("Not enough arguments - check usage with -h\n"));
		M4_LOG(GF_LOG_INFO, ("MP4Box - GPAC version %s\n"
	        "%s\n", gf_gpac_version(), gf_gpac_copyright_cite() ));
		gf_sys_close();
		return 0;
	}

	helpout = stdout;

	i = mp4box_parse_args(argc, argv);
	if (i) {
		return mp4box_cleanup(i - 1);
	}
#if !defined(GPAC_DISABLE_STREAMING) && !defined(GPAC_DISABLE_SENG)
	if (live_scene) {
		int ret = live_session(argc, argv);
		return mp4box_cleanup(ret);
	}
#endif

	if (!dash_duration && interleaving_time && do_frag)
		interleaving_time /= 1000;

	if (do_mpd_conv) inName = do_mpd_conv;

	if (import_flags & GF_IMPORT_FORCE_MPEG4)
		hint_flags |= GP_RTP_PCK_FORCE_MPEG4;

	if (!inName && dump_std)
		inName = "std";

	if (!dash_duration && cprt)
		open_edit = GF_TRUE;

	if (!inName) {
		if (has_next_arg) {
			M4_LOG(GF_LOG_ERROR, ("Broken argument specifier or file name missing - check usage with -h\n"));
		} else {
			PrintUsage();
		}
		return mp4box_cleanup(1);
	}
	if (!strcmp(inName, "std")) dump_std = 2;
	if (!strcmp(inName, "stdb")) {
		inName = "std";
		dump_std = 1;
	}

	if (!interleaving_time) {
		/*by default use single fragment per dash segment*/
		if (dash_duration)
			interleaving_time = dash_duration;
		else if (!do_flat && !(split_duration || split_size || split_range_str)) {
			interleaving_time = DEFAULT_INTERLEAVING_IN_SEC;
		}
	}

	if (dump_std)
		outName = "std";

	if (dump_std==2) {
#ifdef WIN32
		if ( _setmode(_fileno(stdout), _O_BINARY) == -1 )
#else
		if ( freopen(NULL, "wb", stdout) == NULL)
#endif
		{
			M4_LOG(GF_LOG_ERROR, ("Fatal error: cannot reopen stdout in binary mode.\n"));
			return mp4box_cleanup(1);
		}
	}

	GF_LOG_Level level = verbose ? GF_LOG_DEBUG : GF_LOG_INFO;
	gf_log_set_tool_level(GF_LOG_CONTAINER, level);
	gf_log_set_tool_level(GF_LOG_SCENE, level);
	gf_log_set_tool_level(GF_LOG_PARSER, level);
	gf_log_set_tool_level(GF_LOG_AUTHOR, level);
	gf_log_set_tool_level(GF_LOG_CODING, level);
	gf_log_set_tool_level(GF_LOG_DASH, level);
#ifdef GPAC_MEMORY_TRACKING
	if (mem_track)
		gf_log_set_tool_level(GF_LOG_MEMORY, level);
#endif

	e = gf_sys_set_args(argc, (const char **) argv);
	if (e) {
		M4_LOG(GF_LOG_ERROR, ("Error assigning libgpac arguments: %s\n", gf_error_to_string(e) ));
		return mp4box_cleanup(1);
	}

	if (raw_cat)
		return do_raw_cat();

	if (compress_top_boxes) {
		if (size_top_box) {
			u64 top_size = do_size_top_boxes(inName, compress_top_boxes, size_top_box);
			fprintf(stdout, LLU"\n", top_size);
			return mp4box_cleanup(e ? 1 : 0);
		} else {
			e = do_compress_top_boxes(inName, outName);
			return mp4box_cleanup(e ? 1 : 0);
		}
	}

	if (do_mpd_rip) {
		e = rip_mpd(inName, outName);
		return mp4box_cleanup(e ? 1 : 0);
	}

#ifndef GPAC_DISABLE_CORE_TOOLS
	if (do_wget != NULL) {
		e = gf_dm_wget(do_wget, inName, 0, 0, NULL);
		if (e != GF_OK) {
			M4_LOG(GF_LOG_ERROR, ("Cannot retrieve %s: %s\n", do_wget, gf_error_to_string(e) ));
			return mp4box_cleanup(1);
		}
		return mp4box_cleanup(0);
	}
#endif

	if (udp_dest)
		return do_write_udp();

#ifndef GPAC_DISABLE_MPD
	if (do_mpd_conv)
		return convert_mpd();
#endif

	if (dash_duration && !nb_dash_inputs) {
		dash_inputs = set_dash_input(dash_inputs, inName, &nb_dash_inputs);
	}

	if (do_saf && !encode) {
		switch (get_file_type_by_ext(inName)) {
		case GF_FILE_TYPE_BT_WRL_X3DV:
		case GF_FILE_TYPE_XMT_X3D:
		case GF_FILE_TYPE_SVG:
			encode = GF_TRUE;
			break;
		case GF_FILE_TYPE_NOT_SUPPORTED:
		case GF_FILE_TYPE_ISO_MEDIA:
		case GF_FILE_TYPE_SWF:
		case GF_FILE_TYPE_LSR_SAF:
			break;
		}
	}

#ifndef GPAC_DISABLE_SCENE_DUMP
	if (dump_mode == GF_SM_DUMP_SVG) {
		if (strstr(inName, ".srt") || strstr(inName, ".ttxt")) import_subtitle = 2;
	}
#endif

	if (import_subtitle && !trackID)
		return do_import_sub();


#if !defined(GPAC_DISABLE_MEDIA_IMPORT) && !defined(GPAC_DISABLE_ISOM_WRITE)
	if (nb_add || nb_cat) {
		u32 res = do_add_cat(argc, argv);
		if (res) return res;
	}
#endif /*!GPAC_DISABLE_MEDIA_IMPORT && !GPAC_DISABLE_ISOM_WRITE*/

#if !defined(GPAC_DISABLE_ISOM_WRITE) && !defined(GPAC_DISABLE_SCENE_ENCODER) && !defined(GPAC_DISABLE_MEDIA_IMPORT)
	else if (chunk_mode) {
		if (!inName) {
			M4_LOG(GF_LOG_ERROR, ("chunk encoding syntax: [-outctx outDump] -inctx inScene auFile\n"));
			return mp4box_cleanup(1);
		}
		e = EncodeFileChunk(inName, outName ? outName : inName, input_ctx, output_ctx);
		if (e) {
			M4_LOG(GF_LOG_ERROR, ("Error encoding chunk file %s\n", gf_error_to_string(e)));
			return mp4box_cleanup(1);
		}
		goto exit;
	}
#endif // !defined(GPAC_DISABLE_ISOM_WRITE) && !defined(GPAC_DISABLE_SCENE_ENCODER) && !defined(GPAC_DISABLE_MEDIA_IMPORT)

	else if (encode) {
#if !defined(GPAC_DISABLE_ISOM_WRITE) && !defined(GPAC_DISABLE_SCENE_ENCODER) && !defined(GPAC_DISABLE_MEDIA_IMPORT)
		e = do_scene_encode();
		if (e) goto err_exit;
#endif //!defined(GPAC_DISABLE_ISOM_WRITE) && !defined(GPAC_DISABLE_SCENE_ENCODER) && !defined(GPAC_DISABLE_MEDIA_IMPORT)
	}

#ifndef GPAC_DISABLE_ISOM_WRITE
	else if (pack_file) {
		char *fileName = gf_url_colon_suffix(pack_file);
		if (fileName && ((fileName - pack_file)==4)) {
			fileName[0] = 0;
			file = package_file(fileName + 1, pack_file, pack_wgt);
			fileName[0] = ':';
		} else {
			file = package_file(pack_file, NULL, pack_wgt);
			if (!file) {
				M4_LOG(GF_LOG_ERROR, ("Failed to package file\n"));
				return mp4box_cleanup(1);
			}
		}
		if (!outName) outName = inName;
		do_save = GF_TRUE;
		open_edit = GF_TRUE;
	}
#endif //GPAC_DISABLE_ISOM_WRITE

	if (dash_duration) {
		e = do_dash();
		if (e) return mp4box_cleanup(1);
		goto exit;
	}

	if (split_duration || split_size || split_range_str) {
		if (force_new==2) {
			do_flat = 3;
			force_new = 0;
		}
	} else {
		if (do_flat)
			open_edit = GF_TRUE;
	}

	//need to open input
	if (!file && !do_hash) {
		FILE *st = gf_fopen(inName, "rb");
		Bool file_exists = 0;
		GF_ISOOpenMode omode;
		if (st) {
			file_exists = 1;
			gf_fclose(st);
		}
		switch (get_file_type_by_ext(inName)) {
		case 1:
			omode =  (u8) (force_new ? GF_ISOM_WRITE_EDIT : (open_edit ? GF_ISOM_OPEN_EDIT : ( ((dump_isom>0) || print_info) ? GF_ISOM_OPEN_READ_DUMP : GF_ISOM_OPEN_READ) ) );

			if (crypt) {
				//keep fragment signaling in moov
				omode = GF_ISOM_OPEN_READ;
				if (use_init_seg)
					file = gf_isom_open(use_init_seg, GF_ISOM_OPEN_READ, NULL);
			}
			if (!crypt && use_init_seg) {
				file = gf_isom_open(use_init_seg, GF_ISOM_OPEN_READ_DUMP, NULL);
				if (file) {
					e = gf_isom_open_segment(file, inName, 0, 0, 0);
					if (e==GF_ISOM_INCOMPLETE_FILE) {
						M4_LOG(GF_LOG_WARNING, ("Segment %s: %s\n", inName, gf_error_to_string(e) ));
					} else if (e) {
						M4_LOG(GF_LOG_ERROR, ("Error opening segment %s: %s\n", inName, gf_error_to_string(e) ));
						gf_isom_delete(file);
						file = NULL;
					}
				}
			}
			if (!file)
				file = gf_isom_open(inName, omode, NULL);

			if (!file && (gf_isom_last_error(NULL) == GF_ISOM_INCOMPLETE_FILE) && !open_edit) {
				u64 missing_bytes;
				gf_isom_open_progressive(inName, 0, 0, GF_FALSE, &file, &missing_bytes);
				if (missing_bytes)
					M4_LOG(GF_LOG_ERROR, ("Truncated file - missing "LLD" bytes\n", missing_bytes));
			}

			if (!file) {
				if (open_edit && nb_meta_act) {
					file = gf_isom_open(inName, GF_ISOM_WRITE_EDIT, NULL);
					if (!outName && file) outName = inName;
				}

				if (!file) {
					M4_LOG(GF_LOG_ERROR, ("Error opening file %s: %s\n", inName, gf_error_to_string(gf_isom_last_error(NULL))));
					return mp4box_cleanup(1);
				}
			}
			if (freeze_box_order)
				gf_isom_freeze_order(file);
			break;
		/*allowed for bt<->xmt*/
		case 2:
		case 3:
		/*allowed for svg->lsr**/
		case 4:
		/*allowed for swf->bt, swf->xmt, swf->svg*/
		case 5:
			break;
		/*used for .saf / .lsr dump*/
		case 6:
#ifndef GPAC_DISABLE_SCENE_DUMP
			if ((dump_mode==GF_SM_DUMP_LASER) || (dump_mode==GF_SM_DUMP_SVG)) {
				break;
			}
#endif

		default:
			if (!open_edit && file_exists && !gf_isom_probe_file(inName) && track_dump_type) {
			}
#ifndef GPAC_DISABLE_ISOM_WRITE
			else if (!open_edit && file_exists /* && !gf_isom_probe_file(inName) */
#ifndef GPAC_DISABLE_SCENE_DUMP
			         && dump_mode == GF_SM_DUMP_NONE
#endif //GPAC_DISABLE_SCENE_DUMP
			        ) {
				/*************************************************************************************************/
#ifndef GPAC_DISABLE_MEDIA_IMPORT
				if(dvbhdemux)
				{
					GF_MediaImporter import;
					file = gf_isom_open("ttxt_convert", GF_ISOM_OPEN_WRITE, NULL);
					memset(&import, 0, sizeof(GF_MediaImporter));
					import.dest = file;
					import.in_name = inName;
					import.flags = GF_IMPORT_MPE_DEMUX;
					e = gf_media_import(&import);
					if (e) {
						M4_LOG(GF_LOG_ERROR, ("Error importing %s: %s\n", inName, gf_error_to_string(e)));
						gf_isom_delete(file);
						gf_file_delete("ttxt_convert");
						return mp4box_cleanup(1);
					}
				}
#endif /*GPAC_DISABLE_MEDIA_IMPORT*/

				if (dump_m2ts) {
#ifndef GPAC_DISABLE_MPEG2TS
					dump_mpeg2_ts(inName, outName, program_number);
#endif
				} else if (dump_timestamps) {
#ifndef GPAC_DISABLE_MPEG2TS
					dump_mpeg2_ts(inName, outName, program_number);
#endif
#ifndef GPAC_DISABLE_CORE_TOOLS
				} else if (do_bin_xml) {
					xml_bs_to_bin(inName, outName, dump_std);
#endif
				} else if (do_hash) {
					hash_file(inName, dump_std);
				} else if (print_info) {
#ifndef GPAC_DISABLE_MEDIA_IMPORT
					convert_file_info(inName, info_track_id);
#endif
				} else {
					if (mux_name) {
						e = do_remux_file();
						if (e) goto err_exit;
						if (file) gf_isom_delete(file);
						goto exit;
					} else {
						M4_LOG(GF_LOG_ERROR, ("Input %s is not an MP4 file, operation not allowed\n", inName));
						return mp4box_cleanup(1);
					}
				}
				goto exit;
			}
#endif /*GPAC_DISABLE_ISOM_WRITE*/
			else if (open_edit) {
				file = gf_isom_open(inName, GF_ISOM_WRITE_EDIT, NULL);
				if (!outName && file) outName = inName;
			} else if (!file_exists) {
				M4_LOG(GF_LOG_ERROR, ("Error %s file %s: %s\n", force_new ? "creating" : "opening", inName, gf_error_to_string(GF_URL_ERROR)));
				return mp4box_cleanup(1);
			} else {
				M4_LOG(GF_LOG_ERROR, ("Cannot open %s - extension not supported\n", inName));
				return mp4box_cleanup(1);
			}
		}
	}

	if (high_dynamc_range_filename) {
		e = parse_high_dynamc_range_xml_desc(file, high_dynamc_range_filename);
		if (e) goto err_exit;
	}

	if (file && keep_utc) {
		gf_isom_keep_utc_times(file, 1);
	}

	if ( gf_strlcpy(outfile, outName ? outName : inName, sizeof(outfile)) >= sizeof(outfile) ) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("Filename too long (limit is %d)\n", GF_MAX_PATH));
		return mp4box_cleanup(1);
	}

	char *szExt = gf_file_ext_start(outfile);
	if (szExt) {
		/*turn on 3GP saving*/
		if (!stricmp(szExt, ".3gp") || !stricmp(szExt, ".3gpp") || !stricmp(szExt, ".3g2"))
			conv_type = GF_ISOM_CONV_TYPE_3GPP;
		else if (!stricmp(szExt, ".m4a") || !stricmp(szExt, ".m4v"))
			conv_type = GF_ISOM_CONV_TYPE_IPOD;
		else if (!stricmp(szExt, ".psp"))
			conv_type = GF_ISOM_CONV_TYPE_PSP;
		else if (!stricmp(szExt, ".mov") || !stricmp(szExt, ".qt"))
			conv_type = GF_ISOM_CONV_TYPE_MOV;

		//remove extension from outfile
		*szExt = 0;
	}

#ifndef GPAC_DISABLE_MEDIA_EXPORT
	if (!open_edit && track_dump_type && !gf_isom_probe_file(inName)) {
		e = do_export_tracks_non_isobmf();
		if (e) goto err_exit;
		goto exit;
	}
	if (mux_name) {
		e = do_remux_file();
		if (e) goto err_exit;
		if (file) gf_isom_delete(file);
		goto exit;
	}



#endif /*GPAC_DISABLE_MEDIA_EXPORT*/

#ifndef GPAC_DISABLE_SCENE_DUMP
	if (dump_mode != GF_SM_DUMP_NONE) {
		e = dump_isom_scene(inName, dump_std ? NULL : (outName ? outName : outfile), outName ? GF_TRUE : GF_FALSE, dump_mode, do_scene_log, no_odf_conf);
		if (e) goto err_exit;
	}
#endif

#ifndef GPAC_DISABLE_SCENE_STATS
	if (stat_level) dump_isom_scene_stats(inName, dump_std ? NULL : (outName ? outName : outfile), outName ? GF_TRUE : GF_FALSE, stat_level);
#endif

#ifndef GPAC_DISABLE_ISOM_HINTING
	if (!do_hint && print_sdp) dump_isom_sdp(file, dump_std ? NULL : (outName ? outName : outfile), outName ? GF_TRUE : GF_FALSE);
#endif
	if (get_nb_tracks) {
		fprintf(stdout, "%d\n", gf_isom_get_track_count(file));
	}
	if (print_info) {
		if (!file) {
			M4_LOG(GF_LOG_ERROR, ("Cannot print info on a non ISOM file (%s)\n", inName));
		} else {
			if (info_track_id) DumpTrackInfo(file, info_track_id, 1, (print_info==2) ? GF_TRUE : GF_FALSE, GF_FALSE);
			else DumpMovieInfo(file);
		}
	}
#ifndef GPAC_DISABLE_ISOM_DUMP
	if (dump_isom) {
		e = dump_isom_xml(file, dump_std ? NULL : (outName ? outName : outfile), outName ? GF_TRUE : GF_FALSE, (dump_isom==2) ? GF_TRUE : GF_FALSE, merge_vtt_cues, use_init_seg ? GF_TRUE : GF_FALSE, (dump_isom==3) ? GF_TRUE : GF_FALSE);
		if (e) goto err_exit;
	}
	if (dump_cr) dump_isom_ismacryp(file, dump_std ? NULL : (outName ? outName : outfile), outName ? GF_TRUE : GF_FALSE);
	if ((dump_ttxt || dump_srt) && trackID) {

		if (trackID == (u32)-1) {
			for (j=0; j<gf_isom_get_track_count(file); j++) {
				trackID = gf_isom_get_track_id(file, j+1);
				dump_isom_timed_text(file, trackID, dump_std ? NULL : (outName ? outName : outfile), outName ? GF_TRUE : GF_FALSE,
									GF_FALSE, dump_srt ? GF_TEXTDUMPTYPE_SRT : GF_TEXTDUMPTYPE_TTXT);
			}

		}
		else {
			dump_isom_timed_text(file, trackID, dump_std ? NULL : (outName ? outName : outfile), outName ? GF_TRUE : GF_FALSE,
								GF_FALSE, dump_srt ? GF_TEXTDUMPTYPE_SRT : GF_TEXTDUMPTYPE_TTXT);
		}
	}

#ifndef GPAC_DISABLE_ISOM_HINTING
	if (dump_rtp) dump_isom_rtp(file, dump_std ? NULL : (outName ? outName : outfile), outName ? GF_TRUE : GF_FALSE);
#endif

#endif

	if (dump_timestamps) dump_isom_timestamps(file, dump_std ? NULL : (outName ? outName : outfile), outName ? GF_TRUE : GF_FALSE, dump_timestamps);
	if (dump_nal) dump_isom_nal(file, dump_nal, dump_std ? NULL : (outName ? outName : outfile), outName ? GF_TRUE : GF_FALSE, dump_nal_type);
	if (dump_saps) dump_isom_saps(file, dump_saps, dump_saps_mode, dump_std ? NULL : (outName ? outName : outfile), outName ? GF_TRUE : GF_FALSE);

	if (do_hash) {
		e = hash_file(inName, dump_std);
		if (e) goto err_exit;
	}
#ifndef GPAC_DISABLE_CORE_TOOLS
	if (do_bin_xml) {
		e = xml_bs_to_bin(inName, outName, dump_std);
		if (e) goto err_exit;
	}
#endif

	if (dump_chunk) dump_isom_chunks(file, dump_std ? NULL : (outName ? outName : outfile), outName ? GF_TRUE : GF_FALSE);
	if (dump_cart) dump_isom_cover_art(file, dump_std ? NULL : (outName ? outName : outfile), outName ? GF_TRUE : GF_FALSE);
	if (dump_chap) dump_isom_chapters(file, dump_std ? NULL : (outName ? outName : outfile), outName ? GF_TRUE : GF_FALSE, dump_chap);
	if (dump_udta_type) dump_isom_udta(file, dump_std ? NULL : (outName ? outName : outfile), outName ? GF_TRUE : GF_FALSE, dump_udta_type, dump_udta_track);

	if (dump_iod) {
		e = do_dump_iod();
		if (e) goto err_exit;
	}

#if !defined(GPAC_DISABLE_ISOM_WRITE) && !defined(GPAC_DISABLE_MEDIA_IMPORT)
	if (split_duration || split_size || split_range_str) {
		split_isomedia_file(file, split_duration, split_size, inName, interleaving_time, split_start, adjust_split_end, outName, seg_at_rap, split_range_str, fs_dump_flags);

		/*never save file when splitting is desired*/
		open_edit = GF_FALSE;
		do_save = GF_FALSE;
	}
#endif // !defined(GPAC_DISABLE_ISOM_WRITE) && !defined(GPAC_DISABLE_MEDIA_IMPORT)

#ifndef GPAC_DISABLE_MEDIA_EXPORT
	if (track_dump_type) {
		e = do_export_tracks();
		if (e) goto err_exit;
	} else if (do_saf) {
		GF_MediaExporter mdump;
		memset(&mdump, 0, sizeof(mdump));
		mdump.file = file;
		mdump.flags = GF_EXPORT_SAF;
		mdump.out_name = outfile;
		mdump.print_stats_graph = fs_dump_flags;
		e = gf_media_export(&mdump);
		if (e) goto err_exit;
	}
#endif

	e = do_meta_act();
	if (e) goto err_exit;

	if (!open_edit && !do_save) {
		if (file) gf_isom_delete(file);
		goto exit;
	}


#ifndef GPAC_DISABLE_ISOM_WRITE
	if (clean_groups) {
		e = gf_isom_reset_switch_parameters(file);
		if (e) goto err_exit;
		do_save = GF_TRUE;
	}


	e = do_tsel_act();
	if (e) goto err_exit;

	if (remove_sys_tracks) {
#ifndef GPAC_DISABLE_AV_PARSERS
		remove_systems_tracks(file);
#endif
		do_save = GF_TRUE;
		if (conv_type < GF_ISOM_CONV_TYPE_ISMA_EX) conv_type = 0;
	}
	if (remove_root_od) {
		gf_isom_remove_root_od(file);
		do_save = GF_TRUE;
	}
#ifndef GPAC_DISABLE_ISOM_HINTING
	if (remove_hint) {
		for (i=0; i<gf_isom_get_track_count(file); i++) {
			if (gf_isom_get_media_type(file, i+1) == GF_ISOM_MEDIA_HINT) {
				M4_LOG(GF_LOG_INFO, ("Removing hint track ID %d\n", gf_isom_get_track_id(file, i+1)));
				gf_isom_remove_track(file, i+1);
				i--;
			}
		}
		gf_isom_sdp_clean(file);
		do_save = GF_TRUE;
	}
#endif // GPAC_DISABLE_ISOM_HINTING

	if (timescale && (timescale != gf_isom_get_timescale(file))) {
		gf_isom_set_timescale(file, timescale);
		do_save = GF_TRUE;
	}

	if (!encode) {
		if (!file) {
			M4_LOG(GF_LOG_INFO, ("Nothing to do - exiting\n"));
			goto exit;
		}
		if (outName) {
			strcpy(outfile, outName);
		} else {
			const char *tmp_dir = gf_opts_get_key("core", "tmp");
			char *rel_name = strrchr(inName, GF_PATH_SEPARATOR);
			if (!rel_name) rel_name = strrchr(inName, '/');

			strcpy(outfile, "");
			if (tmp_dir) {
				strcpy(outfile, tmp_dir);
				if (!strchr("\\/", tmp_dir[strlen(tmp_dir)-1])) strcat(outfile, "/");
			}
			if (!pack_file) strcat(outfile, "out_");
			strcat(outfile, rel_name ? rel_name + 1 : inName);

			if (pack_file) {
				strcpy(outfile, rel_name ? rel_name + 1 : inName);
				rel_name = strrchr(outfile, '.');
				if (rel_name) rel_name[0] = 0;
				strcat(outfile, ".m21");
			}
		}
#ifndef GPAC_DISABLE_MEDIA_IMPORT
		if ((conv_type == GF_ISOM_CONV_TYPE_ISMA) || (conv_type == GF_ISOM_CONV_TYPE_ISMA_EX)) {
			M4_LOG(GF_LOG_INFO, ("Converting to ISMA Audio-Video MP4 file\n"));
			/*keep ESIDs when doing ISMACryp*/
			e = gf_media_make_isma(file, crypt ? 1 : 0, GF_FALSE, (conv_type==GF_ISOM_CONV_TYPE_ISMA_EX) ? 1 : 0);
			if (e) goto err_exit;
			do_save = GF_TRUE;
		}
		if (conv_type == GF_ISOM_CONV_TYPE_3GPP) {
			M4_LOG(GF_LOG_INFO, ("Converting to 3GP file\n"));
			e = gf_media_make_3gpp(file);
			if (e) goto err_exit;
			do_save = GF_TRUE;
		}
		if (conv_type == GF_ISOM_CONV_TYPE_PSP) {
			M4_LOG(GF_LOG_INFO, ("Converting to PSP file\n"));
			e = gf_media_make_psp(file);
			if (e) goto err_exit;
			do_save = GF_TRUE;
		}
		if (conv_type == GF_ISOM_CONV_TYPE_MOV) {
			e = gf_media_check_qt_prores(file);
			if (e) goto err_exit;
			do_save = GF_TRUE;
			if (interleaving_time) interleaving_time = 0.5;
		}
#endif /*GPAC_DISABLE_MEDIA_IMPORT*/
		if (conv_type == GF_ISOM_CONV_TYPE_IPOD) {
			do_ipod_conv();
		}

	} else if (outName) {
		strcpy(outfile, outName);
	}

	e = do_track_act();
	if (e) goto err_exit;

	if (itunes_tags) {
		e = do_itunes_tag();
		if (e) goto err_exit;
	}

	if (cprt) {
		e = gf_isom_set_copyright(file, "und", cprt);
		do_save = GF_TRUE;
		if (e) goto err_exit;
	}
	if (chap_file || chap_file_qt) {
#ifndef GPAC_DISABLE_MEDIA_IMPORT
		Bool chap_qt = GF_FALSE;
		if (chap_file_qt) {
			chap_file = chap_file_qt;
			chap_qt = GF_TRUE;
		}
		e = gf_media_import_chapters(file, chap_file, import_fps, chap_qt);
		do_save = GF_TRUE;
#else
		M4_LOG(GF_LOG_WARNING, ("Warning: GPAC compiled without Media Import, chapters can't be imported\n"));
		e = GF_NOT_SUPPORTED;
#endif
		if (e) goto err_exit;
	}

	if (major_brand) {
		gf_isom_set_brand_info(file, major_brand, minor_version);
		do_save = GF_TRUE;
	}
	for (i=0; i<nb_alt_brand_add; i++) {
		gf_isom_modify_alternate_brand(file, brand_add[i], GF_TRUE);
		do_save = GF_TRUE;
	}
	for (i=0; i<nb_alt_brand_rem; i++) {
		gf_isom_modify_alternate_brand(file, brand_rem[i], GF_FALSE);
		do_save = GF_TRUE;
	}
	if (box_patch_filename) {
		e = gf_isom_apply_box_patch(file, box_patch_trackID, box_patch_filename, GF_FALSE);
		if (e) {
			M4_LOG(GF_LOG_ERROR, ("Failed to apply box patch %s: %s\n", box_patch_filename, gf_error_to_string(e) ));
			goto err_exit;
		}
		do_save = GF_TRUE;
	}

#ifndef GPAC_DISABLE_CRYPTO
	if (crypt) {
		if (!drm_file && (crypt==1) ) {
			M4_LOG(GF_LOG_ERROR, ("Missing DRM file location - usage '-%s drm_file input_file\n", (crypt==1) ? "crypt" : "decrypt"));
			e = GF_BAD_PARAM;
			goto err_exit;
		}
		if (crypt == 1) {
			if (use_init_seg) {
				e = gf_crypt_fragment(file, drm_file, outfile, inName, fs_dump_flags);
			} else {
				e = gf_crypt_file(file, drm_file, outfile, interleaving_time, fs_dump_flags);
			}
		} else if (crypt ==2) {
			if (use_init_seg) {
				e = gf_decrypt_fragment(file, drm_file, outfile, inName, fs_dump_flags);
			} else {
				e = gf_decrypt_file(file, drm_file, outfile, interleaving_time, fs_dump_flags);
			}
		}
		if (e) goto err_exit;
		do_save = outName ? GF_FALSE : GF_TRUE;

		if (!do_frag && !do_hint && !full_interleave && !force_co64) {
			char szName[GF_MAX_PATH];
			strcpy(szName, gf_isom_get_filename(file) );
			gf_isom_delete(file);
			file = NULL;
			if (!outName) {
				e = gf_file_move(outfile, szName);
				if (e) goto err_exit;
			}
			goto exit;
		}
	}
#endif /*GPAC_DISABLE_CRYPTO*/

#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
	if (do_frag) {
		if (!interleaving_time) interleaving_time = DEFAULT_INTERLEAVING_IN_SEC;
		if (do_hint) M4_LOG(GF_LOG_WARNING, ("Warning: cannot hint and fragment - ignoring hint\n"));
		M4_LOG(GF_LOG_INFO, ("Fragmenting file (%.3f seconds fragments)\n", interleaving_time));
		e = gf_media_fragment_file(file, outfile, interleaving_time, use_mfra);
		if (e) M4_LOG(GF_LOG_ERROR, ("Error while fragmenting file: %s\n", gf_error_to_string(e)));
		if (!e && !outName) {
			if (gf_file_exists(inName) && gf_file_delete(inName)) {
				M4_LOG(GF_LOG_INFO, ("Error removing file %s\n", inName));
			}
			else if (gf_file_move(outfile, inName)) {
				M4_LOG(GF_LOG_INFO, ("Error renaming file %s to %s\n", outfile, inName));
			}
		}
		if (e) goto err_exit;
		gf_isom_delete(file);
		goto exit;
	}
#endif

#ifndef GPAC_DISABLE_ISOM_HINTING
	if (do_hint) {
		if (force_ocr) SetupClockReferences(file);
		MTUSize -= 12;
		e = HintFile(file, MTUSize, max_ptime, rtp_rate, hint_flags, HintCopy, hint_interleave, regular_iod, single_group, hint_no_offset);
		if (e) goto err_exit;
		do_save = GF_TRUE;
		if (print_sdp) dump_isom_sdp(file, dump_std ? NULL : (outName ? outName : outfile), outName ? GF_TRUE : GF_FALSE);
	}
#endif

#if !defined(GPAC_DISABLE_ISOM_HINTING) && !defined(GPAC_DISABLE_SENG)
	set_sdp_ext();
#endif /*!defined(GPAC_DISABLE_ISOM_HINTING) && !defined(GPAC_DISABLE_SENG)*/

	if (force_co64)
		gf_isom_force_64bit_chunk_offset(file, GF_TRUE);

	if (compress_moov)
		gf_isom_enable_compression(file, GF_ISOM_COMP_ALL, (compress_moov==2) ? GF_ISOM_COMP_WRAP_FTYPE : 0);

	if (no_inplace)
		gf_isom_disable_inplace_rewrite(file);

	if (moov_pading)
		gf_isom_set_inplace_padding(file, moov_pading);

	if (outName) {
		gf_isom_set_final_name(file, outfile);
	} else if (!encode && !force_new && !gf_isom_is_inplace_rewrite(file)) {
		gf_isom_set_final_name(file, outfile);
	}

	Bool is_inplace = gf_isom_is_inplace_rewrite(file);


	/*full interleave (sample-based) if just hinted*/
	if (full_interleave) {
		e = gf_isom_set_storage_mode(file, GF_ISOM_STORE_TIGHT);
	} else if (do_flat) {
		e = gf_isom_set_storage_mode(file, (do_flat==1) ? GF_ISOM_STORE_FLAT : GF_ISOM_STORE_STREAMABLE);
		do_save = GF_TRUE;
	}
	//do not set storage mode unless inplace rewrite is disabled , either by user or due to operations on file
	else if (!is_inplace) {
		e = gf_isom_make_interleave(file, interleaving_time);
		if (!e && old_interleave) e = gf_isom_set_storage_mode(file, GF_ISOM_STORE_INTERLEAVED);
	}

	if (e) goto err_exit;


	if (do_save) {

		if (!gf_sys_is_quiet()) {
			if (outName) {
			} else if (encode || pack_file) {
				M4_LOG(GF_LOG_INFO, ("Saving to %s: ", gf_isom_get_filename(file) ));
			} else {
				M4_LOG(GF_LOG_INFO, ("Saving %s: ", inName));
			}
			if (is_inplace) {
				M4_LOG(GF_LOG_INFO, ("In-place rewrite\n"));
			} else if (do_hint && full_interleave) {
				M4_LOG(GF_LOG_INFO, ("Hinted file - Full Interleaving\n"));
			} else if (full_interleave) {
				M4_LOG(GF_LOG_INFO, ("Full Interleaving\n"));
			} else if ((force_new==2) && interleaving_time) {
				M4_LOG(GF_LOG_INFO, ("Fast-start interleaved storage\n"));
			} else if (do_flat || !interleaving_time) {
				M4_LOG(GF_LOG_INFO, ("Flat storage\n"));
			} else {
				M4_LOG(GF_LOG_INFO, ("%.3f secs Interleaving%s\n", interleaving_time, old_interleave ? " - no drift control" : ""));
			}
		}

		e = gf_isom_close(file);
		file = NULL;

		if (!e && !outName && !encode && !force_new && !pack_file && !is_inplace) {
			if (gf_file_exists(inName)) {
				e = gf_file_delete(inName);
				if (e) {
					M4_LOG(GF_LOG_ERROR, ("Error removing file %s\n", inName));
				}
			}

			e = gf_file_move(outfile, inName);
			if (e) {
				M4_LOG(GF_LOG_ERROR, ("Error renaming file %s to %s\n", outfile, inName));
			}
		}
	} else {
		gf_isom_delete(file);
	}

	if (e) {
		M4_LOG(GF_LOG_ERROR, ("Error: %s\n", gf_error_to_string(e)));
		goto err_exit;
	}
	goto exit;

#else
	/*close libgpac*/
	gf_isom_delete(file);
	M4_LOG(GF_LOG_ERROR, ("Error: Read-only version of MP4Box.\n"));
	return mp4box_cleanup(1);
#endif //GPAC_DISABLE_ISOM_WRITE


err_exit:
	/*close libgpac*/
	if (file) gf_isom_delete(file);
	M4_LOG(GF_LOG_ERROR, ("\n\tError: %s\n", gf_error_to_string(e)));
	return mp4box_cleanup(1);

exit:
	mp4box_cleanup(0);

#ifdef GPAC_MEMORY_TRACKING
	if (mem_track && (gf_memory_size() || gf_file_handles_count() )) {
		gf_log_set_tool_level(GF_LOG_MEMORY, GF_LOG_INFO);
		gf_memory_print();
		return 2;
	}
#endif
	return 0;
}

Project: gpac
File: main.c

void PrintUsage()
{
	u32 i=0;
	gf_sys_format_help(helpout, help_flags, "MP4Box [option] input [option]\n"
		"  \n"
		"# General Options:\n"
	);
	while (m4b_usage_args[i].name) {
		GF_GPACArg *arg = (GF_GPACArg *) &m4b_usage_args[i];
		i++;
		gf_sys_print_arg(helpout, help_flags, arg, "mp4box-general");
	}
}

Project: gpac
File: main.c

u32 parse_bs_switch(char *arg_val, u32 opt)
{
	if (!stricmp(arg_val, "no") || !stricmp(arg_val, "off")) bitstream_switching_mode = GF_DASH_BSMODE_NONE;
	else if (!stricmp(arg_val, "merge"))  bitstream_switching_mode = GF_DASH_BSMODE_MERGED;
	else if (!stricmp(arg_val, "multi"))  bitstream_switching_mode = GF_DASH_BSMODE_MULTIPLE_ENTRIES;
	else if (!stricmp(arg_val, "single"))  bitstream_switching_mode = GF_DASH_BSMODE_SINGLE;
	else if (!stricmp(arg_val, "inband"))  bitstream_switching_mode = GF_DASH_BSMODE_INBAND;
	else {
		M4_LOG(GF_LOG_ERROR, ("Unrecognized bitstream switching mode \"%s\" - please check usage\n", arg_val));
		return 2;
	}
	return 0;
}

Project: gpac
File: main.c

static void PrintHelp(char *arg_name, Bool search_desc, Bool no_match)
{
	GF_FilterSession *fs;
	Bool res;

	fs = gf_fs_new_defaults(0);

	if (arg_name[0]=='-')
		arg_name++;

	if (search_desc) {
		char *_arg_name = gf_strdup(arg_name);
		strlwr(_arg_name);
		GF_LOG(GF_LOG_INFO, GF_LOG_APP, ("Possible options mentionning `%s`:\n", arg_name));
		PrintHelpArg(_arg_name, SEARCH_DESC, fs);
		gf_free(_arg_name);
	} else {
		res = no_match ? GF_FALSE : PrintHelpArg(arg_name, SEARCH_ARG_EXACT, fs);
		if (!res) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("Option -%s unknown, please check usage.\n", arg_name));
			GF_LOG(GF_LOG_INFO, GF_LOG_APP, ("Possible options are:\n"));

			PrintHelpArg(arg_name, SEARCH_ARG_CLOSE, fs);
		}
	}
	if (fs)
		gf_fs_del(fs);
}

Project: gpac
File: main.c

static GF_Err do_track_act()
{
	u32 j;
	for (j=0; j<nb_track_act; j++) {
		u32 i;
		GF_Err e = GF_OK;
		TrackAction *tka = &tracks[j];
		u32 track = tka->trackID ? gf_isom_get_track_by_id(file, tka->trackID) : 0;

		timescale = gf_isom_get_timescale(file);
		switch (tka->act_type) {
		case TRAC_ACTION_REM_TRACK:
			e = gf_isom_remove_track(file, track);
			if (e) {
				M4_LOG(GF_LOG_ERROR, ("Error Removing track ID %d: %s\n", tka->trackID, gf_error_to_string(e)));
			} else {
				M4_LOG(GF_LOG_INFO, ("Removing track ID %d\n", tka->trackID));
			}
			do_save = GF_TRUE;
			break;
		case TRAC_ACTION_SET_LANGUAGE:
			for (i=0; i<gf_isom_get_track_count(file); i++) {
				if (track && (track != i+1)) continue;
				e = gf_isom_set_media_language(file, i+1, tka->lang);
				if (e) return e;
				do_save = GF_TRUE;
			}
			do_save = GF_TRUE;
			break;
		case TRAC_ACTION_SET_KIND:
			for (i=0; i<gf_isom_get_track_count(file); i++) {
				if (track && (track != i+1)) continue;
				e = gf_isom_add_track_kind(file, i+1, tka->kind_scheme, tka->kind_value);
				if (e) return e;
				do_save = GF_TRUE;
			}
			do_save = GF_TRUE;
			break;
		case TRAC_ACTION_REM_KIND:
			for (i=0; i<gf_isom_get_track_count(file); i++) {
				if (track && (track != i+1)) continue;
				e = gf_isom_remove_track_kind(file, i+1, tka->kind_scheme, tka->kind_value);
				if (e) return e;
				do_save = GF_TRUE;
			}
			do_save = GF_TRUE;
			break;
		case TRAC_ACTION_SET_DELAY:
			if (tka->delay.num && tka->delay.den) {
				u64 tk_dur;

				e = gf_isom_remove_edits(file, track);
				if (e) return e;
				tk_dur = gf_isom_get_track_duration(file, track);
				if (gf_isom_get_edits_count(file, track))
					do_save = GF_TRUE;
				if (tka->delay.num>0) {
					//cast to u64, delay_ms * timescale can be quite big before / 1000
					e = gf_isom_append_edit(file, track, ((u64) tka->delay.num) * timescale / tka->delay.den, 0, GF_ISOM_EDIT_EMPTY);
					if (e) return e;
					e = gf_isom_append_edit(file, track, tk_dur, 0, GF_ISOM_EDIT_NORMAL);
					if (e) return e;
					do_save = GF_TRUE;
				} else {
					//cast to u64, delay_ms * timescale can be quite big before / 1000
					u64 to_skip = ((u64) -tka->delay.num) * timescale / tka->delay.den;
					if (to_skip<tk_dur) {
						//cast to u64, delay_ms * timescale can be quite big before / 1000
						u64 media_time = ((u64) -tka->delay.num) * gf_isom_get_media_timescale(file, track) / tka->delay.den;
						e = gf_isom_append_edit(file, track, tk_dur-to_skip, media_time, GF_ISOM_EDIT_NORMAL);
						if (e) return e;
						do_save = GF_TRUE;
					} else {
						M4_LOG(GF_LOG_WARNING, ("Warning: request negative delay longer than track duration - ignoring\n"));
					}
				}
			} else if (gf_isom_get_edits_count(file, track)) {
				e = gf_isom_remove_edits(file, track);
				if (e) return e;
				do_save = GF_TRUE;
			}
			break;
		case TRAC_ACTION_SET_KMS_URI:
			for (i=0; i<gf_isom_get_track_count(file); i++) {
				if (track && (track != i+1)) continue;
				if (!gf_isom_is_media_encrypted(file, i+1, 1)) continue;
				if (!gf_isom_is_ismacryp_media(file, i+1, 1)) continue;
				e = gf_isom_change_ismacryp_protection(file, i+1, 1, NULL, (char *) tka->kms);
				if (e) return e;
				do_save = GF_TRUE;
			}
			break;
		case TRAC_ACTION_SET_ID:
			if (!tka->trackID && (gf_isom_get_track_count(file) == 1)) {
				M4_LOG(GF_LOG_WARNING, ("Warning: track id is not specified, but file has only one track - assume that you want to change id for this track\n"));
				track = 1;
			}
			if (track) {
				u32 newTrack;
				newTrack = gf_isom_get_track_by_id(file, tka->newTrackID);
				if (newTrack != 0) {
					M4_LOG(GF_LOG_WARNING, ("Cannot set track id with value %d because a track already exists - ignoring", tka->newTrackID));
				} else {
					e = gf_isom_set_track_id(file, track, tka->newTrackID);
					if (e) return e;
					do_save = GF_TRUE;
				}
			} else {
				M4_LOG(GF_LOG_WARNING, ("Error: Cannot change id for track %d because it does not exist - ignoring", tka->trackID));
			}
			break;
		case TRAC_ACTION_SWAP_ID:
			if (track) {
				u32 tk1, tk2;
				tk1 = gf_isom_get_track_by_id(file, tka->trackID);
				tk2 = gf_isom_get_track_by_id(file, tka->newTrackID);
				if (!tk1 || !tk2) {
					M4_LOG(GF_LOG_WARNING, ("Error: Cannot swap track IDs because not existing - ignoring"));
				} else {
					e = gf_isom_set_track_id(file, tk2, 0);
					if (e) return e;
					e = gf_isom_set_track_id(file, tk1, tka->newTrackID);
					if (e) return e;
					e = gf_isom_set_track_id(file, tk2, tka->trackID);
					if (e) return e;
					do_save = GF_TRUE;
				}
			} else {
				M4_LOG(GF_LOG_WARNING, ("Error: Cannot change id for track %d because it does not exist - ignoring", tka->trackID));
			}
			break;
		case TRAC_ACTION_SET_PAR:
			e = gf_media_change_par(file, track, tka->par_num, tka->par_den, tka->force_par, tka->rewrite_bs);
			do_save = GF_TRUE;
			break;
		case TRAC_ACTION_SET_CLAP:
			e = gf_isom_set_clean_aperture(file, track, 1, tka->clap_wnum, tka->clap_wden, tka->clap_hnum, tka->clap_hden, tka->clap_honum, tka->clap_hoden, tka->clap_vonum, tka->clap_voden);
			do_save = GF_TRUE;
			break;
		case TRAC_ACTION_SET_MX:
			e = gf_isom_set_track_matrix(file, track, tka->mx);
			do_save = GF_TRUE;
			break;
		case TRAC_ACTION_SET_HANDLER_NAME:
			e = gf_isom_set_handler_name(file, track, tka->hdl_name);
			do_save = GF_TRUE;
			break;
		case TRAC_ACTION_ENABLE:
			if (!gf_isom_is_track_enabled(file, track)) {
				e = gf_isom_set_track_enabled(file, track, GF_TRUE);
				do_save = GF_TRUE;
			}
			break;
		case TRAC_ACTION_DISABLE:
			if (gf_isom_is_track_enabled(file, track)) {
				e = gf_isom_set_track_enabled(file, track, GF_FALSE);
				do_save = GF_TRUE;
			}
			break;
		case TRAC_ACTION_REFERENCE:
			e = gf_isom_set_track_reference(file, track, GF_4CC(tka->lang[0], tka->lang[1], tka->lang[2], tka->lang[3]), tka->newTrackID);
			do_save = GF_TRUE;
			break;
		case TRAC_ACTION_REM_NON_RAP:
			e = gf_media_remove_non_rap(file, track, GF_FALSE);
			do_save = GF_TRUE;
			break;
		case TRAC_ACTION_REM_NON_REFS:
			e = gf_media_remove_non_rap(file, track, GF_TRUE);
			do_save = GF_TRUE;
			break;
		case TRAC_ACTION_SET_UDTA:
			e = set_file_udta(file, track, tka->udta_type, tka->string ? tka->string : tka->src_name , tka->sample_num ? GF_TRUE : GF_FALSE, tka->string ? GF_TRUE : GF_FALSE);
			do_save = GF_TRUE;
			break;
		case TRAC_ACTION_SET_EDITS:
			e = apply_edits(file, track, tka->string);
			do_save = GF_TRUE;
			break;
		case TRAC_ACTION_SET_TIME:
			if (!tka->trackID) {
				e = gf_isom_set_creation_time(file, tka->time, tka->time);
				if (e) return e;
				for (i=0; i<gf_isom_get_track_count(file); i++) {
					e = gf_isom_set_track_creation_time(file, i+1, tka->time, tka->time);
					if (e) return e;
				}
			} else {
				e = gf_isom_set_track_creation_time(file, track, tka->time, tka->time);
			}
			do_save = GF_TRUE;
			break;
		case TRAC_ACTION_SET_MEDIA_TIME:
			for (i=0; i<gf_isom_get_track_count(file); i++) {
				if (track && (track != i+1)) continue;
				e = gf_isom_set_media_creation_time(file, i+1, tka->time, tka->time);
				if (e) return e;
			}
			do_save = GF_TRUE;
			break;
		default:
			break;
		}
		if (e) return e;
	}
	return GF_OK;
}

Project: gpac
File: main.c

void PrintEncryptUsage()
{
	u32 i=0;
	gf_sys_format_help(helpout, help_flags, "# Encryption/Decryption Options\n"
	"MP4Box supports encryption and decryption of ISMA, OMA and CENC content, see [encryption filter `gpac -h cecrypt`](cecrypt).\n"
	"It requires a specific XML file called `CryptFile`, whose syntax is available at https://wiki.gpac.io/Common-Encryption\n"
	"Image files (HEIF) can also be crypted / decrypted, using CENC only.\n"
	"  \n"
	"Options:\n"
	);
	while (m4b_crypt_args[i].name) {
		GF_GPACArg *arg = (GF_GPACArg *) &m4b_crypt_args[i];
		i++;
		gf_sys_print_arg(helpout, help_flags, arg, "mp4box-crypt");
	}
}

Project: gpac
File: main.c

static GF_Err do_meta_act()
{
	u32 i;
	for (i=0; i<nb_meta_act; i++) {
		GF_Err e = GF_OK;
		u32 tk = 0;
#ifndef GPAC_DISABLE_ISOM_WRITE
		Bool self_ref;
#endif
		MetaAction *meta = &metas[i];

		if (meta->trackID) tk = gf_isom_get_track_by_id(file, meta->trackID);

		switch (meta->act_type) {
#ifndef GPAC_DISABLE_ISOM_WRITE
		case META_ACTION_SET_TYPE:
			/*note: we don't handle file brand modification, this is an author stuff and cannot be guessed from meta type*/
			e = gf_isom_set_meta_type(file, meta->root_meta, tk, meta->meta_4cc);
			gf_isom_modify_alternate_brand(file, GF_ISOM_BRAND_ISO2, GF_TRUE);
			do_save = GF_TRUE;
			break;
		case META_ACTION_ADD_ITEM:
			self_ref = !stricmp(meta->szPath, "NULL") || !stricmp(meta->szPath, "this") || !stricmp(meta->szPath, "self");
			e = gf_isom_add_meta_item(file, meta->root_meta, tk, self_ref, self_ref ? NULL : meta->szPath,
			                          meta->szName,
			                          meta->item_id,
									  meta->item_type,
			                          meta->mime_type,
			                          meta->enc_type,
			                          meta->use_dref ? meta->szPath : NULL,  NULL,
			                          meta->image_props);
			if (meta->item_refs && gf_list_count(meta->item_refs)) {
				u32 ref_i;
				for (ref_i = 0; ref_i < gf_list_count(meta->item_refs); ref_i++) {
					MetaRef	*ref_entry = gf_list_get(meta->item_refs, ref_i);
					e = gf_isom_meta_add_item_ref(file, meta->root_meta, tk, meta->item_id, ref_entry->ref_item_id, ref_entry->ref_type, NULL);
				}
			}
			do_save = GF_TRUE;
			break;
		case META_ACTION_ADD_IMAGE_ITEM:
		{
			u32 old_tk_count = gf_isom_get_track_count(file);
			u32 src_tk_id = 1;
			GF_Fraction _frac = {0,0};
			GF_ISOFile *fsrc = file;
			self_ref = GF_FALSE;

			tk = 0;
			if (meta->image_props && meta->image_props->auto_grid) {
				e = GF_OK;
				self_ref = GF_TRUE;
			} else if (!meta->szPath || (meta->image_props && meta->image_props->sample_num && meta->image_props->use_reference)) {
				e = GF_OK;
				self_ref = GF_TRUE;
				src_tk_id = meta->trackID;
			} else if (meta->szPath) {
				if (meta->image_props && gf_isom_probe_file(meta->szPath) && !meta->image_props->tile_mode) {
					meta->image_props->src_file = gf_isom_open(meta->szPath, GF_ISOM_OPEN_READ, NULL);
					e = gf_isom_last_error(meta->image_props->src_file);
					fsrc = meta->image_props->src_file;
				} else {
					e = import_file(file, meta->szPath, 0, _frac, 0, NULL, NULL, 0);
				}
			} else {
				M4_LOG(GF_LOG_ERROR, ("Missing file name to import\n"));
				e = GF_BAD_PARAM;
			}
			if (e == GF_OK) {
				u32 meta_type = gf_isom_get_meta_type(file, meta->root_meta, tk);
				if (!meta_type) {
					e = gf_isom_set_meta_type(file, meta->root_meta, tk, GF_META_ITEM_TYPE_PICT);
				} else {
					if (meta_type != GF_META_ITEM_TYPE_PICT) {
						GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("Warning: file already has a root 'meta' box of type %s\n", gf_4cc_to_str(meta_type)));
						e = GF_BAD_PARAM;
					}
				}
				if (e == GF_OK) {
					if (!meta->item_id) {
						e = gf_isom_meta_get_next_item_id(file, meta->root_meta, tk, &meta->item_id);
					}
					if (e == GF_OK) {
						if (!src_tk_id) {
							u32 j;
							for (j=0; j<gf_isom_get_track_count(fsrc); j++) {
								if (gf_isom_is_video_handler_type (gf_isom_get_media_type(fsrc, j+1))) {
									src_tk_id = gf_isom_get_track_id(fsrc, j+1);
									break;
								}
							}

							if (!src_tk_id) {
								M4_LOG(GF_LOG_ERROR, ("No video track in file, cannot add image from track\n"));
								e = GF_BAD_PARAM;
								break;
							}
						}

						e = gf_isom_iff_create_image_item_from_track(file, meta->root_meta, tk, src_tk_id, meta->szName, meta->item_id, meta->image_props, NULL);
						if (e == GF_OK && meta->primary) {
							e = gf_isom_set_meta_primary_item(file, meta->root_meta, tk, meta->item_id);
						}
						if (e == GF_OK && meta->item_refs && gf_list_count(meta->item_refs)) {
							u32 ref_i;
							for (ref_i = 0; ref_i < gf_list_count(meta->item_refs); ref_i++) {
								MetaRef	*ref_entry = gf_list_get(meta->item_refs, ref_i);
								e = gf_isom_meta_add_item_ref(file, meta->root_meta, tk, meta->item_id, ref_entry->ref_item_id, ref_entry->ref_type, NULL);
							}
						}
						if (e == GF_OK && meta->group_type) {
							e = gf_isom_meta_add_item_group(file, meta->root_meta, tk, meta->item_id, meta->group_id, meta->group_type);
						}
					}
				}
			}
			if (meta->image_props && meta->image_props->src_file) {
				gf_isom_delete(meta->image_props->src_file);
				meta->image_props->src_file = NULL;
			} else if (!self_ref) {
				gf_isom_remove_track(file, old_tk_count+1);
				if (do_flat) {
					M4_LOG(GF_LOG_ERROR, ("Warning: -flat storage cannot be used when using -add-image on external file\n"));
					e = GF_NOT_SUPPORTED;
				}
			}
			do_save = GF_TRUE;
		}
			break;
		case META_ACTION_ADD_IMAGE_GRID:
		{
			u32 meta_type = gf_isom_get_meta_type(file, meta->root_meta, tk);
			e = GF_OK;
			if (!meta_type) {
				e = gf_isom_set_meta_type(file, meta->root_meta, tk, GF_META_ITEM_TYPE_PICT);
			} else {
				if (meta_type != GF_META_ITEM_TYPE_PICT) {
					GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("Warning: file already has a root 'meta' box of type %s\n", gf_4cc_to_str(meta_type)));
					e = GF_BAD_PARAM;
				}
			}
			if (e == GF_OK) {
				if (!meta->item_id) {
					e = gf_isom_meta_get_next_item_id(file, meta->root_meta, tk, &meta->item_id);
				}
				if (e == GF_OK) {
					e = gf_isom_iff_create_image_grid_item(file, meta->root_meta, tk,
							meta->szName && strlen(meta->szName) ? meta->szName : NULL,
							meta->item_id,
							meta->image_props);
					if (e == GF_OK && meta->primary) {
						e = gf_isom_set_meta_primary_item(file, meta->root_meta, tk, meta->item_id);
					}
					if (e == GF_OK && meta->item_refs && gf_list_count(meta->item_refs)) {
						u32 ref_i;
						for (ref_i = 0; ref_i < gf_list_count(meta->item_refs); ref_i++) {
							MetaRef	*ref_entry = gf_list_get(meta->item_refs, ref_i);
							e = gf_isom_meta_add_item_ref(file, meta->root_meta, tk, meta->item_id, ref_entry->ref_item_id, ref_entry->ref_type, NULL);
						}
					}
				}
			}
			do_save = GF_TRUE;
		}
			break;
		case META_ACTION_REM_ITEM:
			e = gf_isom_remove_meta_item(file, meta->root_meta, tk, meta->item_id);
			do_save = GF_TRUE;
			break;
		case META_ACTION_SET_PRIMARY_ITEM:
			e = gf_isom_set_meta_primary_item(file, meta->root_meta, tk, meta->item_id);
			do_save = GF_TRUE;
			break;
		case META_ACTION_SET_XML:
		case META_ACTION_SET_BINARY_XML:
			e = gf_isom_set_meta_xml(file, meta->root_meta, tk, meta->szPath, NULL, 0, (meta->act_type==META_ACTION_SET_BINARY_XML) ? 1 : 0);
			do_save = GF_TRUE;
			break;
		case META_ACTION_REM_XML:
			if (gf_isom_get_meta_item_count(file, meta->root_meta, tk)) {
				e = gf_isom_remove_meta_xml(file, meta->root_meta, tk);
				do_save = GF_TRUE;
			} else {
				M4_LOG(GF_LOG_WARNING, ("No meta box in input file\n"));
				e = GF_OK;
			}
			break;
		case META_ACTION_DUMP_ITEM:
			if (gf_isom_get_meta_item_count(file, meta->root_meta, tk)) {
				e = gf_isom_extract_meta_item(file, meta->root_meta, tk, meta->item_id, meta->szPath && strlen(meta->szPath) ? meta->szPath : NULL);
			} else {
				M4_LOG(GF_LOG_WARNING, ("No meta box in input file\n"));
				e = GF_OK;
			}
			break;
#endif // GPAC_DISABLE_ISOM_WRITE

		case META_ACTION_DUMP_XML:
			if (gf_isom_has_meta_xml(file, meta->root_meta, tk)) {
				e = gf_isom_extract_meta_xml(file, meta->root_meta, tk, meta->szPath, NULL);
			} else {
				M4_LOG(GF_LOG_WARNING, ("No meta box in input file\n"));
				e = GF_OK;
			}
			break;
		default:
			break;
		}
		if (meta->item_refs) {
			while (gf_list_count(meta->item_refs)) {
				gf_free(gf_list_pop_back(meta->item_refs));
			}
			gf_list_del(meta->item_refs);
			meta->item_refs = NULL;
		}
		if (meta->image_props) {
			gf_free(meta->image_props);
			meta->image_props = NULL;
		}
		if (e) return e;
	}
	return GF_OK;
}

Project: gpac
File: main.c

static GF_Err do_remux_file()
{
	GF_MediaExporter mdump;
	memset(&mdump, 0, sizeof(GF_MediaExporter));
	mdump.in_name = inName;
	mdump.out_name = mux_name;
	mdump.flags = GF_EXPORT_REMUX;
	mdump.print_stats_graph = fs_dump_flags;
	return gf_media_export(&mdump);
}

Project: gpac
File: main.c

u32 parse_cp_loc(char *arg_val, u32 opt)
{
	if (!strcmp(arg_val, "both")) cp_location_mode = GF_DASH_CPMODE_BOTH;
	else if (!strcmp(arg_val, "as")) cp_location_mode = GF_DASH_CPMODE_ADAPTATION_SET;
	else if (!strcmp(arg_val, "rep")) cp_location_mode = GF_DASH_CPMODE_REPRESENTATION;
	else {
		M4_LOG(GF_LOG_ERROR, ("Unrecognized ContentProtection loction mode \"%s\" - please check usage\n", arg_val));
		return 2;
	}
	return 0;
}

Project: gpac
File: main.c

u32 parse_ttxt(char *arg_val, u32 opt)
{
	if (opt) //-srt
		dump_srt = GF_TRUE;
	else
		dump_ttxt = GF_TRUE;

	import_subtitle = 1;
	trackID = 0;

	if (arg_val && (!strcmp(arg_val, "*") || !strcmp(arg_val, "@") || !strcmp(arg_val, "all")) ) {
		trackID = (u32)-1;
	} else if (arg_val) {
		if (sscanf(arg_val, "%u", &trackID) == 1) {
			char szTk[20];
			sprintf(szTk, "%d", trackID);
			if (strcmp(szTk, arg_val))
				trackID = 0;
		}
		if (!trackID) return 3;
	}
	return 0;
}

Project: gpac
File: main.c

u32 parse_dump_ts(char *arg_val, u32 opt)
{
	dump_timestamps = 1;
	if (arg_val) {
		if (isdigit(arg_val[0])) {
			program_number = atoi(arg_val);
		} else {
			return 3;
		}
	}
	return 0;
}

Project: gpac

static u32 mp4box_cleanup(u32 ret_code) {
	if (mpd_base_urls) {
		gf_free(mpd_base_urls);
		mpd_base_urls = NULL;
	}
	if (sdp_lines) {
		gf_free(sdp_lines);
		sdp_lines = NULL;
	}
	if (metas) {
		u32 i;
		for (i=0; i<nb_meta_act; i++) {
			if (metas[i].enc_type) gf_free(metas[i].enc_type);
			if (metas[i].mime_type) gf_free(metas[i].mime_type);
			if (metas[i].szName) gf_free(metas[i].szName);
			if (metas[i].szPath) gf_free(metas[i].szPath);
		}
		gf_free(metas);
		metas = NULL;
	}
	if (tracks) {
		u32 i;
		for (i = 0; i<nb_track_act; i++) {
			if (tracks[i].out_name)
				gf_free(tracks[i].out_name);
			if (tracks[i].src_name)
				gf_free(tracks[i].src_name);
			if (tracks[i].string)
				gf_free(tracks[i].string);
			if (tracks[i].kind_scheme)
				gf_free(tracks[i].kind_scheme);
			if (tracks[i].kind_value)
				gf_free(tracks[i].kind_value);
		}
		gf_free(tracks);
		tracks = NULL;
	}
	if (tsel_acts) {
		gf_free(tsel_acts);
		tsel_acts = NULL;
	}
	if (brand_add) {
		gf_free(brand_add);
		brand_add = NULL;
	}
	if (brand_rem) {
		gf_free(brand_rem);
		brand_rem = NULL;
	}
	if (dash_inputs) {
		u32 i, j;
		for (i = 0; i<nb_dash_inputs; i++) {
			GF_DashSegmenterInput *di = &dash_inputs[i];
			if (di->nb_baseURL) {
				for (j = 0; j<di->nb_baseURL; j++) {
					gf_free(di->baseURL[j]);
				}
				gf_free(di->baseURL);
			}
			if (di->rep_descs) {
				for (j = 0; j<di->nb_rep_descs; j++) {
					gf_free(di->rep_descs[j]);
				}
				gf_free(di->rep_descs);
			}
			if (di->as_descs) {
				for (j = 0; j<di->nb_as_descs; j++) {
					gf_free(di->as_descs[j]);
				}
				gf_free(di->as_descs);
			}
			if (di->as_c_descs) {
				for (j = 0; j<di->nb_as_c_descs; j++) {
					gf_free(di->as_c_descs[j]);
				}
				gf_free(di->as_c_descs);
			}
			if (di->p_descs) {
				for (j = 0; j<di->nb_p_descs; j++) {
					gf_free(di->p_descs[j]);
				}
				gf_free(di->p_descs);
			}
			if (di->representationID) gf_free(di->representationID);
			if (di->periodID) gf_free(di->periodID);
			if (di->xlink) gf_free(di->xlink);
			if (di->seg_template) gf_free(di->seg_template);
			if (di->hls_pl) gf_free(di->hls_pl);
			if (di->source_opts) gf_free(di->source_opts);
			if (di->filter_chain) gf_free(di->filter_chain);

			if (di->roles) {
				for (j = 0; j<di->nb_roles; j++) {
					gf_free(di->roles[j]);
				}
				gf_free(di->roles);
			}
		}
		gf_free(dash_inputs);
		dash_inputs = NULL;
	}
	if (logfile) gf_fclose(logfile);
	gf_sys_close();

#ifdef GPAC_MEMORY_TRACKING
	if (mem_track && (gf_memory_size() || gf_file_handles_count() )) {
		gf_log_set_tool_level(GF_LOG_MEMORY, GF_LOG_INFO);
		gf_memory_print();
	}
#endif

	return ret_code;
}

Project: gpac
File: main.c

u32 parse_senc_param(char *arg_val, u32 opt)
{
	switch (opt) {
	case 0: //-sync
		smenc_opts.flags |= GF_SM_ENCODE_RAP_INBAND;
		smenc_opts.rap_freq = atoi(arg_val);
		break;
	case 1: //-shadow
		smenc_opts.flags &= ~GF_SM_ENCODE_RAP_INBAND;
		smenc_opts.flags |= GF_SM_ENCODE_RAP_SHADOW;
		smenc_opts.rap_freq = atoi(arg_val);
		break;
	case 2: //-carousel
		smenc_opts.flags &= ~(GF_SM_ENCODE_RAP_INBAND | GF_SM_ENCODE_RAP_SHADOW);
		smenc_opts.rap_freq = atoi(arg_val);
		break;
	case 3: //-auto-quant
		smenc_opts.resolution = atoi(arg_val);
		smenc_opts.auto_quant = 1;
		break;
	case 4: //-global-quant
		smenc_opts.resolution = atoi(arg_val);
		smenc_opts.auto_quant = 2;
		break;
	case 5: //-ctx-in or -inctx
		chunk_mode = GF_TRUE;
		input_ctx = arg_val;
	}
	return 0;
}

Project: gpac
File: main.c

Bool print_version(char *arg_val, u32 param)
{
	fprintf(stderr, "MP4Box - GPAC version %s\n"
	        "%s\n"
	        "GPAC Configuration: " GPAC_CONFIGURATION "\n"
	        "Features: %s %s\n", gf_gpac_version(), gf_gpac_copyright_cite(), gf_sys_features(GF_FALSE), gf_sys_features(GF_TRUE));
	return GF_TRUE;
}

Project: gpac
File: main.c

void PrintImportUsage()
{
	u32 i;

	gf_sys_format_help(helpout, help_flags, "# Importing Options\n"
		"# File importing\n"
		"Syntax is [-add]() / [-cat]() `URL[#FRAGMENT][:opt1...:optN=val]`\n"
		"This process will create the destination file if not existing, and add the track(s) to it. If you wish to always create a new destination file, add [-new](MP4B_GEN).\n"
		"The supported input media types depend on your installation, check [filters documentation](Filters) for more info.\n"
		"  \n"
		"To select a desired media track from a source, a fragment identifier '#' can be specified, before any other options. The following syntax is used:\n"
		"- `#video`: adds the first video track found in source\n"
		"- `#audio`: adds the first audio track found in source\n"
		"- `#auxv`: adds the first auxiliary video track found in source\n"
		"- `#pict`: adds the first picture track found in source\n"
		"- `#trackID=ID` or `#ID`: adds the specified track. For IsoMedia files, ID is the track ID. For other media files, ID is the value indicated by `MP4Box -info inputFile`\n"
		"- `#pid=ID`: number of desired PID for MPEG-2 TS sources\n"
		"- `#prog_id=ID`: number of desired program for MPEG-2 TS sources\n"
		"- `#program=NAME`: name of desired program for MPEG-2 TS sources\n"
		"  \n"
		"By default all imports are performed sequentially, and final interleaving is done at the end; this however requires a temporary file holding original ISOBMF file (if any) and added files before creating the final output. Since this can become quite large, it is possible to add media to a new file without temporary storage, using [-flat](MP4B_GEN) option, but this disables media interleaving.\n"
		"  \n"
		"If you wish to create an interleaved new file with no temporary storage, use the [-newfs](MP4B_GEN) option. The interleaving might not be as precise as when using [-new]() since it is dependent on muxer input scheduling (each execution might lead to a slightly different result). Additionally in this mode: \n"
		" - Some muxing options (marked with `X` below) will be activated for all inputs (e.g it is not possible to import one AVC track with `xps_inband` and another without).\n"
		" - Some muxing options (marked as `D` below) cannot be used as they require temporary storage for file edition.\n"
		" - Usage of [-cat]() is possible, but concatenated sources will not be interleaved in the output. If you wish to perform more complex cat/add operations without temp file, use a [playlist](flist).\n"
		"  \n"
		"Source URL can be any URL supported by GPAC, not limited to local files.\n"
		"  \n"
		"Note: When importing SRT or SUB files, MP4Box will choose default layout options to make the subtitle appear at the bottom of the video. You SHOULD NOT import such files before any video track is added to the destination file, otherwise the results will likely not be useful (default SRT/SUB importing uses default serif font, fontSize 18 and display size 400x60). For more details, check [TTXT doc](Subtitling-with-GPAC).\n"
		"  \n"
		"When importing several tracks/sources in one pass, all options will be applied if relevant to each source. These options are set for all imported streams. If you need to specify these options per stream, set per-file options using the syntax `-add stream[:opt1:...:optN]`.\n"
		"  \n"
		"The import file name may be set to empty or `self`, indicating that the import options should be applied to the destination file track(s).\n"
		"EX -add self:moovts=-1:noedit src.mp4\n"
		"This will apply `moovts` and `noedit` option to all tracks in src.mp4\n"
		"EX -add self#2:moovts=-1:noedit src.mp4\n"
		"This will apply `moovts` and `noedit` option to track with `ID=2` in src.mp4\n"
		"Only per-file options marked with a `S` are possible in this mode.\n"
		"  \n"
		"When importing an ISOBMFF/QT file, only options marked as `C` or `S` can be used.\n"
		"  \n"
		"Allowed per-file options:\n\n"
	);

	i=0;
	while (m4b_imp_fileopt_args[i].name) {
		GF_GPACArg *arg = (GF_GPACArg *) &m4b_imp_fileopt_args[i];
		i++;
		gf_sys_print_arg(helpout, help_flags | GF_PRINTARG_NO_DASH, arg, "mp4box-import");
	}

	gf_sys_format_help(helpout, help_flags, "\n"
		"Note: `sopt`, `dopt` and `@f` must be placed after all other options.\n"
		"# Global import options\n"
	);

	i=0;
	while (m4b_imp_args[i].name) {
		GF_GPACArg *arg = (GF_GPACArg *) &m4b_imp_args[i];
		i++;
		gf_sys_print_arg(helpout, help_flags, arg, "mp4box-import");
	}
}

Project: gpac
File: main.c

static u64 do_size_top_boxes(char *inName, char *compress_top_boxes, u32 mode)
{
	FILE *in;
	u64 top_size = 0;
	Bool do_all = GF_FALSE;
	GF_BitStream *bs_in;
	if (!compress_top_boxes) return GF_BAD_PARAM;
	if (!strcmp(compress_top_boxes, "all") || !strcmp(compress_top_boxes, "*") || !strcmp(compress_top_boxes, "@"))
		do_all = GF_TRUE;

	in = gf_fopen(inName, "rb");
	if (!in) return GF_URL_ERROR;
	bs_in = gf_bs_from_file(in, GF_BITSTREAM_READ);
	while (gf_bs_available(bs_in)) {
		const char *stype;
		u32 hdr_size = 8;
		u64 lsize = gf_bs_read_u32(bs_in);
		u32 type = gf_bs_read_u32(bs_in);

		if (lsize==1) {
			lsize = gf_bs_read_u64(bs_in);
			hdr_size = 16;
		} else if (lsize==0) {
			lsize = gf_bs_available(bs_in) + 8;
		}
		stype = gf_4cc_to_str(type);
		if (do_all || strstr(compress_top_boxes, stype)) {
			//only count boxes
			if (mode==2) {
				top_size += 1;
			} else {
				top_size += lsize;
			}
		}
		gf_bs_skip_bytes(bs_in, lsize - hdr_size);
	}
	gf_bs_del(bs_in);
	gf_fclose(in);
	return top_size;

}

Project: gpac
File: main.c

static void do_ipod_conv()
{
	u32 i, ipod_major_brand = 0;
	M4_LOG(GF_LOG_INFO, ("Setting up iTunes/iPod file\n"));

	for (i=0; i<gf_isom_get_track_count(file); i++) {
		u32 mType = gf_isom_get_media_type(file, i+1);
		switch (mType) {
		case GF_ISOM_MEDIA_VISUAL:
		case GF_ISOM_MEDIA_AUXV:
		case GF_ISOM_MEDIA_PICT:
			ipod_major_brand = GF_ISOM_BRAND_M4V;
			gf_isom_set_ipod_compatible(file, i+1);
			break;
		case GF_ISOM_MEDIA_AUDIO:
			if (!ipod_major_brand) ipod_major_brand = GF_ISOM_BRAND_M4A;
			else gf_isom_modify_alternate_brand(file, GF_ISOM_BRAND_M4A, GF_TRUE);
			break;
		case GF_ISOM_MEDIA_TEXT:
			/*this is a text track track*/
			if (gf_isom_get_media_subtype(file, i+1, 1) == GF_ISOM_SUBTYPE_TX3G) {
				Bool is_chap = 0;
				u32 j;
				for (j=0; j<gf_isom_get_track_count(file); j++) {
					s32 count = gf_isom_get_reference_count(file, j+1, GF_ISOM_REF_CHAP);
					if (count>0) {
						u32 tk, k;
						for (k=0; k<(u32) count; k++) {
							gf_isom_get_reference(file, j+1, GF_ISOM_REF_CHAP, k+1, &tk);
							if (tk==i+1) {
								is_chap = 1;
								break;
							}
						}
						if (is_chap) break;
					}
					if (is_chap) break;
				}
				/*this is a subtitle track*/
				if (!is_chap)
					gf_isom_set_media_type(file, i+1, GF_ISOM_MEDIA_SUBT);
			}
			break;
		}
	}
	gf_isom_set_brand_info(file, ipod_major_brand, 1);
	gf_isom_modify_alternate_brand(file, GF_ISOM_BRAND_MP42, GF_TRUE);
	do_save = GF_TRUE;
}

Project: gpac
File: main.c

u32 parse_mpegu(char *arg_val, u32 opt)
{
	pack_file = arg_val;
	pack_wgt = GF_TRUE;
	return 0;
}

Project: gpac

void PrintGeneralUsage()
{
	u32 i=0;
	gf_sys_format_help(helpout, help_flags, "# General Options\n"
		"MP4Box is a multimedia packager, with a vast number of functionalities: conversion, splitting, hinting, dumping, DASH-ing, encryption, transcoding and others.\n"
		"MP4Box provides a large set of options, classified by categories (see [-h]()). These options do not follow any particular ordering.\n"
		"  \n"
		"By default, MP4Box rewrites the input file. You can change this behavior by using the [-out]() option.\n"
		"MP4Box stores by default the file with 0.5 second interleaving and meta-data (`moov` ...) at the beginning, making it suitable for HTTP download-and-play. This may however takes longer to store the file, use [-flat]() to change this behavior.\n"
		"  \n"
		"MP4Box usually generates a temporary file when creating a new IsoMedia file. The location of this temporary file is OS-dependent, and it may happen that the drive/partition the temporary file is created on has not enough space or no write access. In such a case, you can specify a temporary file location with [-tmp]().\n"
		"  \n"
		"Option values:\n"
		"Unless specified otherwise, an option of type `integer` expects a trackID value following it."
		"An option of type `boolean` expects no following value."
		"Note: Track operations identify tracks through their ID (usually referred to as tkID in the help), not their order.\n"
		"  \n"
	);


	while (m4b_gen_args[i].name) {
		GF_GPACArg *arg = (GF_GPACArg *) &m4b_gen_args[i];
		i++;
		gf_sys_print_arg(helpout, help_flags, arg, "mp4box-gen");
	}
}

Project: gpac
File: main.c

static u32 do_write_udp()
{
	GF_Err e;
	GF_Socket *sock = gf_sk_new(GF_SOCK_TYPE_UDP);
	u16 port = 2345;
	char *sep = strrchr(udp_dest, ':');
	if (sep) {
		sep[0] = 0;
		port = atoi(sep+1);
	}
	e = gf_sk_bind( sock, "127.0.0.1", 0, udp_dest, port, 0);
	if (sep) sep[0] = ':';
	if (e) {
		M4_LOG(GF_LOG_ERROR, ("Failed to bind socket to %s: %s\n", udp_dest, gf_error_to_string(e) ));
	} else {
		e = gf_sk_send(sock, (u8 *) inName, (u32)strlen(inName));
		if (e)
			M4_LOG(GF_LOG_ERROR, ("Failed to send datagram: %s\n", gf_error_to_string(e) ));
	}
	gf_sk_del(sock);
	return 0;
}

Project: gpac
File: main.c

u32 parse_multi_rtp(char *arg_val, u32 opt)
{
	hint_flags |= GP_RTP_PCK_USE_MULTI;
	if (arg_val)
		max_ptime = atoi(arg_val);
	return 0;
}

Project: gpac
File: main.c

static u32 parse_meta_args(char *opts, MetaActionType act_type)
{
	MetaAction *meta;

	metas = gf_realloc(metas, sizeof(MetaAction) * (nb_meta_act + 1));
	if (!metas) return 2;
	meta = &metas[nb_meta_act];
	nb_meta_act ++;

	memset(meta, 0, sizeof(MetaAction));
	meta->act_type = act_type;
	meta->trackID = 0;
	meta->root_meta = 1;
	open_edit = GF_TRUE;

	if (!opts) return 2;

	if (act_type == META_ACTION_ADD_IMAGE_ITEM)
		has_add_image = GF_TRUE;

	while (1) {
		char *next;
		char *szSlot;
		if (!opts || !opts[0]) return 0;
		if (opts[0]==':') opts += 1;

		szSlot = opts;
		next = gf_url_colon_suffix(opts);
		if (next) next[0] = 0;

		if (!strnicmp(szSlot, "tk=", 3)) {
			sscanf(szSlot, "tk=%u", &meta->trackID);
			meta->root_meta = 0;
		}
		else if (!strnicmp(szSlot, "id=", 3)) {
			meta->item_id = atoi(szSlot+3);
		}
		else if (!strnicmp(szSlot, "type=", 5)) {
			meta->item_type = GF_4CC(szSlot[5], szSlot[6], szSlot[7], szSlot[8]);
		}
		//"ref" (without '=') is for data reference, "ref=" is for item references
		else if (!strnicmp(szSlot, "ref=", 4)) {
			char type[5];
			MetaRef	*ref;
			if (!meta->item_refs) {
				meta->item_refs = gf_list_new();
				if (!meta->item_refs) return 2;
			}
			GF_SAFEALLOC(ref, MetaRef);
			if (!ref) return 2;
			sscanf(szSlot, "ref=%4s,%u", type, &(ref->ref_item_id));
			ref->ref_type = GF_4CC(type[0], type[1], type[2], type[3]);
			gf_list_add(meta->item_refs, ref);
		}
		else if (!strnicmp(szSlot, "name=", 5)) {
			meta->szName = gf_strdup(szSlot+5);
		}
		else if (!strnicmp(szSlot, "path=", 5)) {
			meta->szPath = gf_strdup(szSlot+5);
		}
		else if (!strnicmp(szSlot, "mime=", 5)) {
			meta->item_type = GF_META_ITEM_TYPE_MIME;
			meta->mime_type = gf_strdup(szSlot+5);
		}
		else if (!strnicmp(szSlot, "encoding=", 9)) {
			meta->enc_type = gf_strdup(szSlot+9);
		}
		else if (!strnicmp(szSlot, "image-size=", 11)) {
			if (!meta->image_props) {
				GF_SAFEALLOC(meta->image_props, GF_ImageItemProperties);
				if (!meta->image_props) return 2;
			}
			sscanf(szSlot+11, "%dx%d", &meta->image_props->width, &meta->image_props->height);
		}
		else if (!strnicmp(szSlot, "image-grid-size=", 16)) {
			if (!meta->image_props) {
				GF_SAFEALLOC(meta->image_props, GF_ImageItemProperties);
			}
			sscanf(szSlot+16, "%dx%d", &meta->image_props->num_grid_rows, &meta->image_props->num_grid_columns);
		}
		else if (!strnicmp(szSlot, "image-pasp=", 11)) {
			if (!meta->image_props) {
				GF_SAFEALLOC(meta->image_props, GF_ImageItemProperties);
				if (!meta->image_props) return 2;
			}
			sscanf(szSlot+11, "%dx%d", &meta->image_props->hSpacing, &meta->image_props->vSpacing);
		}
		else if (!strnicmp(szSlot, "image-rloc=", 11)) {
			if (!meta->image_props) {
				GF_SAFEALLOC(meta->image_props, GF_ImageItemProperties);
				if (!meta->image_props) return 2;
			}
			sscanf(szSlot+11, "%dx%d", &meta->image_props->hOffset, &meta->image_props->vOffset);
		}
		else if (!strnicmp(szSlot, "rotation=", 9)) {
			if (!meta->image_props) {
				GF_SAFEALLOC(meta->image_props, GF_ImageItemProperties);
				if (!meta->image_props) return 2;
			}
			meta->image_props->angle = atoi(szSlot+9);
		}
		else if (!strnicmp(szSlot, "mirror-axis=", 12)) {
			if (!meta->image_props) {
				GF_SAFEALLOC(meta->image_props, GF_ImageItemProperties);
				if (!meta->image_props) return 2;
			}
			meta->image_props->mirror = (!strnicmp(szSlot+12, "vertical", 8) ? 1 : 2);
		}
		else if (!strnicmp(szSlot, "clap=", 5)) {
			if (!meta->image_props) {
				GF_SAFEALLOC(meta->image_props, GF_ImageItemProperties);
				if (!meta->image_props) return 2;
			}
			sscanf(szSlot + 5, "%d,%d,%d,%d,%d,%d,%d,%d", &meta->image_props->clap_wnum, &meta->image_props->clap_wden,
					   &meta->image_props->clap_hnum, &meta->image_props->clap_hden,
					   &meta->image_props->clap_honum, &meta->image_props->clap_hoden,
					   &meta->image_props->clap_vonum, &meta->image_props->clap_voden);
		}
		else if (!stricmp(szSlot, "hidden")) {
			if (!meta->image_props) {
				GF_SAFEALLOC(meta->image_props, GF_ImageItemProperties);
				if (!meta->image_props) return 2;
			}
			meta->image_props->hidden = GF_TRUE;
		}
		else if (!stricmp(szSlot, "alpha")) {
			if (!meta->image_props) {
				GF_SAFEALLOC(meta->image_props, GF_ImageItemProperties);
				if (!meta->image_props) return 2;
			}
			meta->image_props->alpha = GF_TRUE;
		}
		//"ref" (without '=') is for data reference, "ref=" is for item references
		else if (!stricmp(szSlot, "ref")) {
			if (!meta->image_props) {
				GF_SAFEALLOC(meta->image_props, GF_ImageItemProperties);
				if (!meta->image_props) return 2;
			}
			meta->image_props->use_reference = GF_TRUE;
		}
		else if (!strnicmp(szSlot, "time=", 5)) {
			Float s=0, e=0, step=0;
			if (!meta->image_props) {
				GF_SAFEALLOC(meta->image_props, GF_ImageItemProperties);
				if (!meta->image_props) return 2;
			}
			if (sscanf(szSlot+5, "%f-%f/%f", &s, &e, &step)==3) {
				meta->image_props->time = s;
				meta->image_props->end_time = e;
				meta->image_props->step_time = step;
			} else if (sscanf(szSlot+5, "%f-%f", &s, &e)==2) {
				meta->image_props->time = s;
				meta->image_props->end_time = e;
			} else if (sscanf(szSlot+5, "%f/%f", &s, &step)==2) {
				meta->image_props->time = s;
				meta->image_props->step_time = step;
			} else if (sscanf(szSlot+5, "%f", &s)==1) {
				meta->image_props->time = s;
			}
		}
		else if (!strnicmp(szSlot, "samp=", 5)) {
			if (!meta->image_props) {
				GF_SAFEALLOC(meta->image_props, GF_ImageItemProperties);
				if (!meta->image_props) return 2;
			}
			meta->image_props->sample_num = atoi(szSlot+5);
			meta->root_meta = 1;
		}
		else if (!strnicmp(szSlot, "group=", 6)) {
			char type[5];
			sscanf(szSlot, "group=%4s,%u", type, &meta->group_id);
			meta->group_type = GF_4CC(type[0], type[1], type[2], type[3]);
		}
		else if (!stricmp(szSlot, "split_tiles")) {
			if (!meta->image_props) {
				GF_SAFEALLOC(meta->image_props, GF_ImageItemProperties);
				if (!meta->image_props) return 2;
			}
			meta->image_props->tile_mode = TILE_ITEM_ALL_BASE;
		}
		else if (!stricmp(szSlot, "dref")) {
			meta->use_dref = 1;
		}
		else if (!stricmp(szSlot, "primary")) {
			meta->primary = 1;
		}
		else if (!stricmp(szSlot, "binary")) {
			if (meta->act_type==META_ACTION_SET_XML) meta->act_type=META_ACTION_SET_BINARY_XML;
		}
		else if (!strnicmp(szSlot, "icc_path=", 9)) {
			if (!meta->image_props) {
				GF_SAFEALLOC(meta->image_props, GF_ImageItemProperties);
				if (!meta->image_props) return 2;
			}
			strcpy(meta->image_props->iccPath, szSlot+9);
		}
		else if (!stricmp(szSlot, "agrid") || !strnicmp(szSlot, "agrid=", 6)) {
			if (!meta->image_props) {
				GF_SAFEALLOC(meta->image_props, GF_ImageItemProperties);
				if (!meta->image_props) return 2;
			}
			meta->image_props->auto_grid = GF_TRUE;
			if (!strnicmp(szSlot, "agrid=", 6))
				meta->image_props->auto_grid_ratio = atof(szSlot+6);
		}
		else if (!strchr(szSlot, '=')) {
			switch (meta->act_type) {
			case META_ACTION_SET_TYPE:
				if (!stricmp(szSlot, "null") || !stricmp(szSlot, "0")) meta->meta_4cc = 0;
				else meta->meta_4cc = GF_4CC(szSlot[0], szSlot[1], szSlot[2], szSlot[3]);
				break;
			case META_ACTION_ADD_ITEM:
			case META_ACTION_ADD_IMAGE_ITEM:
			case META_ACTION_SET_XML:
			case META_ACTION_DUMP_XML:
				if (!strncmp(szSlot, "dopt", 4) || !strncmp(szSlot, "sopt", 4) || !strncmp(szSlot, "@", 1)) {
					if (next) next[0]=':';
					next=NULL;
				}
				//cat as -add arg
				gf_dynstrcat(&meta->szPath, szSlot, ":");
				if (!meta->szPath) return 2;
				break;
			case META_ACTION_REM_ITEM:
			case META_ACTION_SET_PRIMARY_ITEM:
			case META_ACTION_DUMP_ITEM:
				meta->item_id = atoi(szSlot);
				break;
			default:
				break;
			}
		}
		if (!next) break;
		opts += strlen(szSlot);
		next[0] = ':';
	}
	return 0;
}

Project: gpac
File: main.c

static GF_Err do_export_tracks_non_isobmf()
{
	u32 i;

	GF_MediaExporter mdump;
	char szFile[GF_MAX_PATH+24];
	for (i=0; i<nb_track_act; i++) {
		GF_Err e;
		TrackAction *tka = &tracks[i];
		if (tka->act_type != TRAC_ACTION_RAW_EXTRACT) continue;
		memset(&mdump, 0, sizeof(mdump));
		mdump.in_name = inName;
		mdump.flags = tka->dump_type;
		mdump.trackID = tka->trackID;
		mdump.track_type = tka->dump_track_type;
		mdump.sample_num = tka->sample_num;

		if (dump_std) {
			mdump.out_name = "std";
		}
		else if (outName) {
			mdump.out_name = outName;
			mdump.flags |= GF_EXPORT_MERGE;
		} else if (nb_track_act>1) {
			sprintf(szFile, "%s_track%d", outfile, mdump.trackID);
			mdump.out_name = szFile;
		} else {
			mdump.out_name = outfile;
		}
		mdump.print_stats_graph = fs_dump_flags;
		e = gf_media_export(&mdump);
		if (e) return e;
	}
	return GF_OK;
}