📄 main.c
字号:
RTP_Stream *rtp = session->stream; while (rtp) { if (rtp->port==first_port) { return check_next_port(streamer, (u16) (first_port+2) ); } rtp = rtp->next; } session = session->next; } return first_port;}/* * configuration: * retrieves the parameters from the configuration file * */GF_Err configuration(Streamer *streamer, char *cfg_file, char *src_file, char *ip_dest, u16 port, Bool loop, Bool force_mpeg4){ GF_Err e; RTP_Session *session, *last_sess; u32 nb_sessions; const char *opt; const char *dest_ip; GF_Config *configFile; u32 i, j; if (cfg_file) { fprintf(stdout, "Configuration file: %s \n", cfg_file); configFile = gf_cfg_new(PATHFILE, cfg_file); if (!configFile) { fprintf(stderr, "ERROR: could not open the file\n"); return GF_IO_ERR; } opt = gf_cfg_get_key(configFile, "GLOBAL", "nbSession"); nb_sessions = opt ? atoi(opt) : 0; fprintf(stdout, " Number of sessions: %u \n", nb_sessions); opt = gf_cfg_get_key(configFile, "GLOBAL", "IP_dest"); dest_ip = opt ? opt : "127.0.0.1"; fprintf(stdout, " Destination IP: %s \n", dest_ip); opt = gf_cfg_get_key(configFile, "GLOBAL", "path_mtu"); if (opt) streamer->path_mtu = atoi(opt); if (!streamer->path_mtu) streamer->path_mtu = 1450; fprintf(stdout, " Path MTU: %u bytes \n", streamer->path_mtu); /*configure burst mode*/ if (streamer->burst_mode) { opt = gf_cfg_get_key(configFile, "GLOBAL", "off_duration"); streamer->offDuration = opt ? atoi(opt) : 0; fprintf(stdout, " Offtime duration: %u ms \n", streamer->offDuration); opt = gf_cfg_get_key(configFile, "GLOBAL", "burst_duration"); streamer->burstDuration = opt ? atoi(opt) : 1000; fprintf(stdout, " Burst duration: %u ms \n", streamer->burstDuration); opt = gf_cfg_get_key(configFile, "GLOBAL", "burst_bitrate"); streamer->burstBitRate = opt ? atoi(opt) : 500; fprintf(stdout, " Burst bit rate: %u kbps \n", streamer->burstBitRate); streamer->burstSize = streamer->burstBitRate*1024*streamer->burstDuration/1000/8; streamer->averageBitRate = (streamer->burstDuration * streamer->burstBitRate)/(streamer->offDuration + streamer->burstDuration); fprintf(stdout, " Burst mode enabled - burst size: %d bytes - average bit rate %d kbps\n", streamer->burstSize, streamer->averageBitRate); } } else { fprintf(stdout, " Path MTU: %u bytes \n", streamer->path_mtu); dest_ip = ip_dest; fprintf(stdout, " Destination IP: %s Port %d\n", dest_ip, port); nb_sessions = 1; } streamer->payt = BASE_PAYT; last_sess = NULL; for(i=0; i<nb_sessions; i++) { GF_ISOFile *file; RTP_Stream *rtp, *prev_stream; u16 first_port; u32 nb_tracks; u32 sess_data_size; u16 sess_path_mtu; char *sess_dest_ip; char sessionName[1024]; if (cfg_file) { sprintf(sessionName, "SESSION%d",i+1); opt = gf_cfg_get_key(configFile, sessionName, "file"); /*session doesn't exist*/ if (!opt) { fprintf(stderr, "No configuration info for session %d - skipping\n", i+1); continue; } file = gf_isom_open(opt, GF_ISOM_OPEN_READ, NULL); if (!file) { fprintf(stderr, "Error opening file %s of session %u: %s - skipping\n", opt, i+1, gf_error_to_string(gf_isom_last_error(NULL))); continue; } } else { file = gf_isom_open(src_file, GF_ISOM_OPEN_READ, NULL); if (!file) { fprintf(stderr, "Error opening file %s of session %u: %s - skipping\n", opt, i+1, gf_error_to_string(gf_isom_last_error(NULL))); return GF_IO_ERR; } } GF_SAFEALLOC(session, RTP_Session); if (last_sess) { last_sess->next = session; } else { streamer->session = session; } last_sess = session; session->streamer = streamer; session->id = i+1; session->mp4File = file; if (cfg_file) { opt = gf_cfg_get_key(configFile, sessionName, "port"); first_port = opt ? atoi(opt) : 7000+4*i; opt = gf_cfg_get_key(configFile, sessionName, "looping"); session->looping = opt ? atoi(opt) : 1; opt = gf_cfg_get_key(configFile, sessionName, "force_mpeg4-generic"); session->force_mpeg4_generic = opt ? atoi(opt) : 0; opt = gf_cfg_get_key(configFile, sessionName, "path_mtu"); sess_path_mtu = opt ? atoi(opt) : 0; if (!opt) sess_path_mtu = streamer->path_mtu; opt = gf_cfg_get_key(configFile, sessionName, "IP_dest"); sess_dest_ip = (char *) (opt ? opt : dest_ip); } else { sess_path_mtu = streamer->path_mtu; sess_dest_ip = (char *) dest_ip; session->looping = loop; session->force_mpeg4_generic = force_mpeg4; first_port = port; } sess_data_size = 0; prev_stream = NULL; nb_tracks = gf_isom_get_track_count(session->mp4File); for (j=0;j<nb_tracks;j++) { u32 mediaTimescale; u32 mediaSize; u32 mediaDuration; switch (gf_isom_get_media_type(session->mp4File, j+1)) { case GF_ISOM_MEDIA_VISUAL: case GF_ISOM_MEDIA_AUDIO: case GF_ISOM_MEDIA_TEXT: case GF_ISOM_MEDIA_OD: case GF_ISOM_MEDIA_SCENE: break; default: continue; } GF_SAFEALLOC(rtp, RTP_Stream); if (prev_stream) prev_stream->next = rtp; else session->stream = rtp; prev_stream = rtp; rtp->session = session; rtp->track = j+1; rtp->nb_aus = gf_isom_get_sample_count(session->mp4File, rtp->track); mediaTimescale = gf_isom_get_media_timescale(session->mp4File, rtp->track); mediaDuration = (u32)(gf_isom_get_media_duration(session->mp4File, rtp->track)*1000/mediaTimescale); // ms mediaSize = (u32)gf_isom_get_media_data_size(session->mp4File, rtp->track); sess_data_size += mediaSize; if (mediaDuration > session->duration) session->duration = mediaDuration; rtp->port = check_next_port(streamer, first_port); first_port = rtp->port+2; e = rtp_init_channel(rtp, sess_path_mtu+12, sess_dest_ip, rtp->port); if (e) { fprintf(stderr, "Could not initialize RTP Channel: %s\n", gf_error_to_string(e)); goto exit; } e = rtp_init_packetizer(rtp, sess_dest_ip); if (e) { fprintf(stderr, "Could not initialize Packetizer: %s\n", gf_error_to_string(e)); goto exit; } } rtp_setup_sdp(session, sess_dest_ip); if (streamer->burst_mode) { session->minBurstSize = (sess_data_size * (streamer->burstDuration + streamer->offDuration)) / session->duration; // bps * ms ==> bits fprintf(stdout, "Session %u: %d ms - avg bitrate %d kbps - Min Burst Size %d bytes\n", session->id, session->duration, sess_data_size/session->duration, session->minBurstSize); } } /*configure burst*/ if (streamer->burst_mode) { streamer->cycleDuration = 0; session = streamer->session; while (session) { session->nextBurstTime = streamer->cycleDuration; streamer->cycleDuration += streamer->burstDuration; session = session->next; } streamer->cycleDuration += streamer->offDuration; } fprintf(stdout, "\n");exit: if (cfg_file) gf_cfg_del(configFile); return e;} /* configuration */// ---------------------------------------------------------------------------------------------------void usage() { fprintf(stdout, "Usage: MP4Streamer [options] file\n" "with options being one fo the following:\n" "-cfg: file is a configuration file for all sessions\n" "\n" "Options used for simple streaming:\n" "-port=NUM: port to use. Default is 7000\n" "-mtu=NUM: network path MTU to use. Default is 1450\n" "-dst=ADD: destination IP address. Default is 127.0.0.1\n" "-mpeg4: forces usage of mpeg4-generic payload format. Default is off\n" "-noloop: disables session looping. Default is off\n" );}Bool check_exit(){ if (gf_prompt_has_input()) { char c; c = (char) gf_prompt_get_char(); if (c=='q') return 1; } return 0;}int main(int argc, char **argv){ Streamer streamer; /* Streamer metadata (from cfg file) */ char *cfg = NULL; RTP_Session *session; u32 i; s32 sleepDuration; u32 time; char *ip_dest = "127.0.0.1"; u16 port = 7000; Bool loop = 1; Bool force_mpeg4 = 0; char *file_name = NULL; if (argc < 2) { usage(argv[0]); return 0; } gf_log_set_tools(0xFFFFFFFF); gf_log_set_level(GF_LOG_ERROR); memset(&streamer, 0, sizeof(Streamer)); streamer.log_level = LOG_BURST; streamer.path_mtu = 1450; for (i=1; i<(u32) argc; i++) { char *arg = argv[i]; if (arg[0]=='-') { if (!stricmp(arg, "-q") || !stricmp(arg, "--quiet")) streamer.log_level = LOG_NONE; else if (!strnicmp(arg, "-v=", 3)) { if (!stricmp(arg+3, "au")) streamer.log_level = LOG_AU; else if (!stricmp(arg+3, "rtp")) streamer.log_level = LOG_PACKET; } else if (!strnicmp(arg, "-cfg=", 5)) cfg = arg+5; else if (!strnicmp(arg, "-port=", 6)) port = atoi(arg+6); else if (!strnicmp(arg, "-mtu=", 5)) streamer.path_mtu = atoi(arg+5); else if (!strnicmp(arg, "-dst=", 5)) ip_dest = arg+5; else if (!stricmp(arg, "-noloop")) loop = 0; else if (!stricmp(arg, "-mpeg4")) force_mpeg4 = 1; } else { file_name = arg; } } if (!cfg && !file_name) { usage(argv[0]); return 0; } fprintf(stdout, "Time-sliced MP4 Streamer - (c) ENST 2006-200X\n"); fprintf(stdout, "Developed within the Multimedia group\n"); fprintf(stdout, "with the help of the following students: \n"); fprintf(stdout, " MIX 2006: Anh-Vu BUI and Xiangfeng LIU \n"); fprintf(stdout, "\n"); if (!cfg) fprintf(stdout, "Configuring streaming of file %s to %s:%d - loop %s\n", file_name, ip_dest, port, loop?"enabled":"disabled"); /* * Initialization * */ gf_sys_init(); if (configuration(&streamer, cfg, file_name, ip_dest, port, loop, force_mpeg4) != GF_OK) { goto err_exit; } if (streamer.burst_mode) { session = streamer.session; while (1) { burst_process_session(session); session->dataLengthInBurst = 0; session->nextBurstTime += streamer.cycleDuration; session = session->next; if (!session) session = streamer.session; time = gf_sys_clock(); sleepDuration = session->nextBurstTime - (time - session->timelineOrigin); if (sleepDuration > 0) { gf_sleep(sleepDuration); } if (check_exit()) break; } } else { while (1) { process_sessions(&streamer); if (check_exit()) break; } } err_exit: /* * Desallocation * */ session = streamer.session; while (session) { RTP_Session *_s = session; RTP_Stream *rtp = session->stream; while (rtp) { RTP_Stream *tmp = rtp; rtp_flush_channel(rtp); if (rtp->au) gf_isom_sample_del(&rtp->au); if (rtp->channel) gf_rtp_del(rtp->channel); if (rtp->packetizer) gf_rtp_builder_del(rtp->packetizer); if (rtp->packet.payload) free(rtp->packet.payload); rtp = rtp->next; free(tmp); } if (session->mp4File) gf_isom_close(session->mp4File); session = session->next; free(_s); } gf_sys_close(); fprintf(stdout, "done\n"); return GF_OK;} /* end main */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -