Example #1
0
int main(int argc, char **argv)
{
	int ret = 0;

	if (argc < 2) {
		fprintf(stderr, "USAGE: %s file1 [file2 ... filen]\n", argv[0]);
		ret = 1;
		goto exit;
	}

#ifdef GPAC_MEMORY_TRACKING
	gf_sys_init(GF_TRUE);
#else
	gf_sys_init(GF_FALSE);
#endif
	gf_log_set_tool_level(GF_LOG_ALL, GF_LOG_WARNING);

	if (!player_foreach(argc, argv)) {
		ret = 1;
		goto exit;
	}

exit:
	gf_sys_close();
	return ret;
}
Example #2
0
static void rewrite_log_tools(u32 tool)
{
	char *logs;
	if (tool == GF_LOG_ALL) {
		gf_log_set_tool_level(GF_LOG_ALL, log_level);
	} else {
		if (gf_log_tool_level_on(tool, log_level)) {
			gf_log_set_tool_level(tool, GF_LOG_QUIET);
		} else {
			gf_log_set_tool_level(tool, log_level);
		}
	}
	logs = gf_log_get_tools_levels();
	if (logs) {
		gf_cfg_set_key(user.config, "General", "Logs", logs);
		gf_free(logs);
	}
	setup_logs();
}
Example #3
0
File: main.c Project: ARSekkat/gpac
/*parse TS2HDS arguments*/
static GFINLINE GF_Err parse_args(int argc, char **argv, char **input, char **output, u64 *curr_time, u32 *segnum)
{
	Bool input_found=0, output_found=0;
	char *arg = NULL, *error_msg = "no argument found";
	s32 i;

	for (i=1; i<argc; i++) {
		arg = argv[i];
		if (!strnicmp(arg, "-h", 2) || strstr(arg, "-help")) {
			usage(argv[0]);
			return GF_EOS;
		} else if (!strnicmp(arg, "-input", 6)) {
			CHECK_NEXT_ARG
			*input = argv[++i];
			input_found = 1;
		} else if (!strnicmp(arg, "-output", 6)) {
			CHECK_NEXT_ARG
			*output = argv[++i];
			output_found = 1;
		} else if (!strnicmp(arg, "-segnum", 6)) {
			CHECK_NEXT_ARG
			*segnum = atoi(argv[++i]);
		} else if (!strnicmp(arg, "-mem-track", 10)) {
#ifdef GPAC_MEMORY_TRACKING
			gf_sys_close();
			gf_sys_init(GF_MemTrackerSimple);
			gf_log_set_tool_level(GF_LOG_MEMORY, GF_LOG_INFO);
#else
			fprintf(stderr, "WARNING - GPAC not compiled with Memory Tracker - ignoring \"-mem-track\"\n");
#endif
		} else {
			error_msg = "unknown option \"%s\"";
			goto error;
		}
	}

	/*syntax is correct; now testing the presence of mandatory arguments*/
	if (input_found && output_found) {
		return GF_OK;
	} else {
		if (!input_found)
			fprintf(stderr, "Error: input argument not found\n\n");
		if (!output_found)
			fprintf(stderr, "Error: output argument not found\n\n");
		return GF_BAD_PARAM;
	}

error:
	if (!arg) {
		fprintf(stderr, "Error: %s\n\n", error_msg);
	} else {
		fprintf(stderr, "Error: %s \"%s\"\n\n", error_msg, arg);
	}
	return GF_BAD_PARAM;
}
Example #4
0
static void setup_logs()
{
	if (log_file) fclose(log_file);
	log_file = NULL;

	gf_log_set_tool_level(GF_LOG_ALL, GF_LOG_ERROR);
	gf_log_set_callback(NULL, NULL);

	if (log_rti) {
		const char *filename = gf_cfg_get_key(user.config, "General", "LogFile");
		if (!filename) {
			gf_cfg_set_key(user.config, "General", "LogFile", "\\gpac_logs.txt");
			filename = "\\gpac_logs.txt";
		}
		log_file = gf_f64_open(filename, "a+t");

		fprintf(log_file, "!! GPAC RunTime Info for file %s !!\n", the_url);
		fprintf(log_file, "SysTime(ms)\tSceneTime(ms)\tCPU\tFPS\tMemory(kB)\tObservation\n");

		gf_log_set_tool_level(GF_LOG_ALL, GF_LOG_ERROR);
		gf_log_set_tool_level(GF_LOG_RTI, GF_LOG_DEBUG);
		gf_log_set_callback(log_file, on_gpac_rti_log);

		GF_LOG(GF_LOG_DEBUG, GF_LOG_RTI, ("[RTI] System state when enabling log\n"));
	} else {
		const char *filename = gf_cfg_get_key(user.config, "General", "LogFile");
		if (!filename) {
			gf_cfg_set_key(user.config, "General", "LogFile", "\\gpac_logs.txt");
			filename = "\\gpac_logs.txt";
		}
		const char *logs = gf_cfg_get_key(user.config, "General", "Logs");
		if (logs) {
			if (gf_log_set_tools_levels( logs ) != GF_OK) {
			} else {
				if (log_file = gf_f64_open(filename, "a+t")) {
					gf_log_set_callback(log_file, on_gpac_log);
				}
			}
		}
	}
}
Example #5
0
void COsmo4AppView::SetupLogs()
{
	const char *opt;

#ifndef GPAC_GUI_ONLY
	gf_mx_p(m_mx);
	if (do_log) {
		gf_log_set_tool_level(GF_LOG_ALL, GF_LOG_NONE);
		do_log = 0;
	}
	/*setup GPAC logs: log all errors*/
	opt = gf_cfg_get_key(m_user.config, "General", "Logs");
	if (opt && !strstr(opt, "none")){
		const char *filename = gf_cfg_get_key(m_user.config, "General", "LogFile");
		if (!filename) {
			gf_cfg_set_key(m_user.config, "General", "LogFile", "\\data\\gpac_logs.txt");
			filename = "\\data\\gpac_logs.txt";
		}
		m_Logs = gf_f64_open(filename, "wt");
		if (!m_Logs) {
			MessageBox("Cannot open log file - disabling logs", "Warning !");
		} else {
			MessageBox("Debug logs enabled!", filename);
			do_log = 1;
			gf_log_set_tools_levels( opt );
		}
	}
	if (!do_log) {
		gf_log_set_tool_level(GF_LOG_ALL, GF_LOG_ERROR);
		if (m_Logs) fclose(m_Logs);
	}

	gf_log_set_callback(this, on_gpac_log);
	gf_mx_v(m_mx);

	GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("Osmo4 logs initialized\n"));
#endif
}
Example #6
0
/// <summary>
/// Entry point for the application
/// </summary>
/// <param name="hInstance">handle to the application instance</param>
/// <param name="hPrevInstance">always 0</param>
/// <param name="lpCmdLine">command line arguments</param>
/// <param name="nCmdShow">whether to display minimized, maximized, or normally</param>
/// <returns>status</returns>
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
{
    CColorBasics application;

	//params:
	DASHout *dasher;
	loook_opt *options;
	
#ifdef _DEBUG
	RedirectIOToConsole();
#endif
	
	options = loook_init();
	
	gf_sys_init(GF_MemTrackerNone);
#ifdef USE_GPAC_LOG
	gf_log_set_tool_level(GF_LOG_DASH, GF_LOG_DEBUG);
	if (gf_log_tool_level_on(GF_LOG_DASH, GF_LOG_DEBUG)) {
		printf("log on");
	} else {
		printf("log off");
	}
	gf_log_set_callback(NULL, on_gpac_log);
#endif
	dasher = muxer_init(options);

	if(!dasher){
		return 1;
	}	

	application.setDasher(dasher);

    application.Run(hInstance, nCmdShow, dasher);
	/*
KinectSensor sensor;

  foreach (var potentialSensor in KinectSensor.KinectSensors)
  {
    if (potentialSensor.Status == KinectStatus.Connected)
    {
      this.sensor = potentialSensor;
      break;
    }
  }*/
}
Example #7
0
int stream_file_rtp(int argc, char **argv) 
{
	GF_ISOMRTPStreamer *file_streamer;
	char *sdp_file = "session.sdp";
	char *ip_dest = "127.0.0.1";
	char *ifce_addr = NULL;
	char *inName = NULL;
	char *logs=NULL; 
	FILE *logfile=NULL;
	u16 port = 7000;
	u32 ttl = 1;
	Bool loop = 1;
	Bool mem_track = 0;
	Bool force_mpeg4 = 0;
	u32 path_mtu = 1450;
	u32 i;

	for (i = 1; i < (u32) argc ; i++) {
		char *arg = argv[i];

		if (arg[0] != '-') {
			if (inName) { fprintf(stderr, "Error - 2 input names specified, please check usage\n"); return 1; }
			inName = arg;
		}
		else if (!stricmp(arg, "-noloop")) loop = 0;
		else if (!stricmp(arg, "-mpeg4")) force_mpeg4 = 1;
		else if (!strnicmp(arg, "-port=", 6)) port = atoi(arg+6);
		else if (!strnicmp(arg, "-mtu=", 5)) path_mtu = atoi(arg+5);
		else if (!strnicmp(arg, "-dst=", 5)) ip_dest = arg+5;
		else if (!strnicmp(arg, "-ttl=", 5)) ttl = atoi(arg+5);
		else if (!strnicmp(arg, "-ifce=", 6)) ifce_addr = arg+6;
		else if (!strnicmp(arg, "-sdp=", 5)) sdp_file = arg+5;
		else if (!stricmp(arg, "-mem-track")) mem_track = 1;
		else if (!strnicmp(arg, "-logs=", 6)) logs = arg+6;
		else if (!strnicmp(arg, "-lf=", 4)) logfile = gf_f64_open(arg+4, "wt");
	}

	gf_sys_init(mem_track);
	if (logs) 
		gf_log_set_tools_levels(logs);
	else 
		gf_log_set_tool_level(GF_LOG_RTP, GF_LOG_INFO); //set to debug to have packet list
	if (logfile) {
		gf_log_set_callback(logfile, on_logs);
	}

	if (!gf_isom_probe_file(inName)) {
		fprintf(stderr, "File %s is not a valid ISO Media file and cannot be streamed\n", inName);
		if (logfile) fclose(logfile);
		gf_sys_close();
		return 1;
	}

	file_streamer = gf_isom_streamer_new(inName, ip_dest, port, loop, force_mpeg4, path_mtu, ttl, ifce_addr);
	if (!file_streamer) {
		fprintf(stderr, "Cannot create file streamer\n");
	} else {
		u32 check = 50;
		fprintf(stderr, "Starting streaming %s to %s:%d\n", inName, ip_dest, port);
		gf_isom_streamer_write_sdp(file_streamer, sdp_file);

		while (1) {
			gf_isom_streamer_send_next_packet(file_streamer, 0, 0);
			check--;
			if (!check) {
				if (gf_prompt_has_input()) {
					char c = (char) gf_prompt_get_char(); 
					if (c=='q') break;
				}
				check = 50;
			}
		}
		gf_isom_streamer_del(file_streamer);
	}
	if (logfile) fclose(logfile);
	gf_sys_close();
	return 0;
}
Example #8
0
int live_session(int argc, char **argv)
{
	GF_Err e;
	int i;
	char *filename = NULL;
	char *dst = NULL;
	char *ifce_addr = NULL;
	char *sdp_name = "session.sdp";
	u16 dst_port = 7000;
	u32 load_type=0;
	u32 check;
	u32 ttl = 1;
	u32 path_mtu = 1450;
	s32 next_time;
	u64 last_src_modif, mod_time;
	char *src_name = NULL;
	Bool run, has_carousel, no_rap;
    Bool udp = 0;
	u16 sk_port=0;
    GF_Socket *sk = NULL;
	LiveSession livesess;
	RTPChannel *ch;
	char *update_buffer = NULL;
	u32 update_buffer_size = 0;
	u16 aggregate_on_stream;
	Bool adjust_carousel_time, force_rap, aggregate_au, discard_pending, signal_rap, version_inc;
	Bool update_context;
	u32 period, ts_delta, signal_critical;
	u16 es_id;
	e = GF_OK;
	aggregate_au = 1;
	es_id = 0;
	no_rap = 0;
	gf_sys_init(0);

	memset(&livesess, 0, sizeof(LiveSession));
	
	gf_log_set_tool_level(GF_LOG_ALL, GF_LOG_INFO);

	for (i=1; i<argc; i++) {
		char *arg = argv[i];
		if (arg[0] != '-') filename = arg;
		else if (!strnicmp(arg, "-dst=", 5)) dst = arg+5;
		else if (!strnicmp(arg, "-port=", 6)) dst_port = atoi(arg+6);
		else if (!strnicmp(arg, "-sdp=", 5)) sdp_name = arg+5;
		else if (!strnicmp(arg, "-mtu=", 5)) path_mtu = atoi(arg+5);
		else if (!strnicmp(arg, "-ttl=", 5)) ttl = atoi(arg+5);
		else if (!strnicmp(arg, "-ifce=", 6)) ifce_addr = arg+6;
        else if (!strnicmp(arg, "-no-rap", 7)) no_rap = 1;
		else if (!strnicmp(arg, "-dims", 5)) load_type = GF_SM_LOAD_DIMS;
		else if (!strnicmp(arg, "-src=", 5)) src_name = arg+5;
        else if (!strnicmp(arg, "-udp=", 5)) { sk_port = atoi(arg+5); udp = 1; }
        else if (!strnicmp(arg, "-tcp=", 5)) { sk_port = atoi(arg+5); udp = 0; }		
	}
	if (!filename) {
		fprintf(stderr, "Missing filename\n");
		PrintLiveUsage();
		return 1;
	}

	if (dst_port && dst) livesess.streams = gf_list_new();

	livesess.seng = gf_seng_init(&livesess, filename, load_type, NULL, (load_type == GF_SM_LOAD_DIMS) ? 1 : 0);
    if (!livesess.seng) {
		fprintf(stderr, "Cannot create scene engine\n");
		return 1;
    }
	if (livesess.streams) live_session_setup(&livesess, dst, dst_port, path_mtu, ttl, ifce_addr, sdp_name);

	has_carousel = 0;
	last_src_modif = src_name ? gf_file_modification_time(src_name) : 0;

    if (sk_port) {
        sk = gf_sk_new(udp ? GF_SOCK_TYPE_UDP : GF_SOCK_TYPE_TCP);
        if (udp) {
            e = gf_sk_bind(sk, NULL, sk_port, NULL, 0, 0);
            if (e != GF_OK) {
                if (sk) gf_sk_del(sk);
                sk = NULL;
            }
        } else {
        }
    }


	for (i=0; i<argc; i++) {
		char *arg = argv[i];
		if (!strnicmp(arg, "-rap=", 5)) {
			u32 period, id, j;
			RTPChannel *ch;
			period = id = 0;
			if (strchr(arg, ':')) {
				sscanf(arg, "-rap=ESID=%u:%u", &id, &period);
				e = gf_seng_enable_aggregation(livesess.seng, id, 1);
				if (e) {
					fprintf(stderr, "Cannot enable aggregation on stream %u: %s\n", id, gf_error_to_string(e));
					goto exit;
				}
			} else {
				sscanf(arg, "-rap=%u", &period);
			}

			j=0;
			while (NULL != (ch = gf_list_enum(livesess.streams, &j))) {
				if (!id || (ch->ESID==id))
					ch->carousel_period = period;
			}
			has_carousel = 1;
		}
	}

	i=0;
	while (NULL != (ch = gf_list_enum(livesess.streams, &i))) {
		if (ch->carousel_period) {
			has_carousel = 1;
			break;
		}
	}

	update_context = 0;

	if (has_carousel || !no_rap) {
		livesess.carousel_generation = 1;
		gf_seng_encode_context(livesess.seng, live_session_callback);
		livesess.carousel_generation = 0;
	}

	live_session_send_carousel(&livesess, NULL);

	check = 10;
	run = 1;
	while (run) {
		check--;
		if (!check) {
			check = 10;
			if (gf_prompt_has_input()) {
				char c = gf_prompt_get_char();
				switch (c) {
				case 'q':
					run=0;
					break;
				case 'U':
					livesess.critical = 1;
				case 'u':
				{
					GF_Err e;
					char szCom[8192];
					fprintf(stderr, "Enter command to send:\n");
					szCom[0] = 0;
					if (1 > scanf("%[^\t\n]", szCom)){
					    fprintf(stderr, "No command entered properly, aborting.\n");
					    break;
					}
					/*stdin flush bug*/
					while (getchar()!='\n') {}
					e = gf_seng_encode_from_string(livesess.seng, 0, 0, szCom, live_session_callback);
					if (e) fprintf(stderr, "Processing command failed: %s\n", gf_error_to_string(e));
					e = gf_seng_aggregate_context(livesess.seng, 0);
					livesess.critical = 0;
					update_context = 1;
				}
					break;
				case 'E':
					livesess.critical = 1;
				case 'e':
				{
					GF_Err e;
					char szCom[8192];
					fprintf(stderr, "Enter command to send:\n");
					szCom[0] = 0;
					if (1 > scanf("%[^\t\n]", szCom)){
					    printf("No command entered properly, aborting.\n");
					    break;
					}
					/*stdin flush bug*/
					while (getchar()!='\n') {}
					e = gf_seng_encode_from_string(livesess.seng, 0, 1, szCom, live_session_callback);
					if (e) fprintf(stderr, "Processing command failed: %s\n", gf_error_to_string(e));
					livesess.critical = 0;				
					e = gf_seng_aggregate_context(livesess.seng, 0);

				}
					break;

				case 'p':
				{
					char rad[GF_MAX_PATH];
					fprintf(stderr, "Enter output file name - \"std\" for stderr: ");
					if (1 > scanf("%s", rad)){
					    fprintf(stderr, "No ouput file name entered, aborting.\n");
					    break;
					}
					e = gf_seng_save_context(livesess.seng, !strcmp(rad, "std") ? NULL : rad);
					fprintf(stderr, "Dump done (%s)\n", gf_error_to_string(e));
				}
					break;
				case 'F':
					update_context = 1;
				case 'f':
					livesess.force_carousel = 1;
					break;
				}
				e = GF_OK;
			}
		}

		/*process updates from file source*/
		if (src_name) {
			mod_time = gf_file_modification_time(src_name);
			if (mod_time != last_src_modif) {
				FILE *srcf;
				char flag_buf[201], *flag;
				fprintf(stderr, "Update file modified - processing\n");
				last_src_modif = mod_time;

				srcf = gf_f64_open(src_name, "rt");
				if (!srcf) continue;

				/*checks if we have a broadcast config*/
				if (!fgets(flag_buf, 200, srcf))
				  flag_buf[0] = '\0';
				fclose(srcf);

				aggregate_on_stream = (u16) -1;
				adjust_carousel_time = force_rap = discard_pending = signal_rap = signal_critical = 0;
				aggregate_au = version_inc = 1;
				period = -1;
				ts_delta = 0;
				es_id = 0;

				/*find our keyword*/
				flag = strstr(flag_buf, "gpac_broadcast_config ");
				if (flag) {
					flag += strlen("gpac_broadcast_config ");
					/*move to next word*/
					while (flag && (flag[0]==' ')) flag++;

					while (1) {
						char *sep = strchr(flag, ' ');
						if (sep) sep[0] = 0;
						if (!strnicmp(flag, "esid=", 5)) es_id = atoi(flag+5);
						else if (!strnicmp(flag, "period=", 7)) period = atoi(flag+7);
						else if (!strnicmp(flag, "ts=", 3)) ts_delta = atoi(flag+3);
						else if (!strnicmp(flag, "carousel=", 9)) aggregate_on_stream = atoi(flag+9);
						else if (!strnicmp(flag, "restamp=", 8)) adjust_carousel_time = atoi(flag+8);

						else if (!strnicmp(flag, "discard=", 8)) discard_pending = atoi(flag+8);
						else if (!strnicmp(flag, "aggregate=", 10)) aggregate_au = atoi(flag+10);
						else if (!strnicmp(flag, "force_rap=", 10)) force_rap = atoi(flag+10);
						else if (!strnicmp(flag, "rap=", 4)) signal_rap = atoi(flag+4);
						else if (!strnicmp(flag, "critical=", 9)) signal_critical = atoi(flag+9);
						else if (!strnicmp(flag, "vers_inc=", 9)) version_inc = atoi(flag+9);
						if (sep) {
							sep[0] = ' ';
							flag = sep+1;
						} else {
							break;
						}
					}

					set_broadcast_params(&livesess, es_id, period, ts_delta, aggregate_on_stream, adjust_carousel_time, force_rap, aggregate_au, discard_pending, signal_rap, signal_critical, version_inc);
				}

				e = gf_seng_encode_from_file(livesess.seng, es_id, aggregate_au ? 0 : 1, src_name, live_session_callback);
				if (e) fprintf(stderr, "Processing command failed: %s\n", gf_error_to_string(e));
				e = gf_seng_aggregate_context(livesess.seng, 0);

				update_context = no_rap ? 0 : 1;
			}
		}

		/*process updates from socket source*/
		if (sk) {
		    char buffer[2049];
		    u32 bytes_read;
		    u32 update_length;
		    u32 bytes_received;


			e = gf_sk_receive(sk, buffer, 2048, 0, &bytes_read);
			if (e == GF_OK) {
				u32 hdr_length = 0;
				u8 cmd_type = buffer[0];
				bytes_received = 0;
				switch (cmd_type) {
				case 0:
				{
					GF_BitStream *bs = gf_bs_new(buffer, bytes_read, GF_BITSTREAM_READ);
					gf_bs_read_u8(bs);
					es_id = gf_bs_read_u16(bs);
					aggregate_on_stream = gf_bs_read_u16(bs);
					if (aggregate_on_stream==0xFFFF) aggregate_on_stream = -1;
					adjust_carousel_time = gf_bs_read_int(bs, 1);
					force_rap = gf_bs_read_int(bs, 1);
					aggregate_au = gf_bs_read_int(bs, 1);
					discard_pending = gf_bs_read_int(bs, 1);
					signal_rap = gf_bs_read_int(bs, 1);
					signal_critical = gf_bs_read_int(bs, 1);
					version_inc = gf_bs_read_int(bs, 1);
					gf_bs_read_int(bs, 1);
					period = gf_bs_read_u16(bs);
					if (period==0xFFFF) period = -1;
					ts_delta = gf_bs_read_u16(bs);
					update_length = gf_bs_read_u32(bs);
					hdr_length = 12;
					gf_bs_del(bs);
				}

					set_broadcast_params(&livesess, es_id, period, ts_delta, aggregate_on_stream, adjust_carousel_time, force_rap, aggregate_au, discard_pending, signal_rap, signal_critical, version_inc);
					break;
				default:
					update_length = 0;
					break;
				}

				if (update_buffer_size <= update_length) {
					update_buffer = gf_realloc(update_buffer, update_length+1);
					update_buffer_size = update_length+1;
				}
				if (update_length && (bytes_read>hdr_length) ) {
					memcpy(update_buffer, buffer+hdr_length, bytes_read-hdr_length);
					bytes_received = bytes_read-hdr_length;
				}
				while (bytes_received<update_length) {
					e = gf_sk_receive(sk, buffer, 2048, 0, &bytes_read);
					switch (e) {
					case GF_IP_NETWORK_EMPTY:
						break;
					case GF_OK:
						memcpy(update_buffer+bytes_received, buffer, bytes_read);
						bytes_received += bytes_read;
						break;
					default:
						fprintf(stderr, "Error with UDP socket : %s\n", gf_error_to_string(e));
						break;
					}
				}
				update_buffer[update_length] = 0;

				if (update_length) {
					e = gf_seng_encode_from_string(livesess.seng, es_id, aggregate_au ? 0 : 1, update_buffer, live_session_callback);
					if (e) fprintf(stderr, "Processing command failed: %s\n", gf_error_to_string(e));
					e = gf_seng_aggregate_context(livesess.seng, 0);

					update_context = 1;
				}
			}
		}

		if (update_context) {
			livesess.carousel_generation=1;
			e = gf_seng_encode_context(livesess.seng, live_session_callback	);
			livesess.carousel_generation=0;
			update_context = 0;
		}

		if (livesess.force_carousel) {
			live_session_send_carousel(&livesess, NULL);
			livesess.force_carousel = 0;
			continue;
		}

		if (!has_carousel) {
			gf_sleep(10);
			continue;
		}
		ch = next_carousel(&livesess, &next_time); 
		if ((ch==NULL) || (next_time > 20)) {
			gf_sleep(20);
			continue;
		}
		if (next_time) gf_sleep(next_time);
		live_session_send_carousel(&livesess, ch);
	}

exit:
	live_session_shutdown(&livesess);
	if (update_buffer) gf_free(update_buffer);
	if (sk) gf_sk_del(sk);
	gf_sys_close();
	return e ? 1 : 0;
}
Example #9
0
int dc_parse_command(int argc, char **argv, CmdData *cmd_data)
{
	Bool use_mem_track = GF_FALSE;
	int i;

	const char *command_usage =
	    "Usage: DashCast [options]\n"
	    "\n"
	    "General options:\n"
	    "    -log-file filename       set output log file. Also works with -lf\n"
	    "    -logs LOGS               set log tools and levels, formatted as a ':'-separated list of toolX[:toolZ]@levelX\n"
#ifdef GPAC_MEMORY_TRACKING
	    "    -mem-track               enable the memory tracker\n"
#endif
	    "    -conf filename           set the configuration file name (default: dashcast.conf)\n"
	    "    -switch-source filename  set the configuration file name for source switching\n"
	    "\n"
	    "Live options:\n"
	    "    -live                    system is live and input is a camera\n"
	    "    -live-media              system is live and input is a media file\n"
	    "    -no-loop                 system does not loop on the input media file when live\n"
	    "    -dynamic-ast             changes segment availability start time at each MPD generation (old behaviour but not allowed in most profiles)\n"
	    "    -insert-utc              inserts UTC clock at the start of each segment\n"
	    "\n"
	    "Source options:\n"
	    "    -npts                    use frame counting for timestamps (not error-free) instead of source timing (default)\n"
	    "    -av string               set the source name for a multiplexed audio and video input\n"
	    "                                - if this option is present, neither '-a' nor '-v' shall be present\n"
	    "* Video options:\n"
	    "    -v string                set the source name for a video input\n"
	    "                                - if input is from a webcam, use \"/dev/video[x]\" \n"
	    "                                  where x is the video device number\n"
	    "                                - if input is the screen video, use \":0.0+[x],[y]\" \n"
	    "                                  which captures from upper-left at x,y\n"
	    "                                - if input is from stdin, use \"pipe:\"\n"
	    "    -vf string               set the input video format\n"
#ifdef WIN32
	    "                                - to capture from a VfW webcam, set vfwcap\n"
	    "                                - to capture from a directshow device, set dshow\n"
#else
	    "                                - to capture from a webcam, set video4linux2\n"
	    "                                - to capture the screen, set x11grab\n"
	    "    -v4l2f inv4l2f           inv4l2f is the input format for webcam acquisition\n"
	    "                                - it can be mjpeg, yuyv422, etc.\n"
#endif
	    "    -pixf FMT                set the input pixel format\n"
	    "    -vfr N                   force the input video framerate\n"
	    "    -vres WxH                force the video resolution (e.g. 640x480)\n"
	    "    -vcrop XxY               crop the source video from X pixels left and Y pixels top. Must be used with -vres.\n"
	    "    -gdr                     use Gradual Decoder Refresh feature for video encoding (h264 codec only)\n"
	    "* Audio options:\n"
	    "    -a string                set the source name for an audio input\n"
	    "                                - if input is from microphone, use \"plughw:[x],[y]\"\n"
	    "                                  where x is the card number and y is the device number\n"
	    "    -af string               set the input audio format\n"
	    "\n"
	    "Output options:\n"
	    "* Video encoding options:\n"
	    "    -vcodec string          set the output video codec (default: h264)\n"
#if 0 //TODO: bind to option and params - test first how it binds to current input parameters
	    "    -vb int                 set the output video bitrate (in bits)\n"
#endif
	    "    -vcustom string         send custom parameters directly to the audio encoder\n"
	    "* Audio encoding options:\n"
	    "    -acodec string          set the output audio codec (default: aac)\n"
#if 0 //TODO: bind to option and params - test first how it binds to current input parameters
	    "    -ab int                 set the output audio bitrate in bits (default: 192000)\n"
	    "    -as int                 set the sample rate (default: 44100)\n"
	    "    -ach int                set the number of output audio channels (default: 2)\n"
#endif
	    "    -acustom string         send custom parameters directly to the audio encoder\n"
	    "\n"
	    "DASH options:\n"
	    "    -seg-dur dur:int         set the segment duration in millisecond (default value: 1000)\n"
	    "    -frag-dur dur:int        set the fragment duration in millisecond (default value: 1000)\n"
	    "    -seg-marker marker:str   add a marker box named marker at the end of DASH segment\n"
	    "    -out outdir:str          outdir is the output data directory (default: output)\n"
	    "    -mpd mpdname:str         mpdname is the MPD file name (default: dashcast.mpd)\n"
	    "    -ast-offset dur:int      dur is the MPD availabilityStartTime shift in milliseconds (default value: 1000)\n"
	    "    -mpd-refresh dur:int     dur is the MPD minimumUpdatePeriod in seconds\n"
	    "    -time-shift dur:int      dur is the MPD TimeShiftBufferDepth in seconds\n"
	    "                                - the default value is 10. Specify -1 to keep all files.\n"
	    "    -min-buffer dur:float    dur is the MPD minBufferTime in seconds (default value: 1.0)\n"
	    "    -base-url baseurl:str    baseurl is the MPD BaseURL\n"
	    "\n"
	    "\n"
	    "Examples:\n"
	    "\n"
	    "    DashCast -av test.avi -live-media\n"
	    "    DashCast -a test_audio.mp3 -v test_audio.mp4 -live-media\n"
#ifdef WIN32
	    "    DashCast -vf vfwcap -vres 1280x720 -vfr 24 -v 0 -live\n"
	    "    DashCast -vf dshow  -vres 1280x720 -vfr 24 -v video=\"screen-capture-recorder\" -live (please install http://screencapturer.sf.net/)\n"
	    "    DashCast -vf dshow  -vres 1280x720 -vfr 24 -v video=\"YOUR-WEBCAM\" -pixf yuv420p -live\n"
#else
	    "    DashCast -vf video4linux2 -vres 1280x720 -vfr 24 -v4l2f mjpeg -v /dev/video0 -af alsa -a plughw:1,0 -live\n"
	    "    DashCast -vf x11grab -vres 800x600 -vfr 25 -v :0.0 -live\n"
#endif
	    "\n";

	const char *command_error = "\33[31mUnknown option or missing mandatory argument.\33[0m\n";

	if (argc == 1) {
		fprintf(stderr, "%s", command_usage);
		return -2;
	}

#ifdef GPAC_MEMORY_TRACKING
	i = 1;
	while (i < argc) {
		if (strcmp(argv[i], "-mem-track") == 0) {
			use_mem_track = GF_TRUE;
			break;
		}
		i++;
	}
#endif

	gf_sys_init(use_mem_track);

	if (use_mem_track) {
		gf_log_set_tool_level(GF_LOG_MEMORY, GF_LOG_INFO);
	}

	/* Initialize command data */
	dc_cmd_data_init(cmd_data);

	i = 1;
	while (i < argc) {
		if (strcmp(argv[i], "-a") == 0 || strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "-av") == 0) {
			DASHCAST_CHECK_NEXT_ARG
			if (strcmp(argv[i - 1], "-a") == 0 || strcmp(argv[i - 1], "-av") == 0) {
				if (strcmp(cmd_data->audio_data_conf.filename, "") != 0) {
					fprintf(stderr, "Audio source has already been specified.\n");
					fprintf(stderr, "%s", command_usage);
					return -1;
				}
				strcpy(cmd_data->audio_data_conf.filename, argv[i]);
			}

			if (strcmp(argv[i - 1], "-v") == 0 || strcmp(argv[i - 1], "-av") == 0) {
				if (strcmp(cmd_data->video_data_conf.filename, "") != 0) {
					fprintf(stderr, "Video source has already been specified.\n");
					fprintf(stderr, "%s", command_usage);
					return -1;
				}
				strcpy(cmd_data->video_data_conf.filename, argv[i]);
			}

			i++;
		} else if (strcmp(argv[i], "-af") == 0 || strcmp(argv[i], "-vf") == 0) {
Example #10
0
//Create window message fuction. when the window is created, also initialize a instance of
//GPAC player instance.
LRESULT CGPAXPlugin::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
    if (m_term) return 0;
    const char *str;

    if (m_hWnd==NULL) return 0;

	gf_sys_init(0);

	//Create a structure m_user for initialize the terminal. the parameters to set:
	//1)config file path
	//2)Modules file path
	//3)window handler
	//4)EventProc
    memset(&m_user, 0, sizeof(m_user));

	gf_log_set_tool_level(GF_LOG_ALL, GF_LOG_ERROR);

    m_user.config = gf_cfg_init(NULL, NULL);
    if(!m_user.config) {
#ifdef _WIN32_WCE
		::MessageBox(NULL, _T("GPAC Configuration file not found"), _T("Fatal Error"), MB_OK);
#else
		::MessageBox(NULL, "GPAC Configuration file not found", "Fatal Error", MB_OK);
#endif
		goto err_exit;
	}

/*check log file*/	
	str = gf_cfg_get_key(m_user.config, "General", "LogFile");
	if (str) {
		m_pLogs = gf_f64_open(str, "wt");
		if (m_pLogs) gf_log_set_callback(m_pLogs, gpax_do_log);
	}
 
	/*if logs are specified, use them*/
	gf_log_set_tools_levels( gf_cfg_get_key(m_user.config, "General", "Logs") );
	

    str = gf_cfg_get_key(m_user.config, "General", "ModulesDirectory");
    m_user.modules = gf_modules_new(str, m_user.config);
    if(!gf_modules_get_count(m_user.modules)) goto err_exit;

    m_user.os_window_handler = m_hWnd;
    m_user.opaque = this;
    m_user.EventProc = GPAX_EventProc;

	//create a terminal
    m_term = gf_term_new(&m_user);

	if (!m_term) goto err_exit;
	
	gf_term_set_option(m_term, GF_OPT_AUDIO_VOLUME, 100);
    
	LoadDATAUrl();

	RECT rc;
    ::GetWindowRect(m_hWnd, &rc);
    m_width = rc.right-rc.left;
    m_height = rc.bottom-rc.top;
	if (m_bAutoStart && strlen(m_url)) Play();
    return 0;

	//Error Processing
err_exit:
    if(m_user.modules)
        gf_modules_del(m_user.modules);
    m_user.modules = NULL;
    if(m_user.config)
        gf_cfg_del(m_user.config);
    m_user.config = NULL;
	gf_sys_close();
	return 1;
}
Example #11
0
int main(int argc, char **argv)
{
	GF_Err e;
	VariantPlaylist * pl = NULL;
	char *url = argv[1];
	//char *cache_m3u8_file;
	u32 i, count;
	FILE *fmpd;
	Bool verbose = 0;
	u32 update_interval = 0;
	char *m3u8_local_name = "file.m3u8";
	Bool is_local = 0;

	gf_sys_init(0);

	gf_log_set_tool_level(GF_LOG_NETWORK, verbose ? GF_LOG_DEBUG : GF_LOG_INFO);

	while (1) {

		if (gf_url_is_local(url)) {
			m3u8_local_name = url;
			is_local = 1;
		} else {
			e = gf_dm_wget(url, m3u8_local_name, 0, 0);
			if (e != GF_OK) return -1;
		}

		e = parse_root_playlist(m3u8_local_name, &pl, ".");
		if (e != GF_OK) return -1;
		
		fmpd = fopen(argv[2], "wt");
		
		fprintf(fmpd, "<MPD type=\"Live\" xmlns=\"urn:3GPP:ns:PSS:AdaptiveHTTPStreamingMPD:2009\">\n");
		fprintf(fmpd, " <ProgramInformation moreInformationURL=\"http://gpac.sourceforge.net\">\n");
		fprintf(fmpd, "  <Title>Media Presentation Description for file %s</Title>\n", url);
		fprintf(fmpd, "  <Source>Generated by GPAC %s</Source>\n", GPAC_FULL_VERSION);

		fprintf(fmpd, " </ProgramInformation>\n");
		fprintf(fmpd, " <Period start=\"PT0S\">\n");	

		count = gf_list_count(pl->programs);
		for (i=0; i<count; i++) {
			u32 j, count2;
			Program *prog = gf_list_get(pl->programs, i);
			count2 = gf_list_count(prog->bitrates);
			for (j = 0; j<count2; j++) {
				PlaylistElement *pe = gf_list_get(prog->bitrates, j);
				fprintf(stdout, "%d, %d, %s, %s, %d\n", pe->durationInfo, pe->bandwidth, pe->title, pe->url, pe->elementType);
				if (pe->elementType == TYPE_PLAYLIST) {
					u32 k, count3;
					char *tmp;
					char c;
					char baseURL[GF_MAX_PATH]; 
					tmp = strrchr(url, '/');
					if (tmp) {
						tmp++;
						c = tmp[0];
						tmp[0] = 0;
						strcpy(baseURL, url);
						tmp[0] = c;
					} else {
						baseURL[0] = 0;
					}
					fprintf(fmpd, "  <Representation mimeType=\"video/mp2t\">\n");	
					fprintf(fmpd, "   <SegmentInfo duration=\"PT%dS\"", pe->durationInfo);	
					if (baseURL[0]) fprintf(fmpd, "baseURL=\"%s\"", baseURL);	
					fprintf(fmpd, ">\n");	
					count3 = gf_list_count(pe->element.playlist.elements);
					update_interval = (count3 - 1) * pe->durationInfo * 1000;
					for (k=0; k<count3; k++) {
						PlaylistElement *elt = gf_list_get(pe->element.playlist.elements, k);
						if (k) fprintf(fmpd, "    <Url sourceURL=\"%s\"/>\n", elt->url);	
						else fprintf(fmpd, "    <InitialisationSegmentURL sourceURL=\"%s\"/>\n", elt->url);	
					}
					fprintf(fmpd, "   </SegmentInfo>\n");
					fprintf(fmpd, "  </Representation>\n");
				} else if (pe->elementType == TYPE_STREAM) {
					fprintf(stdout, "Stream\n");
				}
			}
		}
		fprintf(fmpd, " </Period>\n");
		fprintf(fmpd, "</MPD>");
		fclose(fmpd);
		variant_playlist_del(pl);
		if (is_local) break;
		gf_sleep(update_interval);
	}

	gf_sys_close();
	return 0;
}
Example #12
0
File: main.c Project: ARSekkat/gpac
int main(int argc, char **argv)
{
	/********************/
	/*   declarations   */
	/********************/
	char *input, *output, tmpstr[GF_MAX_PATH];
	GF_ISOFile *isom_file_in;
	GF_MediaImporter import;
	AdobeHDSCtx ctx;
	GF_Err e;
	u32 i;

	/*****************/
	/*   gpac init   */
	/*****************/
	gf_sys_init(GF_MemTrackerNone);
	gf_log_set_tool_level(GF_LOG_ALL, GF_LOG_WARNING);

	/***********************/
	/*   initialisations   */
	/***********************/
	input = NULL;
	output = NULL;
	isom_file_in = NULL;
	memset(&import, 0, sizeof(GF_MediaImporter));
	e = GF_OK;
	memset(&ctx, 0, sizeof(ctx));

	ctx.curr_time = 0;
	ctx.segnum = 1;

	/*********************************************/
	/*   parse arguments and build HDS context   */
	/*********************************************/
	if (GF_OK != parse_args(argc, argv, &input, &output, &ctx.curr_time, &ctx.segnum)) {
		usage(argv[0]);
		goto exit;
	}

	ctx.multirate_manifest = adobe_alloc_multirate_manifest(output);

#if 0 /*'moov' conversion tests*/
	{
		char metamoov64[GF_MAX_PATH];
		u32 metamoov64_len;
		unsigned char metamoov[GF_MAX_PATH];
		u32 metamoov_len=GF_MAX_PATH;
		FILE *f = gf_fopen("metamoov64"/*input*/, "rt");
		gf_fseek(f, 0, SEEK_END);
		metamoov64_len = (u32)gf_ftell(f);
		gf_fseek(f, 0, SEEK_SET);
		fread(metamoov64, metamoov64_len, 1, f);
		metamoov_len = gf_base64_decode(metamoov64, metamoov64_len, metamoov, metamoov_len);
		gf_fclose(f);
		f = gf_fopen("metamoov", "wb");
		fwrite(metamoov, metamoov_len, 1, f);
		gf_fclose(f);
		return 0;
	}
#endif

#if 0 /*'abst'conversion tests*/
	{
		char bootstrap64[GF_MAX_PATH];
		u32 bootstrap64_len;
		unsigned char bootstrap[GF_MAX_PATH];
		u32 bootstrap_len=GF_MAX_PATH;
		GF_AdobeBootstrapInfoBox *abst = (GF_AdobeBootstrapInfoBox *)abst_New();
		GF_BitStream *bs;
#if 1 //64
		FILE *f = gf_fopen("bootstrap64"/*input*/, "rt");
		gf_fseek(f, 0, SEEK_END);
		bootstrap64_len = (u32)gf_ftell(f);
		gf_fseek(f, 0, SEEK_SET);
		fread(bootstrap64, bootstrap64_len, 1, f);
		bootstrap_len = gf_base64_decode(bootstrap64, bootstrap64_len, bootstrap, bootstrap_len);
#else //binary bootstrap
		FILE *f = gf_fopen("bootstrap.bin"/*input*/, "rb");
		gf_fseek(f, 0, SEEK_END);
		bootstrap_len = (u32)gf_ftell(f);
		gf_fseek(f, 0, SEEK_SET);
		fread(bootstrap, bootstrap_len, 1, f);
#endif
		bs = gf_bs_new(bootstrap+8, bootstrap_len-8, GF_BITSTREAM_READ);
		abst->size = bootstrap[2]*256+bootstrap[3];
		assert(abst->size<GF_MAX_PATH);
		abst_Read((GF_Box*)abst, bs);
		gf_bs_del(bs);
		//then rewrite with just one 'afrt'
		memset(bootstrap, 0, bootstrap_len);
		bs = gf_bs_new(bootstrap, bootstrap_len, GF_BITSTREAM_WRITE);
		abst_Write((GF_Box*)abst, bs);
		bootstrap_len = (u32)gf_bs_get_position(bs);
		gf_bs_del(bs);
		gf_fclose(f);
		f = gf_fopen("bootstrap", "wt");
		bootstrap64_len = gf_base64_encode(bootstrap, bootstrap_len, bootstrap64, GF_MAX_PATH);
		fwrite(bootstrap64, bootstrap64_len, 1, f);
		fprintf(f, "\n\n");
		abst_dump((GF_Box*)abst, f);
		gf_fclose(f);
		abst_del((GF_Box*)abst);
		return 0;
	}
#endif

	/*****************/
	/*   main loop   */
	/*****************/
	import.trackID = 0;
	import.in_name = input;
	import.flags = GF_IMPORT_PROBE_ONLY;

	//create output or open when recovering from a saved state
	sprintf(tmpstr, "%s_import.mp4", input);
	isom_file_in = gf_isom_open(tmpstr, GF_ISOM_WRITE_EDIT, NULL);
	if (!isom_file_in) {
		fprintf(stderr, "Error opening output file %s: %s\n", tmpstr, gf_error_to_string(e));
		assert(0);
		goto exit;
	}
	import.dest = isom_file_in;

	//probe input
	e = gf_media_import(&import);
	if (e) {
		fprintf(stderr, "Error while importing input file %s: %s\n", input, gf_error_to_string(e));
		assert(0);
		goto exit;
	}

	//import input data
	import.flags = 0;
	for (i=0; i<import.nb_tracks; i++) {
		import.trackID = import.tk_info[i].track_num;
		e = gf_media_import(&import);
		if (e) {
			fprintf(stderr, "Error while importing track number %u, input file %s: %s\n", import.trackID, input, gf_error_to_string(e));
			assert(0);
			goto exit;
		}
	}

	//Adobe specific stuff
	e = adobize_segment(isom_file_in, &ctx);
	if (e) {
		fprintf(stderr, "Couldn't turn the ISOM fragmented file into an Adobe f4v segment: %s\n", gf_error_to_string(e));
		assert(0);
		goto exit;
	}

	//interleave data and remove imported file
	//FIXME: set multiple fragments:
	sprintf(tmpstr, "%s_HD_100_Seg%u-Frag1", output, ctx.segnum); //FIXME: "HD", "100" and fragnum: pass as arg
	//e = gf_media_fragment_file(isom_file_in, tmpstr, 1.0);
	e = gf_media_fragment_file(isom_file_in, tmpstr, 1.0+gf_isom_get_duration(isom_file_in)/gf_isom_get_timescale(isom_file_in));
	if (e) {
		fprintf(stderr, "Error while fragmenting file to output %s: %s\n", output, gf_error_to_string(e));
		assert(0);
		goto exit;
	}
	gf_isom_delete(isom_file_in);
	isom_file_in = NULL;

	e = adobe_gen_multirate_manifest(ctx.multirate_manifest, ctx.bootstrap, ctx.bootstrap_size);
	if (e) {
		fprintf(stderr, "Couldn't generate Adobe f4m manifest: %s\n", gf_error_to_string(e));
		assert(0);
		goto exit;
	}

exit:
	//delete intermediate mp4 file
	if (isom_file_in)
		gf_isom_delete(isom_file_in);

	if (ctx.multirate_manifest)
		adobe_free_multirate_manifest(ctx.multirate_manifest);

	if (ctx.bootstrap) {
		gf_free(ctx.bootstrap);
		//ctx.bootstrap = NULL;
		//ctx.bootstrap_size = 0;
	}

	gf_sys_close();

	return !e ? 0 : 1;
}
Example #13
0
int main(int argc, char **argv)
{
	/* The ISO progressive reader */
	GF_ISOFile *movie;
	/* Error indicator */
	GF_Err e;
	/* Number of bytes required to finish the current ISO Box reading */
	u64 missing_bytes;
	/* Return value for the program */
	int ret = 0;
	/* Maximum index of the segments*/
	u32 seg_max = argc-2;
	/* Number of the segment being processed*/
	u32 seg_curr = 0;
	u32 track_id = 1;
	u32 sample_index = 1;

	/* Usage */
	if (argc < 2) {
		fprintf(stdout, "Usage: %s filename0 [filename1 filename2 ...]\n", argv[0]);
		return 1;
	}

#if defined(DEBUG) || defined(_DEBUG)
	/* Enables GPAC memory tracking in debug mode only */
	gf_sys_init(GF_TRUE);
	gf_log_set_tool_level(GF_LOG_CONTAINER, GF_LOG_INFO);
	gf_log_set_tool_level(GF_LOG_MEMORY, GF_LOG_INFO);
#endif

	/* First or init segment */
	fprintf(stdout, "Process segment %5d/%5d: %s\n", seg_curr, seg_max, argv[seg_curr+1]);
	e = gf_isom_open_progressive(argv[seg_curr+1], 0, 0, &movie, &missing_bytes);
	if ((e != GF_OK && e != GF_ISOM_INCOMPLETE_FILE) || movie == NULL) {
		fprintf(stdout, "Could not open file %s for reading (%s).\n", argv[seg_curr+1], gf_error_to_string(e));
		return 1;
	}
	process_samples_from_track(movie, track_id, &sample_index);
	seg_curr++;

	/* Process segments */
	while (seg_curr <= seg_max) {
		fprintf(stdout, "Process segment %5d/%5d: %s\n", seg_curr, seg_max, argv[seg_curr+1]);

		/* Open the segment */
		e = gf_isom_open_segment(movie, argv[seg_curr+1], 0, 0, GF_FALSE);
		if (e != GF_OK) {
			fprintf(stdout, "Could not open segment %s for reading (%s).\n", argv[seg_curr+1], gf_error_to_string(e));
			ret = 1;
			goto exit;
		}

		/* Process the segment */
		process_samples_from_track(movie, track_id, &sample_index);

		/* Release the segment */
		gf_isom_release_segment(movie, 1);

		seg_curr++;
	}

exit:
	fprintf(stdout, "Total nb Samples: %d\n", gf_isom_get_sample_count(movie, gf_isom_get_track_by_id(movie, track_id) ) );
	gf_isom_release_segment(movie, 1);
	gf_isom_close(movie);
#if defined(DEBUG) || defined(_DEBUG)
	/* Closes GPAC memory tracking in debug mode only */
	gf_sys_close();
#endif

	return ret;
}
Example #14
0
int main(int argc, char **argv)
{
	/* The ISO progressive reader */
	ISOProgressiveReader reader;
	/* Error indicator */
	GF_Err e;
	/* input file to be read in the data buffer */
	FILE *input;
	/* number of bytes read from the file at each read operation */
	u32 read_bytes;
	/* number of bytes read from the file (total) */
	u64 total_read_bytes;
	/* size of the input file */
	u64 file_size;
	/* number of bytes required to finish the current ISO Box reading (not used here)*/
	u64 missing_bytes;
	/* Thread used to run the ISO parsing in */
	GF_Thread *reading_thread;
	/* Return value for the program */
	int ret = 0;

	/* Usage */
	if (argc != 2) {
		fprintf(stdout, "Usage: %s filename\n", argv[0]);
		return 1;
	}

	/* Initializing GPAC framework */
	/* Enables GPAC memory tracking in debug mode only */
#if defined(DEBUG) || defined(_DEBUG)
	gf_sys_init(GF_MemTrackerSimple);
	gf_log_set_tool_level(GF_LOG_ALL, GF_LOG_WARNING);
	gf_log_set_tool_level(GF_LOG_MEMORY, GF_LOG_INFO);
#else
	gf_sys_init(GF_MemTrackerNone);
	gf_log_set_tool_level(GF_LOG_ALL, GF_LOG_WARNING);
#endif

	/* This is an input file to read data from. Could be replaced by any other method to retrieve the data (e.g. JavaScript, socket, ...)*/
	input = gf_fopen(argv[1], "rb");
	if (!input) {
		fprintf(stdout, "Could not open file %s for reading.\n", argv[1]);
		gf_sys_close();
		return 1;
	}

	gf_fseek(input, 0, SEEK_END);
	file_size = gf_ftell(input);
	gf_fseek(input, 0, SEEK_SET);

	/* Initializing the progressive reader */
	memset(&reader, 0, sizeof(ISOProgressiveReader));
	reading_thread = gf_th_new("ISO reading thread");
	reader.mutex = gf_mx_new("ISO Segment");
	reader.do_run = GF_TRUE;
	/* we want to parse the first track */
	reader.track_id = 1;
	/* start the async parsing */
	gf_th_run(reading_thread, iso_progressive_read_thread, &reader);

	/* start the data reading */
	reader.data_size = BUFFER_BLOCK_SIZE;
	reader.data = (u8 *)gf_malloc(reader.data_size);
	reader.valid_data_size = 0;
	total_read_bytes = 0;
	while (1) {
		/* block the parser until we are done manipulating the data buffer */
		gf_mx_p(reader.mutex);

		if (reader.valid_data_size + BUFFER_BLOCK_SIZE > MAX_BUFFER_SIZE) {
			/* regulate the reader to limit the max buffer size and let some time to the parser to release buffer data */
			fprintf(stdout, "Buffer full (%d/%d)- waiting to read next data \r", reader.valid_data_size, reader.data_size);
			gf_mx_v(reader.mutex);
			//gf_sleep(10);
		} else {
			/* make sure we have enough space in the buffer to read the next bloc of data */
			if (reader.valid_data_size + BUFFER_BLOCK_SIZE > reader.data_size) {
				reader.data = (u8 *)gf_realloc(reader.data, reader.data_size + BUFFER_BLOCK_SIZE);
				reader.data_size += BUFFER_BLOCK_SIZE;
			}

			/* read the next bloc of data and update the data buffer url */
			read_bytes = fread(reader.data+reader.valid_data_size, 1, BUFFER_BLOCK_SIZE, input);
			total_read_bytes += read_bytes;
			fprintf(stdout, "Read "LLD" bytes of "LLD" bytes from input file %s (buffer status: %5d/%5d)\r", total_read_bytes, file_size, argv[1], reader.valid_data_size, reader.data_size);
			if (read_bytes) {
				reader.valid_data_size += read_bytes;
				sprintf(reader.data_url, "gmem://%d@%p", reader.valid_data_size, reader.data);
			} else {
				/* end of file we can quit */
				gf_mx_v(reader.mutex);
				break;
			}

			/* if the file is not yet opened (no movie), open it in progressive mode (to update its data later on) */
			if (!reader.movie) {
				/* let's initialize the parser */
				e = gf_isom_open_progressive(reader.data_url, 0, 0, &reader.movie, &missing_bytes);
				if (reader.movie) {
					gf_isom_set_single_moof_mode(reader.movie, GF_TRUE);
				}
				/* we can let parser try to work now */
				gf_mx_v(reader.mutex);

				if ((e == GF_OK || e == GF_ISOM_INCOMPLETE_FILE) && reader.movie) {
					/* nothing to do, this is normal */
				} else {
					fprintf(stdout, "Error opening fragmented mp4 in progressive mode: %s (missing "LLD" bytes)\n", gf_error_to_string(e), missing_bytes);
					ret = 1;
					goto exit;
				}
			} else {
				/* let inform the parser that the buffer has been updated with new data */
				e = gf_isom_refresh_fragmented(reader.movie, &missing_bytes, reader.data_url);

				/* we can let parser try to work now */
				gf_mx_v(reader.mutex);

				if (e != GF_OK && e != GF_ISOM_INCOMPLETE_FILE) {
					fprintf(stdout, "Error refreshing fragmented mp4: %s (missing "LLD" bytes)\n", gf_error_to_string(e), missing_bytes);
					ret = 1;
					goto exit;
				}
			}

			//gf_sleep(1);
		}
	}

exit:
	/* stop the parser */
	reader.do_run = GF_FALSE;
	gf_th_stop(reading_thread);

	/* clean structures */
	gf_th_del(reading_thread);
	gf_mx_del(reader.mutex);
	gf_free(reader.data);
	gf_isom_close(reader.movie);
	gf_fclose(input);
	gf_sys_close();

	return ret;
}