void STDCALL TerminateXT() { if(bBaseLoaded) { FreeProfileData(); delete locale; locale = NULL; if(MainAllocator) { Alloc *curAlloc = MainAllocator; MainAllocator = new DefaultAlloc; delete curAlloc; delete MainAllocator; MainAllocator = NULL; } bBaseLoaded = 0; if(LogFile.IsOpen()) LogFile.Close(); OSExit(); } }
void OBS::Stop() { if(!bRunning) return; OSEnterMutex(hStartupShutdownMutex); //we only want the capture thread to stop first, so we can ensure all packets are flushed bShutdownEncodeThread = true; ShowWindow(hwndProjector, SW_HIDE); if(hEncodeThread) { OSTerminateThread(hEncodeThread, 30000); hEncodeThread = NULL; } bShutdownVideoThread = true; SetEvent(hVideoEvent); if(hVideoThread) { OSTerminateThread(hVideoThread, 30000); hVideoThread = NULL; } bRunning = false; ReportStopStreamTrigger(); for(UINT i=0; i<globalSources.Num(); i++) globalSources[i].source->EndScene(); if(scene) scene->EndScene(); //------------------------------------------------------------- if(hSoundThread) { //ReleaseSemaphore(hRequestAudioEvent, 1, NULL); OSTerminateThread(hSoundThread, 20000); } //if(hRequestAudioEvent) // CloseHandle(hRequestAudioEvent); if(hSoundDataMutex) OSCloseMutex(hSoundDataMutex); hSoundThread = NULL; //hRequestAudioEvent = NULL; hSoundDataMutex = NULL; //------------------------------------------------------------- StopBlankSoundPlayback(); //------------------------------------------------------------- delete network; network = NULL; delete fileStream; fileStream = NULL; delete micAudio; micAudio = NULL; delete desktopAudio; desktopAudio = NULL; delete audioEncoder; audioEncoder = NULL; delete videoEncoder; videoEncoder = NULL; //------------------------------------------------------------- for(UINT i=0; i<pendingAudioFrames.Num(); i++) pendingAudioFrames[i].audioData.Clear(); pendingAudioFrames.Clear(); //------------------------------------------------------------- if(GS) GS->UnloadAllData(); //------------------------------------------------------------- delete scene; scene = NULL; for(UINT i=0; i<globalSources.Num(); i++) globalSources[i].FreeData(); globalSources.Clear(); //------------------------------------------------------------- for(UINT i=0; i<auxAudioSources.Num(); i++) delete auxAudioSources[i]; auxAudioSources.Clear(); //------------------------------------------------------------- for(UINT i=0; i<NUM_RENDER_BUFFERS; i++) { delete mainRenderTextures[i]; delete yuvRenderTextures[i]; mainRenderTextures[i] = NULL; yuvRenderTextures[i] = NULL; } for(UINT i=0; i<NUM_RENDER_BUFFERS; i++) { SafeRelease(copyTextures[i]); } delete transitionTexture; transitionTexture = NULL; //------------------------------------------------------------- delete mainVertexShader; delete mainPixelShader; delete yuvScalePixelShader; delete solidVertexShader; delete solidPixelShader; mainVertexShader = NULL; mainPixelShader = NULL; yuvScalePixelShader = NULL; solidVertexShader = NULL; solidPixelShader = NULL; //------------------------------------------------------------- delete GS; GS = NULL; //------------------------------------------------------------- ResizeRenderFrame(false); RedrawWindow(hwndRenderFrame, NULL, NULL, RDW_INVALIDATE|RDW_UPDATENOW); //------------------------------------------------------------- AudioDeviceList audioDevices; GetAudioDevices(audioDevices, ADT_RECORDING); String strDevice = AppConfig->GetString(TEXT("Audio"), TEXT("Device"), NULL); if(strDevice.IsEmpty() || !audioDevices.HasID(strDevice)) { AppConfig->SetString(TEXT("Audio"), TEXT("Device"), TEXT("Disable")); strDevice = TEXT("Disable"); } audioDevices.FreeData(); EnableWindow(GetDlgItem(hwndMain, ID_MICVOLUME), !strDevice.CompareI(TEXT("Disable"))); //------------------------------------------------------------- ClearStreamInfo(); DumpProfileData(); FreeProfileData(); Log(TEXT("=====Stream End: %s================================================="), CurrentDateTimeString().Array()); //update notification icon to reflect current status UpdateNotificationAreaIcon(); SetWindowText(GetDlgItem(hwndMain, ID_TESTSTREAM), Str("MainWindow.TestStream")); EnableWindow(GetDlgItem(hwndMain, ID_STARTSTOP), TRUE); SetWindowText(GetDlgItem(hwndMain, ID_STARTSTOP), Str("MainWindow.StartStream")); EnableWindow(GetDlgItem(hwndMain, ID_TESTSTREAM), TRUE); bEditMode = false; SendMessage(GetDlgItem(hwndMain, ID_SCENEEDITOR), BM_SETCHECK, BST_UNCHECKED, 0); EnableWindow(GetDlgItem(hwndMain, ID_SCENEEDITOR), FALSE); ClearStatusBar(); InvalidateRect(hwndRenderFrame, NULL, TRUE); SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 1, 0, 0); SetThreadExecutionState(ES_CONTINUOUS); String processPriority = AppConfig->GetString(TEXT("General"), TEXT("Priority"), TEXT("Normal")); if (scmp(processPriority, TEXT("Normal"))) SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS); bTestStream = false; UpdateRenderViewMessage(); OSLeaveMutex(hStartupShutdownMutex); }
void OBS::Stop(bool overrideKeepRecording) { if((!bStreaming && !bRecording && !bRunning) && (!bTestStream)) return; //ugly hack to prevent hotkeys from being processed while we're stopping otherwise we end up //with callbacks from the ProcessEvents call in DelayedPublisher which causes havoc. OSEnterMutex(hHotkeyMutex); int networkMode = AppConfig->GetInt(TEXT("Publish"), TEXT("Mode"), 2); if(!overrideKeepRecording && bRecording && bKeepRecording && networkMode == 0) { NetworkStream *tempStream = NULL; videoEncoder->RequestKeyframe(); tempStream = network; network = NULL; Log(TEXT("=====Stream End (recording continues): %s========================="), CurrentDateTimeString().Array()); delete tempStream; bStreaming = false; bSentHeaders = false; ReportStopStreamingTrigger(); ConfigureStreamButtons(); OSLeaveMutex(hHotkeyMutex); return; } OSEnterMutex(hStartupShutdownMutex); //we only want the capture thread to stop first, so we can ensure all packets are flushed bShutdownEncodeThread = true; ShowWindow(hwndProjector, SW_HIDE); if(hEncodeThread) { OSTerminateThread(hEncodeThread, 30000); hEncodeThread = NULL; } bShutdownVideoThread = true; SetEvent(hVideoEvent); if(hVideoThread) { OSTerminateThread(hVideoThread, 30000); hVideoThread = NULL; } bRunning = false; ReportStopStreamTrigger(); for(UINT i=0; i<globalSources.Num(); i++) globalSources[i].source->EndScene(); if(scene) scene->EndScene(); //------------------------------------------------------------- if(hSoundThread) { //ReleaseSemaphore(hRequestAudioEvent, 1, NULL); OSTerminateThread(hSoundThread, 20000); } //if(hRequestAudioEvent) // CloseHandle(hRequestAudioEvent); if(hSoundDataMutex) OSCloseMutex(hSoundDataMutex); hSoundThread = NULL; //hRequestAudioEvent = NULL; hSoundDataMutex = NULL; //------------------------------------------------------------- StopBlankSoundPlayback(); //------------------------------------------------------------- delete network; network = NULL; if (bStreaming) ReportStopStreamingTrigger(); bStreaming = false; if(bRecording) StopRecording(); delete micAudio; micAudio = NULL; delete desktopAudio; desktopAudio = NULL; delete audioEncoder; audioEncoder = NULL; delete videoEncoder; videoEncoder = NULL; //------------------------------------------------------------- for(UINT i=0; i<pendingAudioFrames.Num(); i++) pendingAudioFrames[i].audioData.Clear(); pendingAudioFrames.Clear(); //------------------------------------------------------------- if(GS) GS->UnloadAllData(); //------------------------------------------------------------- delete scene; scene = NULL; for(UINT i=0; i<globalSources.Num(); i++) globalSources[i].FreeData(); globalSources.Clear(); //------------------------------------------------------------- for(UINT i=0; i<auxAudioSources.Num(); i++) delete auxAudioSources[i]; auxAudioSources.Clear(); //------------------------------------------------------------- for(UINT i=0; i<NUM_RENDER_BUFFERS; i++) { delete mainRenderTextures[i]; delete yuvRenderTextures[i]; mainRenderTextures[i] = NULL; yuvRenderTextures[i] = NULL; } for(UINT i=0; i<NUM_RENDER_BUFFERS; i++) { SafeRelease(copyTextures[i]); } delete transitionTexture; transitionTexture = NULL; //------------------------------------------------------------- delete mainVertexShader; delete mainPixelShader; delete yuvScalePixelShader; delete solidVertexShader; delete solidPixelShader; mainVertexShader = NULL; mainPixelShader = NULL; yuvScalePixelShader = NULL; solidVertexShader = NULL; solidPixelShader = NULL; //------------------------------------------------------------- delete GS; GS = NULL; //------------------------------------------------------------- ResizeRenderFrame(false); RedrawWindow(hwndRenderFrame, NULL, NULL, RDW_INVALIDATE|RDW_UPDATENOW); //------------------------------------------------------------- AudioDeviceList audioDevices; GetAudioDevices(audioDevices, ADT_RECORDING, false, true); String strDevice = AppConfig->GetString(TEXT("Audio"), TEXT("Device"), NULL); if(strDevice.IsEmpty() || !audioDevices.HasID(strDevice)) { AppConfig->SetString(TEXT("Audio"), TEXT("Device"), TEXT("Disable")); strDevice = TEXT("Disable"); } audioDevices.FreeData(); EnableWindow(GetDlgItem(hwndMain, ID_MICVOLUME), !strDevice.CompareI(TEXT("Disable"))); //------------------------------------------------------------- ClearStreamInfo(); DumpProfileData(); FreeProfileData(); Log(TEXT("=====Stream End: %s================================================="), CurrentDateTimeString().Array()); //update notification icon to reflect current status UpdateNotificationAreaIcon(); bEditMode = false; SendMessage(GetDlgItem(hwndMain, ID_SCENEEDITOR), BM_SETCHECK, BST_UNCHECKED, 0); EnableWindow(GetDlgItem(hwndMain, ID_SCENEEDITOR), FALSE); ClearStatusBar(); InvalidateRect(hwndRenderFrame, NULL, TRUE); SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 1, 0, 0); SetThreadExecutionState(ES_CONTINUOUS); String processPriority = AppConfig->GetString(TEXT("General"), TEXT("Priority"), TEXT("Normal")); if (scmp(processPriority, TEXT("Normal"))) SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS); bTestStream = false; ConfigureStreamButtons(); UpdateRenderViewMessage(); DisableMenusWhileStreaming(false); OSLeaveMutex(hStartupShutdownMutex); OSLeaveMutex(hHotkeyMutex); }