PageRenderTime 187ms CodeModel.GetById 31ms app.highlight 127ms RepoModel.GetById 14ms app.codeStats 0ms

/applications/dashcast/cmd_data.c

https://github.com/svettom/gpac
C | 865 lines | 717 code | 118 blank | 30 comment | 245 complexity | c773b525dcfd8213b9e5ce2d06e185f1 MD5 | raw file
  1/*
  2 *			GPAC - Multimedia Framework C SDK
  3 *
  4 *			Authors: Arash Shafiei
  5 *			Copyright (c) Telecom ParisTech 2000-2013
  6 *					All rights reserved
  7 *
  8 *  This file is part of GPAC / dashcast
  9 *
 10 *  GPAC is free software; you can redistribute it and/or modify
 11 *  it under the terms of the GNU Lesser General Public License as published by
 12 *  the Free Software Foundation; either version 2, or (at your option)
 13 *  any later version.
 14 *
 15 *  GPAC is distributed in the hope that it will be useful,
 16 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 17 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 18 *  GNU Lesser General Public License for more details.
 19 *
 20 *  You should have received a copy of the GNU Lesser General Public
 21 *  License along with this library; see the file COPYING.  If not, write to
 22 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 23 *
 24 */
 25
 26#include "cmd_data.h"
 27
 28
 29int dc_str_to_resolution(char *str, int *width, int *height)
 30{
 31	char *token = strtok(str, "x");
 32	if (!token) {
 33		fprintf(stderr, "Cannot parse resolution string.\n");
 34		return -1;
 35	}
 36	*width = atoi(token);
 37
 38	token = strtok(NULL, " ");
 39	if (!token) {
 40		fprintf(stderr, "Cannot parse resolution string.\n");
 41		return -1;
 42	}
 43	*height = atoi(token);
 44
 45	return 0;
 46}
 47
 48
 49#define DEFAULT_VIDEO_BITRATE    400000
 50#define DEFAULT_VIDEO_FRAMERATE  25
 51#define DEFAULT_VIDEO_WIDTH      640
 52#define DEFAULT_VIDEO_HEIGHT     480
 53#define DEFAULT_VIDEO_CODEC      "libx264"
 54#define DEFAULT_AUDIO_BITRATE    192000
 55#define DEFAULT_AUDIO_SAMPLERATE 48000
 56#define DEFAULT_AUDIO_CHANNELS   2
 57#define DEFAULT_AUDIO_CODEC      "mp2"
 58
 59static void dc_create_configuration(CmdData *cmd_data)
 60{
 61	u32 i;
 62	GF_Config *conf = cmd_data->conf;
 63	u32 sec_count = gf_cfg_get_section_count(conf);
 64	if (!sec_count) {
 65		gf_cfg_set_key(conf, "v1", "type", "video");
 66		gf_cfg_set_key(conf, "a1", "type", "audio");
 67		sec_count = gf_cfg_get_section_count(conf);
 68	}
 69	for (i=0; i<sec_count; i++) {
 70		char value[GF_MAX_PATH];
 71		const char *section_name = gf_cfg_get_section_name(conf, i);
 72		const char *section_type = gf_cfg_get_key(conf, section_name, "type");
 73
 74		if (strcmp(section_type, "video") == 0) {
 75			if (!gf_cfg_get_key(conf, section_name, "bitrate")) {
 76				if (cmd_data->video_data_conf.bitrate == -1)
 77					cmd_data->video_data_conf.bitrate = DEFAULT_VIDEO_BITRATE;
 78				snprintf(value, sizeof(value), "%d", cmd_data->video_data_conf.bitrate);
 79				gf_cfg_set_key(conf, section_name, "bitrate", value);
 80			}
 81
 82			if (!gf_cfg_get_key(conf, section_name, "framerate")) {
 83				if (cmd_data->video_data_conf.framerate == -1)
 84					cmd_data->video_data_conf.framerate = DEFAULT_VIDEO_FRAMERATE;
 85				snprintf(value, sizeof(value), "%d", cmd_data->video_data_conf.framerate);
 86				gf_cfg_set_key(conf, section_name, "framerate", value);
 87			}
 88
 89			if (!gf_cfg_get_key(conf, section_name, "width")) {
 90				if (cmd_data->video_data_conf.width == -1)
 91					cmd_data->video_data_conf.width = DEFAULT_VIDEO_WIDTH;
 92				snprintf(value, sizeof(value), "%d", cmd_data->video_data_conf.width);
 93				gf_cfg_set_key(conf, section_name, "width", value);
 94			}
 95
 96			if (!gf_cfg_get_key(conf, section_name, "height")) {
 97				if (cmd_data->video_data_conf.height == -1)
 98					cmd_data->video_data_conf.height = DEFAULT_VIDEO_HEIGHT;
 99				snprintf(value, sizeof(value), "%d", cmd_data->video_data_conf.height);
100				gf_cfg_set_key(conf, section_name, "height", value);
101			}
102
103			if (!gf_cfg_get_key(conf, section_name, "codec"))
104				gf_cfg_set_key(conf, section_name, "codec", DEFAULT_VIDEO_CODEC);
105		}
106
107		if (strcmp(section_type, "audio") == 0) {
108			if (!gf_cfg_get_key(conf, section_name, "bitrate")) {
109				if (cmd_data->audio_data_conf.bitrate == -1)
110					cmd_data->audio_data_conf.bitrate = DEFAULT_AUDIO_BITRATE;
111				snprintf(value, sizeof(value), "%d", cmd_data->audio_data_conf.bitrate);
112				gf_cfg_set_key(conf, section_name, "bitrate", value);
113			}
114
115			if (!gf_cfg_get_key(conf, section_name, "samplerate")) {
116				if (cmd_data->audio_data_conf.samplerate == -1)
117					cmd_data->audio_data_conf.samplerate = DEFAULT_AUDIO_SAMPLERATE;
118				snprintf(value, sizeof(value), "%d", cmd_data->audio_data_conf.samplerate);
119				gf_cfg_set_key(conf, section_name, "samplerate", value);
120			}
121
122			if (!gf_cfg_get_key(conf, section_name, "channels")) {
123				if (cmd_data->audio_data_conf.channels == -1)
124					cmd_data->audio_data_conf.channels = DEFAULT_AUDIO_CHANNELS;
125				snprintf(value, sizeof(value), "%d", cmd_data->audio_data_conf.channels);
126				gf_cfg_set_key(conf, section_name, "channels", value);
127			}
128
129			if (!gf_cfg_get_key(conf, section_name, "codec"))
130				gf_cfg_set_key(conf, section_name, "codec", DEFAULT_AUDIO_CODEC);
131		}
132	}
133}
134
135int dc_read_configuration(CmdData *cmd_data)
136{
137	const char *opt;
138	u32 i;
139	GF_Config *conf = cmd_data->conf;
140
141	u32 sec_count = gf_cfg_get_section_count(conf);
142	for (i=0; i<sec_count; i++) {
143		const char *section_name = gf_cfg_get_section_name(conf, i);
144		const char *section_type = gf_cfg_get_key(conf, section_name, "type");
145
146		if (strcmp(section_type, "video") == 0) {
147			VideoDataConf *video_data_conf;
148			GF_SAFEALLOC(video_data_conf, VideoDataConf);
149			strcpy(video_data_conf->filename, section_name);
150			opt = gf_cfg_get_key(conf, section_name, "codec");
151			if (!opt) opt = DEFAULT_VIDEO_CODEC;
152			strcpy(video_data_conf->codec, opt);
153			opt = gf_cfg_get_key(conf, section_name, "bitrate");
154			video_data_conf->bitrate = opt ? atoi(opt) : DEFAULT_VIDEO_BITRATE;
155			opt = gf_cfg_get_key(conf, section_name, "framerate");
156			video_data_conf->framerate = opt ? atoi(opt) : DEFAULT_VIDEO_FRAMERATE;
157			opt = gf_cfg_get_key(conf, section_name, "height");
158			video_data_conf->height = opt ? atoi(opt) : DEFAULT_VIDEO_HEIGHT;
159			opt = gf_cfg_get_key(conf, section_name, "width");
160			video_data_conf->width = opt ? atoi(opt) : DEFAULT_VIDEO_WIDTH;
161			opt = gf_cfg_get_key(conf, section_name, "custom");
162			video_data_conf->custom = opt ? strdup(opt) : NULL;
163			gf_list_add(cmd_data->video_lst, (void *) video_data_conf);
164		}
165		else if (strcmp(section_type, "audio") == 0)
166		{
167			AudioDataConf *audio_data_conf;
168			GF_SAFEALLOC(audio_data_conf, AudioDataConf);
169			strcpy(audio_data_conf->filename, section_name);
170			opt = gf_cfg_get_key(conf, section_name, "codec");
171			if (!opt) opt = DEFAULT_AUDIO_CODEC;
172			strcpy(audio_data_conf->codec, opt);
173			opt = gf_cfg_get_key(conf, section_name, "bitrate");
174			audio_data_conf->bitrate = opt ? atoi(opt) : DEFAULT_AUDIO_BITRATE;
175			opt = gf_cfg_get_key(conf, section_name, "samplerate");
176			audio_data_conf->samplerate = opt ? atoi(opt) : DEFAULT_AUDIO_SAMPLERATE;
177			opt = gf_cfg_get_key(conf, section_name, "channels");
178			audio_data_conf->channels = opt ? atoi(opt) : DEFAULT_AUDIO_CHANNELS;
179			opt = gf_cfg_get_key(conf, section_name, "custom");
180			audio_data_conf->custom = opt ? strdup(opt) : NULL;
181			gf_list_add(cmd_data->audio_lst, (void *) audio_data_conf);
182		} else {
183			fprintf(stdout, "Configuration file: type %s is not supported.\n", section_type);
184		}
185	}
186
187	fprintf(stdout, "\33[34m\33[1m");
188	fprintf(stdout, "Configurations:\n");
189	for (i=0; i<gf_list_count(cmd_data->video_lst); i++) {
190		VideoDataConf *video_data_conf = gf_list_get(cmd_data->video_lst, i);
191		fprintf(stdout, "    id:%s\tres:%dx%d\tvbr:%d\n", video_data_conf->filename,
192				video_data_conf->width, video_data_conf->height,
193				video_data_conf->bitrate/*, video_data_conf->framerate, video_data_conf->codec*/);	}
194
195	for (i=0; i<gf_list_count(cmd_data->audio_lst); i++) {
196		AudioDataConf *audio_data_conf = gf_list_get(cmd_data->audio_lst, i);
197		fprintf(stdout, "    id:%s\tabr:%d\n", audio_data_conf->filename, audio_data_conf->bitrate/*, audio_data_conf->samplerate, audio_data_conf->channels,audio_data_conf->codec*/);
198	}
199	fprintf(stdout, "\33[0m");
200	fflush(stdout);
201
202	return 0;
203}
204
205/**
206 * Parse time from a string to a struct tm.
207 */
208static Bool parse_time(const char* str_time, struct tm *tm_time)
209{
210	if (!tm_time)
211		return GF_FALSE;
212
213#if defined(__GNUC__)
214	strptime(str_time, "%Y-%m-%d %H:%M:%S", tm_time);
215#elif defined(WIN32)
216	assert(0); //TODO
217#else
218#error
219#endif
220
221	return GF_TRUE;
222}
223
224int dc_read_switch_config(CmdData *cmd_data)
225{
226	u32 i;
227	int src_number;
228	char start_time[4096], end_time[4096];
229
230	time_t now_t = time(NULL);
231	struct tm start_tm = *localtime(&now_t);
232	struct tm end_tm = *localtime(&now_t);
233
234	GF_Config *conf = cmd_data->switch_conf;
235	u32 sec_count = gf_cfg_get_section_count(conf);
236
237	dc_task_init(&cmd_data->task_list);
238
239	if (sec_count == 0) {
240		return 0;
241	}
242
243	for (i = 0; i < sec_count; i++) {
244		const char *section_name = gf_cfg_get_section_name(conf, i);
245		const char *section_type = gf_cfg_get_key(conf, section_name, "type");
246
247		if (strcmp(section_type, "video") == 0) {
248			VideoDataConf *video_data_conf = gf_malloc(sizeof(VideoDataConf));
249
250			strcpy(video_data_conf->source_id, section_name);
251			strcpy(video_data_conf->filename, gf_cfg_get_key(conf, section_name, "source"));
252
253			strcpy(start_time, gf_cfg_get_key(conf, section_name, "start"));
254			parse_time(start_time, &start_tm);
255			video_data_conf->start_time = mktime(&start_tm);
256			strcpy(end_time, gf_cfg_get_key(conf, section_name, "end"));
257			parse_time(end_time, &end_tm);
258			video_data_conf->end_time = mktime(&end_tm);
259
260			gf_list_add(cmd_data->vsrc, (void *) video_data_conf);
261
262			src_number = gf_list_count(cmd_data->vsrc);
263
264			dc_task_add(&cmd_data->task_list, src_number, video_data_conf->source_id, video_data_conf->start_time, video_data_conf->end_time);
265		}
266		else if (strcmp(section_type, "audio") == 0)
267		{
268			AudioDataConf *audio_data_conf = gf_malloc(sizeof(AudioDataConf));
269			strcpy(audio_data_conf->source_id, section_name);
270			strcpy(audio_data_conf->filename, gf_cfg_get_key(conf, section_name, "source"));
271
272			strcpy(start_time, gf_cfg_get_key(conf, section_name, "start"));
273			parse_time(start_time, &start_tm);
274			audio_data_conf->start_time = mktime(&start_tm);
275
276			strcpy(end_time, gf_cfg_get_key(conf, section_name, "end"));
277			parse_time(end_time, &end_tm);
278			audio_data_conf->end_time = mktime(&end_tm);
279
280			gf_list_add(cmd_data->asrc, (void *) audio_data_conf);
281		} else {
282			fprintf(stdout, "Switch source configuration file: type %s is not supported.\n", section_type);
283		}
284	}
285
286	fprintf(stdout, "\33[34m\33[1m");
287	fprintf(stdout, "Sources:\n");
288	for (i=0; i<gf_list_count(cmd_data->vsrc); i++) {
289		VideoDataConf *video_data_conf = gf_list_get(cmd_data->vsrc, i);
290		strftime(start_time, 20, "%Y-%m-%d %H:%M:%S", localtime(&video_data_conf->start_time));
291		strftime(end_time, 20, "%Y-%m-%d %H:%M:%S", localtime(&video_data_conf->end_time));
292		fprintf(stdout, "    id:%s\tsource:%s\tstart:%s\tend:%s\n", video_data_conf->source_id, video_data_conf->filename, start_time, end_time);
293	}
294
295	for (i=0; i<gf_list_count(cmd_data->asrc); i++) {
296		AudioDataConf *audio_data_conf = gf_list_get(cmd_data->asrc, i);
297		strftime(start_time, 20, "%Y-%m-%d %H:%M:%S", localtime(&audio_data_conf->start_time));
298		strftime(end_time, 20, "%Y-%m-%d %H:%M:%S", localtime(&audio_data_conf->end_time));
299		fprintf(stdout, "    id:%s\tsource:%s\tstart:%s\tend:%s\n", audio_data_conf->source_id, audio_data_conf->filename, start_time, end_time);
300	}
301	fprintf(stdout, "\33[0m");
302	fflush(stdout);
303
304	return 0;
305}
306
307void dc_cmd_data_init(CmdData *cmd_data)
308{
309	memset(cmd_data, 0, sizeof(CmdData));
310	dc_audio_data_set_default(&cmd_data->audio_data_conf);
311	dc_video_data_set_default(&cmd_data->video_data_conf);
312
313	cmd_data->mode = ON_DEMAND;
314	cmd_data->ast_offset = -1;
315	cmd_data->min_buffer_time = -1;
316	cmd_data->use_source_timing = 1;
317
318	cmd_data->audio_lst = gf_list_new();
319	cmd_data->video_lst = gf_list_new();
320	cmd_data->asrc = gf_list_new();
321	cmd_data->vsrc = gf_list_new();
322}
323
324void dc_cmd_data_destroy(CmdData *cmd_data)
325{
326	while (gf_list_count(cmd_data->audio_lst)) {
327		AudioDataConf *audio_data_conf = gf_list_last(cmd_data->audio_lst);
328		gf_list_rem_last(cmd_data->audio_lst);
329		gf_free(audio_data_conf);
330	}
331	gf_list_del(cmd_data->audio_lst);
332
333	while (gf_list_count(cmd_data->video_lst)) {
334		VideoDataConf *video_data_conf = gf_list_last(cmd_data->video_lst);
335		gf_list_rem_last(cmd_data->video_lst);
336		gf_free(video_data_conf);
337	}
338	gf_list_del(cmd_data->video_lst);
339
340	gf_list_del(cmd_data->asrc);
341	gf_list_del(cmd_data->vsrc);
342	gf_cfg_del(cmd_data->conf);
343	gf_cfg_del(cmd_data->switch_conf);
344	if (cmd_data->logfile)
345		fclose(cmd_data->logfile);
346
347	dc_task_destroy(&cmd_data->task_list);
348
349	gf_sys_close();
350}
351
352static void on_dc_log(void *cbk, u32 ll, u32 lm, const char *fmt, va_list list)
353{
354	FILE *logs = cbk;
355	vfprintf(logs, fmt, list);
356	fflush(logs);
357}
358
359int dc_parse_command(int argc, char **argv, CmdData *cmd_data)
360{
361	Bool use_mem_track = GF_FALSE;
362	int i;
363
364	const char *command_usage =
365			"Usage: DashCast [options]\n"
366					"\n"
367					"Options:\n"
368					"\n"
369					"    -log-file file               set output log file. Also works with -lf\n"
370					"    -logs LOGS                   set log tools and levels, formatted as a ':'-separated list of toolX[:toolZ]@levelX\n"
371					"    -a inasrc:str                input audio source named inasrc\n"
372			    "                                    - If input is from microphone, inasrc will be \"plughw:[x],[y]\"\n"
373			    "                                      where x is the card number and y is the device number.\n"
374					"    -v invsrc:str                input video source named invsrc\n"
375			    "                                    - If input is from a webcam, invsrc will be \"/dev/video[x]\" \n"
376			    "                                      where x is the video device number.\n"
377			    "                                    - If input is the screen video, invsrc will be \":0.0+[x],[y]\" \n"
378			    "                                      which captures from upper-left at x,y.\n"
379			    "                                    - If input is from stdin, invsrc will be \"pipe:\".\n"
380					"    -av inavsrc:str              a multiplexed audio and video source named inavsrc\n"
381					"                                    - If this option is present, non of '-a' or '-v' can be present.\n"
382					"    -vf invfmt:str               invfmt is the input video format\n"
383#ifdef WIN32
384					"                                    - To capture from a VfW webcam invfmt will be vfwcap."
385					"                                    - To capture from a directshow device invfmt will be dshow."
386#else
387					"                                    - To capture from a webcam invfmt will be video4linux2.\n"
388					"                                    - To capture the screen invfmt will be x11grab.\n"
389					"    -v4l2f inv4l2f:str           inv4l2f is the input format for webcam acquisition\n"
390					"                                    - It can be mjpeg, yuyv422, etc.\n"
391#endif
392					"    -pixf FMT                    spcifies the input pixel format to use\n"
393					"    -vfr invfr:int               invfr is the input video framerate\n"
394					"    -vres invres:intxint         input video resolution\n"
395					"    -af inafmt:str               inafmt is the input audio format\n"
396					"    -conf confname:str           confname is the configuration file\n"
397					"                                    - The default value is dashcast.conf\n\n"
398
399					"    -seg-dur dur:int             dur is the segment duration in millisecond\n"
400					"                                    - The default value is 1000.\n"
401					"    -frag-dur dur:int            dur is the fragment duration in millisecond\n"
402					"                                    - The default value is 1000.\n"
403					"    -live                        system is live and input is a camera\n"
404					"    -npts                        uses frame counting for timestamps (not error-free) instead of source timing (default)\n"
405					"    -live-media                  system is live and input is a media file\n"
406					"    -no-loop                     system does not loop on the input media file\n"
407					"    -seg-marker marker:str       add a marker box named marker at the end of DASH segment\n"
408					"    -gdr                         use Gradual Decoder Refresh feature for video encoding\n\n"
409
410					"    -out outdir:str              outdir is the output data directory\n"
411					"                                    - The default value is output.\n"
412					"    -mpd mpdname:str             mpdname is the MPD file name\n"
413					"                                    - The default value is dashcast.mpd.\n"
414					"    -ast-offset dur:int          dur is the MPD availabilityStartTime shift in milliseconds\n"
415					"                                    - The default value is 1000.\n"
416					"    -time-shift dur:int          dur is the MPD TimeShiftBufferDepth in seconds\n"
417					"                                    - The default value is 10. Specify -1 to keep all files.\n"
418					"    -min-buffer dur:float        dur is the MPD minBufferTime in seconds\n"
419					"                                    - The default value is 1.0.\n\n"
420
421					"    -switch-source confname:str  confname is the name of configuration file for source switching.\n\n"
422
423
424					"Examples:\n"
425			        "\n"
426			        "    DashCast -av test.avi -live-media\n"
427					    "    DashCast -a test_audio.mp3 -v test_audio.mp4 -live-media\n"
428#ifdef WIN32
429	        		"    DashCast -vf vfwcap -vres 1280x720 -vfr 24 -v 0 -live\n"
430					"    DashCast -vf dshow -vres 1280x720 -vfr 24 -v video=\"screen-capture-recorder\" -live (please install http://screencapturer.sf.net/)\n"
431	        		"    DashCast -vf dshow -vres 1280x720 -vfr 24 -v video=\"YOUR-WEBCAM\" -pixf yuv420p -live\n"
432#else
433	        		"    DashCast -vf video4linux2 -vres 1280x720 -vfr 24 -v4l2f mjpeg -v /dev/video0 -af alsa -a plughw:1,0 -live\n"
434	        		"    DashCast -vf x11grab -vres 800x600 -vfr 25 -v :0.0 -live\n"
435#endif
436					"\n";
437
438	char *command_error = "\33[31mUnknown option or missing mandatory argument.\33[0m\n";
439
440	if (argc == 1) {
441		fprintf(stdout, "%s", command_usage);
442		return -2;
443	}
444
445#ifdef GPAC_MEMORY_TRACKING
446	i = 1;
447	while (i < argc) {
448		if (strcmp(argv[i], "-mem-track") == 0) {
449			use_mem_track = GF_TRUE;
450			break;
451		}
452		i++;
453	}
454#endif
455
456	gf_sys_init(use_mem_track);
457
458	if (use_mem_track) {
459		gf_log_set_tool_level(GF_LOG_MEMORY, GF_LOG_INFO);
460	}
461
462	/* Initialize command data */
463	dc_cmd_data_init(cmd_data);
464
465	i = 1;
466	while (i < argc) {
467		if (strcmp(argv[i], "-a") == 0 || strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "-av") == 0) {
468			i++;
469			if (i >= argc) {
470				fprintf(stdout, "%s", command_error);
471				fprintf(stdout, "%s", command_usage);
472				return -1;
473			}
474
475			if (strcmp(argv[i - 1], "-a") == 0 || strcmp(argv[i - 1], "-av") == 0) {
476				if (strcmp(cmd_data->audio_data_conf.filename, "") != 0) {
477					fprintf(stdout, "Audio source has been already specified.\n");
478					fprintf(stdout, "%s", command_usage);
479					return -1;
480				}
481				strcpy(cmd_data->audio_data_conf.filename, argv[i]);
482			}
483
484			if (strcmp(argv[i - 1], "-v") == 0 || strcmp(argv[i - 1], "-av") == 0) {
485				if (strcmp(cmd_data->video_data_conf.filename, "") != 0) {
486					fprintf(stdout, "Video source has been already specified.\n");
487					fprintf(stdout, "%s", command_usage);
488					return -1;
489				}
490				strcpy(cmd_data->video_data_conf.filename, argv[i]);
491			}
492
493			i++;
494		} else if (strcmp(argv[i], "-af") == 0 || strcmp(argv[i], "-vf") == 0) {
495			i++;
496			if (i >= argc) {
497				fprintf(stdout, "%s", command_error);
498				fprintf(stdout, "%s", command_usage);
499				return -1;
500			}
501
502			if (strcmp(argv[i - 1], "-af") == 0) {
503				if (strcmp(cmd_data->audio_data_conf.format, "") != 0) {
504					fprintf(stdout, "Audio format has been already specified.\n");
505					fprintf(stdout, "%s", command_usage);
506					return -1;
507				}
508				strcpy(cmd_data->audio_data_conf.format, argv[i]);
509			}
510
511			if (strcmp(argv[i - 1], "-vf") == 0) {
512				if (strcmp(cmd_data->video_data_conf.format, "") != 0) {
513					fprintf(stdout, "Video format has been already specified.\n");
514					fprintf(stdout, "%s", command_usage);
515					return -1;
516				}
517				strcpy(cmd_data->video_data_conf.format, argv[i]);
518			}
519
520			i++;
521		} else if (strcmp(argv[i], "-pixf") == 0) {
522			i++;
523			if (i >= argc) {
524				fprintf(stdout, "%s", command_error);
525				fprintf(stdout, "%s", command_usage);
526				return -1;
527			}
528			if (strcmp(cmd_data->video_data_conf.pixel_format, "") != 0) {
529				fprintf(stdout, "Input pixel format has been already specified.\n");
530				fprintf(stdout, "%s", command_usage);
531				return -1;
532			}
533			strcpy(cmd_data->video_data_conf.pixel_format, argv[i]);
534
535			i++;
536		} else if (strcmp(argv[i], "-vfr") == 0) {
537			i++;
538			if (i >= argc) {
539				fprintf(stdout, "%s", command_error);
540				fprintf(stdout, "%s", command_usage);
541				return -1;
542			}
543
544			if (cmd_data->video_data_conf.framerate != -1) {
545				fprintf(stdout, "Video framerate has been already specified.\n");
546				fprintf(stdout, "%s", command_usage);
547				return -1;
548			}
549			cmd_data->video_data_conf.framerate = atoi(argv[i]);
550			i++;
551		} else if (strcmp(argv[i], "-vres") == 0) {
552			i++;
553			if (i >= argc) {
554				fprintf(stdout, "%s", command_error);
555				fprintf(stdout, "%s", command_usage);
556				return -1;
557			}
558
559			if (cmd_data->video_data_conf.height != -1 && cmd_data->video_data_conf.width != -1) {
560				fprintf(stdout, "Video resolution has been already specified.\n");
561				fprintf(stdout, "%s", command_usage);
562				return -1;
563			}
564			dc_str_to_resolution(argv[i], &cmd_data->video_data_conf.width, &cmd_data->video_data_conf.height);
565
566			i++;
567		} else if (strcmp(argv[i], "-conf") == 0) {
568			i++;
569			if (i >= argc) {
570				fprintf(stdout, "%s", command_error);
571				fprintf(stdout, "%s", command_usage);
572				return -1;
573			}
574
575			cmd_data->conf = gf_cfg_force_new(NULL, argv[i]);
576
577			i++;
578
579		} else if (strcmp(argv[i], "-switch-source") == 0) {
580			i++;
581			if (i >= argc) {
582				fprintf(stdout, "%s", command_error);
583				fprintf(stdout, "%s", command_usage);
584				return -1;
585			}
586
587			cmd_data->switch_conf = gf_cfg_force_new(NULL, argv[i]);
588
589			i++;
590		} else if (strcmp(argv[i], "-out") == 0) {
591			i++;
592			if (i >= argc) {
593				fprintf(stdout, "%s", command_error);
594				fprintf(stdout, "%s", command_usage);
595				return -1;
596			}
597
598			strcpy(cmd_data->out_dir, argv[i]);
599
600			i++;
601#ifndef WIN32
602		} else if (strcmp(argv[i], "-v4l2f") == 0) {
603			i++;
604			if (i >= argc) {
605				fprintf(stdout, "%s", command_error);
606				fprintf(stdout, "%s", command_usage);
607				return -1;
608			}
609
610			strcpy(cmd_data->video_data_conf.v4l2f, argv[i]);
611
612			i++;
613#endif
614		} else if (strcmp(argv[i], "-seg-marker") == 0) {
615			char *m;
616			i++;
617			if (i >= argc) {
618				fprintf(stdout, "%s", command_error);
619				fprintf(stdout, "%s", command_usage);
620				return -1;
621			}
622			m = argv[i];
623			if (strlen(m) == 4) {
624				cmd_data->seg_marker = GF_4CC(m[0], m[1], m[2], m[3]);
625			} else {
626				fprintf(stdout, "Invalid marker box name specified: %s\n", m);
627				return -1;
628			}
629
630			i++;
631
632		} else if (strcmp(argv[i], "-mpd") == 0) {
633			i++;
634			if (i >= argc) {
635				fprintf(stdout, "%s", command_error);
636				fprintf(stdout, "%s", command_usage);
637				return -1;
638			}
639
640			if (strcmp(cmd_data->mpd_filename, "") != 0) {
641				fprintf(stdout, "MPD file has been already specified.\n");
642				fprintf(stdout, "%s", command_usage);
643				return -1;
644			}
645
646			strncpy(cmd_data->mpd_filename, argv[i], GF_MAX_PATH);
647			i++;
648
649		} else if (strcmp(argv[i], "-seg-dur") == 0) {
650			i++;
651			if (i >= argc) {
652				fprintf(stdout, "%s", command_error);
653				fprintf(stdout, "%s", command_usage);
654				return -1;
655			}
656
657			if (cmd_data->seg_dur != 0) {
658				fprintf(stdout, "Segment duration has been already specified.\n");
659				fprintf(stdout, "%s", command_usage);
660				return -1;
661			}
662
663			cmd_data->seg_dur = atoi(argv[i]);
664			i++;
665
666		} else if (strcmp(argv[i], "-frag-dur") == 0) {
667			i++;
668			if (i >= argc) {
669				fprintf(stdout, "%s", command_error);
670				fprintf(stdout, "%s", command_usage);
671				return -1;
672			}
673
674			if (cmd_data->frag_dur != 0) {
675				fprintf(stdout, "Fragment duration has been already specified.\n");
676				fprintf(stdout, "%s", command_usage);
677				return -1;
678			}
679
680			cmd_data->frag_dur = atoi(argv[i]);
681			i++;
682
683		} else if (strcmp(argv[i], "-ast-offset") == 0) {
684			i++;
685			if (i >= argc) {
686				fprintf(stdout, "%s", command_error);
687				fprintf(stdout, "%s", command_usage);
688				return -1;
689			}
690
691			if (cmd_data->ast_offset != -1) {
692				fprintf(stdout, "AvailabilityStartTime offset has been already specified.\n");
693				fprintf(stdout, "%s", command_usage);
694				return -1;
695			}
696
697			cmd_data->ast_offset = atoi(argv[i]);
698			i++;
699
700		} else if (strcmp(argv[i], "-time-shift") == 0) {
701			i++;
702			if (i >= argc) {
703				fprintf(stdout, "%s", command_error);
704				fprintf(stdout, "%s", command_usage);
705				return -1;
706			}
707
708			if (cmd_data->time_shift != 0) {
709				fprintf(stdout, "TimeShiftBufferDepth has been already specified.\n");
710				fprintf(stdout, "%s", command_usage);
711				return -1;
712			}
713
714			cmd_data->time_shift = atoi(argv[i]);
715			i++;
716
717		} else if (strcmp(argv[i], "-min-buffer") == 0) {
718			i++;
719			if (i >= argc) {
720				fprintf(stdout, "%s", command_error);
721				fprintf(stdout, "%s", command_usage);
722				return -1;
723			}
724			if (cmd_data->min_buffer_time != -1) {
725				fprintf(stdout, "Min Buffer Time has been already specified.\n");
726				fprintf(stdout, "%s", command_usage);
727				return -1;
728			}
729
730			cmd_data->min_buffer_time = (float)atof(argv[i]);
731			i++;
732
733		} else if (strcmp(argv[i], "-live") == 0) {
734			cmd_data->mode = LIVE_CAMERA;
735			i++;
736		} else if (strcmp(argv[i], "-npts") == 0) {
737			cmd_data->use_source_timing = 0;
738			i++;
739		} else if (strcmp(argv[i], "-live-media") == 0) {
740			cmd_data->mode = LIVE_MEDIA;
741			i++;
742		} else if (strcmp(argv[i], "-no-loop") == 0) {
743			cmd_data->no_loop = 1;
744			i++;
745		} else if (strcmp(argv[i], "-send-message") == 0) {
746			cmd_data->send_message = 1;
747			i++;
748		} else if (strcmp(argv[i], "-logs") == 0) {
749			i++;
750			if (i >= argc) {
751				fprintf(stdout, "%s", command_error);
752				fprintf(stdout, "%s", command_usage);
753				return -1;
754			}
755			if (gf_log_set_tools_levels(argv[i]) != GF_OK) {
756				fprintf(stdout, "Invalid log format %s", argv[i]);
757				return 1;
758			}
759			i++;
760		} else if (strcmp(argv[i], "-mem-track") == 0) {
761			i++;
762#ifndef GPAC_MEMORY_TRACKING
763			fprintf(stderr, "WARNING - GPAC not compiled with Memory Tracker - ignoring \"-mem-track\"\n");
764#endif
765		} else if (!strcmp(argv[i], "-lf") || !strcmp(argv[i], "-log-file")) {
766			i++;
767			if (i >= argc) {
768				fprintf(stdout, "%s", command_error);
769				fprintf(stdout, "%s", command_usage);
770				return -1;
771			}
772			cmd_data->logfile = gf_f64_open(argv[i], "wt");
773			gf_log_set_callback(cmd_data->logfile, on_dc_log);
774			i++;
775		} else if (strcmp(argv[i], "-gdr") == 0) {
776			cmd_data->gdr = 1;
777			i++;
778		} else {
779			fprintf(stdout, "%s", command_error);
780			fprintf(stdout, "%s", command_usage);
781			return -1;
782		}
783	}
784
785	if (strcmp(cmd_data->mpd_filename, "") == 0) {
786		strcpy(cmd_data->mpd_filename, "dashcast.mpd");
787	}
788
789	if (strcmp(cmd_data->out_dir, "") == 0) {
790		struct stat status;
791		strcpy(cmd_data->out_dir, "output");
792		if (stat(cmd_data->out_dir, &status) != 0) {
793			gf_mkdir(cmd_data->out_dir);
794		}
795	}
796
797	if (strcmp(cmd_data->video_data_conf.filename, "") == 0 && strcmp(cmd_data->audio_data_conf.filename, "") == 0) {
798		fprintf(stdout, "Audio/Video source must be specified.\n");
799		fprintf(stdout, "%s", command_usage);
800		return -1;
801	}
802
803	if (cmd_data->seg_dur == 0) {
804		cmd_data->seg_dur = 1000;
805	}
806
807	if (cmd_data->frag_dur == 0) {
808		cmd_data->frag_dur = cmd_data->seg_dur;
809	}
810
811	if (cmd_data->ast_offset == -1) {
812		//generate MPD as soon as possible (no offset)
813		cmd_data->ast_offset = 0;
814	}
815
816	if (cmd_data->mode == ON_DEMAND)
817		cmd_data->time_shift = -1;
818	else {
819		if (cmd_data->time_shift == 0) {
820			cmd_data->time_shift = 10;
821		}
822	}
823
824	if (cmd_data->min_buffer_time == -1) {
825		cmd_data->min_buffer_time = 1.0;
826	}
827
828	fprintf(stdout, "\33[34m\33[1m");
829	fprintf(stdout, "Options:\n");
830	fprintf(stdout, "    video source: %s\n", cmd_data->video_data_conf.filename);
831	if (strcmp(cmd_data->video_data_conf.format, "") != 0) {
832		fprintf(stdout, "    video format: %s\n", cmd_data->video_data_conf.format);
833	}
834#ifndef WIN32
835	if (strcmp(cmd_data->video_data_conf.v4l2f, "") != 0) {
836		fprintf(stdout, "    v4l2 format: %s\n", cmd_data->video_data_conf.v4l2f);
837	}
838#endif
839	if (cmd_data->video_data_conf.framerate != -1) {
840		fprintf(stdout, "    video framerate: %d\n", cmd_data->video_data_conf.framerate);
841	}
842	if (cmd_data->video_data_conf.height != -1 && cmd_data->video_data_conf.width != -1) {
843		fprintf(stdout, "    video resolution: %dx%d\n", cmd_data->video_data_conf.width, cmd_data->video_data_conf.height);
844	}
845
846	fprintf(stdout, "    audio source: %s\n", cmd_data->audio_data_conf.filename);
847	if (strcmp(cmd_data->audio_data_conf.format, "") != 0) {
848		fprintf(stdout, "    audio format: %s\n", cmd_data->audio_data_conf.format);
849	}
850	fprintf(stdout, "\33[0m");
851//	fflush(stdout);
852
853	if (!cmd_data->conf) {
854		cmd_data->conf = gf_cfg_force_new(NULL, "dashcast.conf");
855		dc_create_configuration(cmd_data);
856	}
857	dc_read_configuration(cmd_data);
858
859	if (!cmd_data->switch_conf) {
860		cmd_data->switch_conf = gf_cfg_force_new(NULL, "switch.conf");
861	}
862	dc_read_switch_config(cmd_data);
863
864	return 0;
865}