static void gst_player_start_stop_end(App* app) { gint index; g_print ("Stopping\n"); app->exiting = TRUE; for(index = 0; index < app->thread_count; ++index) { if (app->threads[index] && app->threads[index]->joinable) { g_thread_join(app->threads[index]); } } for(index = 0; index < app->process_count; ++index) { if (app->processes[index]) { g_print("Terminating process %d\n", app->processes[index]); KILL_PROCESS(app->processes[index]); g_spawn_close_pid(app->processes[index]); } } }
void ZapUp() { KILL_PROCESS(&Channels[SelectedChannel].StreamerProcess); SelectedChannel--; if(SelectedChannel < 0) SelectedChannel = NChannels-1; SwitchChannel(&(Channels[SelectedChannel])); }
void ZapDown() { KILL_PROCESS(&Channels[SelectedChannel].StreamerProcess); SelectedChannel = ((SelectedChannel+1) %NChannels); SwitchChannel(&(Channels[SelectedChannel])); }
int main(int argc, char *argv[]) { srand ( time(NULL) ); #ifdef __linux__ XInitThreads(); #endif // some initializations SilentMode = 0; queue_filling_threshold = 5; quit = 0; QueueFillingMode=1; LogTraces = 0; qoe_led = 1; scale_with_sdl = SCALE_WITH_SDL_DEFAULT; NChannels = 0; SelectedChannel = -1; char firstChannelName[255]; int firstChannelIndex; firstChannelName[0] = 0; memset((void*)Channels, 0, (MAX_CHANNELS_NUM*sizeof(SChannel))); Port = 6100; SDL_Event event; OverlayMutex = SDL_CreateMutex(); char c; while ((c = getopt (argc, argv, "q:c:C:p:s:t")) != -1) { switch (c) { case 0: //for long options break; case 'q': sscanf(optarg, "%d", &queue_filling_threshold); break; case 'c': sprintf(firstChannelName, "%s", optarg); break; case 'C': ConfFilename = strdup(optarg); break; case 'p': sscanf(optarg, "%d", &Port); break; case 's': sscanf(optarg, "%d", &SilentMode); break; case 't': DELETE_DIR("traces"); CREATE_DIR("traces"); LogTraces = 1; break; default: print_usage(argc, argv); return -1; } } #ifdef EMULATE_CHUNK_LOSS ScheduledChunkLosses = NULL; cfg_opt_t scheduled_chunk_loss_opts[] = { CFG_INT("Time", 0, CFGF_NONE), CFG_INT("Value", 0, CFGF_NONE), CFG_INT("MinValue", 0, CFGF_NONE), CFG_INT("MaxValue", 0, CFGF_NONE), CFG_INT("Burstiness", 0, CFGF_NONE), CFG_END() }; cfg_opt_t opts[] = { CFG_SEC("ScheduledChunkLoss", scheduled_chunk_loss_opts, CFGF_MULTI), CFG_END() }; cfg_t *cfg, *cfg_sched; cfg = cfg_init(opts, CFGF_NONE); if(!cfg_parse(cfg, "_chunklossrate.conf") == CFG_PARSE_ERROR) { NScheduledChunkLosses = cfg_size(cfg, "ScheduledChunkLoss"); if(NScheduledChunkLosses > 0) ScheduledChunkLosses = (SChunkLoss*)malloc((NScheduledChunkLosses)*sizeof(SChunkLoss)); int j; for(j = 0; j < cfg_size(cfg, "ScheduledChunkLoss"); j++) { cfg_sched = cfg_getnsec(cfg, "ScheduledChunkLoss", j); ScheduledChunkLosses[j].Time = cfg_getint(cfg_sched, "Time"); ScheduledChunkLosses[j].Value = cfg_getint(cfg_sched, "Value"); ScheduledChunkLosses[j].Burstiness = cfg_getint(cfg_sched, "Burstiness"); // -1 means random value between min and max if(ScheduledChunkLosses[j].Value == -1) { ScheduledChunkLosses[j].MinValue = cfg_getint(cfg_sched, "MinValue"); ScheduledChunkLosses[j].MaxValue = cfg_getint(cfg_sched, "MaxValue"); } } cfg_free(cfg); CurrChunkLossIndex = -1; for(j=0; j < NScheduledChunkLosses; j++) { printf("ScheduledChunkLosses[%d].Time = %ld\n", j, ScheduledChunkLosses[j].Time); printf("ScheduledChunkLosses[%d].Value = %d\n", j, ScheduledChunkLosses[j].Value); printf("ScheduledChunkLosses[%d].Burstiness = %d\n", j, ScheduledChunkLosses[j].Burstiness); } } #endif if (initIPCReceiver(Port) < 0) { exit(2); } #ifdef PSNR_PUBLICATION repoclient=NULL; LastTimeRepoPublish.tv_sec=0; LastTimeRepoPublish.tv_usec=0; eventbase = event_base_new(); napaInitLog(LOG_DEBUG, NULL, NULL); repInit(""); #endif if(SilentMode == 0) { if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) { fprintf(stderr, "Could not initialize SDL audio/video or timer - %s\n", SDL_GetError()); return -1; } } else if(SilentMode == 1) { if(SDL_Init(SDL_INIT_AUDIO | SDL_INIT_TIMER)) { fprintf(stderr, "Could not initialize SDL audio or timer - %s\n", SDL_GetError()); return -1; } } else { if(SDL_Init(SDL_INIT_TIMER)) { fprintf(stderr, "Could not initialize SDL timer - %s\n", SDL_GetError()); return -1; } } if (ConfFilename) { if(ParseConf(ConfFilename, NULL)) { printf("ERROR: Cannot parse configuration file %s, exit...\n", ConfFilename); exit(1); } } else { if(ParseConf(DEFAULT_CONF_FILENAME, DEFAULT_CONF_URI)) { printf("ERROR: Cannot parse configuration file, exit...\n"); exit(1); } } firstChannelIndex = -1; int it; for(it = 0; it < NChannels; it++) { if(firstChannelName[0] == 0) { firstChannelIndex = 0; break; } else if (!strcmp(Channels[it].Title, firstChannelName)) { firstChannelIndex = it; break; } } if(firstChannelIndex < 0) { printf("Cannot find the specified channel (%s) in the configuration file (channels.conf), exiting\n", firstChannelName); exit(0); } if(ChunkerPlayerGUI_Init()) { printf("ERROR: Cannot init player gui, exit...\n"); exit(1); } SelectedChannel = firstChannelIndex; SwitchChannel(&(Channels[SelectedChannel])); // Wait for user input while(!quit) { if(QueueFillingMode) { if(ChunkerPlayerCore_AudioEnded()) ChunkerPlayerCore_ResetAVQueues(); #ifdef DEBUG_QUEUE //printf("QUEUE: MAIN audio:%d video:%d audiolastframe:%d videolastframe:%d\n", audioq.nb_packets, videoq.nb_packets, audioq.last_frame_extracted, videoq.last_frame_extracted); #endif } #ifdef PSNR_PUBLICATION event_base_loop(eventbase, EVLOOP_NONBLOCK); #endif //listen for key and mouse while(SDL_PollEvent(&event)) { switch(event.type) { case SDL_QUIT: quit=1; break; case SDL_VIDEORESIZE: if(SilentMode) break; // printf("\tSDL_VIDEORESIZE event received!! \n"); if(!FullscreenMode) ChunkerPlayerGUI_HandleResize(event.resize.w, event.resize.h); else ChunkerPlayerGUI_HandleResize(FullscreenWidth, FullscreenHeight); break; case SDL_ACTIVEEVENT: if(SilentMode) break; // if the window was iconified or restored if(event.active.state & SDL_APPACTIVE) { //If the application is being reactivated if( event.active.gain != 0 ) { ChunkerPlayerGUI_HandleGetFocus(); } } //If something happened to the keyboard focus else if( event.active.state & SDL_APPINPUTFOCUS ) { //If the application gained keyboard focus if( event.active.gain != 0 ) { ChunkerPlayerGUI_HandleGetFocus(); } } //If something happened to the mouse focus else if( event.active.state & SDL_APPMOUSEFOCUS ) { //If the application gained mouse focus if( event.active.gain != 0 ) { ChunkerPlayerGUI_HandleGetFocus(); } } break; case SDL_MOUSEMOTION: if(SilentMode) break; ChunkerPlayerGUI_HandleMouseMotion(event.motion.x, event.motion.y); break; case SDL_MOUSEBUTTONUP: if(SilentMode) break; if( event.button.button != SDL_BUTTON_LEFT ) break; ChunkerPlayerGUI_HandleLButton(event.motion.x, event.motion.y); break; case SDL_KEYDOWN: /* Handle a KEYDOWN event */ switch( event.key.keysym.sym ){ case SDLK_ESCAPE: if(FullscreenMode) { ChunkerPlayerGUI_ToggleFullscreen(); } break; case SDLK_r: ChunkerPlayerGUI_ChangeRatio(); break; case SDLK_q: qoe_led = !qoe_led; break; case SDLK_x: scale_with_sdl = !scale_with_sdl; break; case SDLK_f: ChunkerPlayerGUI_ToggleFullscreen(); break; case SDLK_UP: ZapUp(); break; case SDLK_DOWN: ZapDown(); break; case SDLK_LEFT: ChunkerPlayerCore_ChangeDelay(100); break; case SDLK_RIGHT: ChunkerPlayerCore_ChangeDelay(-100); break; default: break; } break; } ChunkerPlayerGUI_HandleKey(); } usleep(120000); } KILL_PROCESS(&(Channels[SelectedChannel].StreamerProcess)); //TERMINATE ChunkerPlayerCore_Stop(); ChunkerPlayerCore_Finalize(); ChunkerPlayerGUI_Close(); SDL_DestroyMutex(OverlayMutex); SDL_Quit(); #ifdef HTTPIO finalizeChunkPuller(daemon); #endif #ifdef TCPIO finalizeChunkPuller(); #endif #ifdef EMULATE_CHUNK_LOSS if(ScheduledChunkLosses) free(ScheduledChunkLosses); #endif #ifdef PSNR_PUBLICATION if(repoclient) repClose(repoclient); event_base_free(eventbase); #endif return 0; }