From 25c1a1130cf920c2fdfd98d0fc2b7b2e629ab529 Mon Sep 17 00:00:00 2001 From: palana Date: Tue, 16 Sep 2014 17:21:22 +0200 Subject: [PATCH] Add ClosableStream support to ReplayBuffer --- Source/OBS.cpp | 3 +-- Source/OBS.h | 5 +++-- Source/OBSCapture.cpp | 31 ++++++++++++++++++++++--------- Source/OBSVideoCapture.cpp | 5 ++++- Source/ReplayBuffer.cpp | 8 +++++--- 5 files changed, 35 insertions(+), 17 deletions(-) diff --git a/Source/OBS.cpp b/Source/OBS.cpp index 7da09e7be..6bfbfbc9c 100644 --- a/Source/OBS.cpp +++ b/Source/OBS.cpp @@ -816,8 +816,7 @@ OBS::OBS() OBS::~OBS() { - Stop(true); - StopReplayBuffer(); + Stop(true, true); bShuttingDown = true; diff --git a/Source/OBS.h b/Source/OBS.h index 2267d609d..6b6080919 100644 --- a/Source/OBS.h +++ b/Source/OBS.h @@ -850,6 +850,7 @@ class OBS std::unique_ptr replayBufferStream; ReplayBuffer *replayBuffer; + StopInfo replayBufferStop; bool bRequestKeyframe; int keyframeWait; @@ -1017,11 +1018,11 @@ class OBS void ResetItemCrops(); void Start(bool recordingOnly=false, bool replayBufferOnly=false); - void Stop(bool overrideKeepRecording=false); + void Stop(bool overrideKeepRecording=false, bool stopReplayBuffer=false); bool StartRecording(bool force=false); void StopRecording(); void StartReplayBuffer(); - void StopReplayBuffer(); + void StopReplayBuffer(bool immediate=false); static void STDCALL StartStreamHotkey(DWORD hotkey, UPARAM param, bool bDown); static void STDCALL StopStreamHotkey(DWORD hotkey, UPARAM param, bool bDown); diff --git a/Source/OBSCapture.cpp b/Source/OBSCapture.cpp index e92a155b5..6ef188b60 100644 --- a/Source/OBSCapture.cpp +++ b/Source/OBSCapture.cpp @@ -109,20 +109,32 @@ void OBS::StartReplayBuffer() ConfigureStreamButtons(); } -void OBS::StopReplayBuffer() +void OBS::StopReplayBuffer(bool immediate) { if (!replayBufferStream) return; - bRecordingReplayBuffer = false; - ReportStopRecordingReplayBufferTrigger(); + if (!immediate && replayBufferStop.func) return; - if (!bStreaming && !bRecording && bRunning) Stop(true); + auto shutdown = [this]() + { + bRecordingReplayBuffer = false; + ReportStopRecordingReplayBufferTrigger(); - auto stream = move(replayBufferStream); + if (!bStreaming && !bRecording && bRunning) PostStopMessage(true); - replayBuffer = nullptr; + auto stream = move(replayBufferStream); - ConfigureStreamButtons(); + replayBuffer = nullptr; + + ConfigureStreamButtons(); + }; + + if (immediate) + return shutdown(); + + replayBufferStop.func = shutdown; + + replayBufferStop.time = (DWORD)(GetVideoTime() - firstFrameTimestamp); } String ExpandRecordingFilename(String filename) @@ -876,7 +888,7 @@ void OBS::Start(bool recordingOnly, bool replayBufferOnly) ConfigureStreamButtons(); } -void OBS::Stop(bool overrideKeepRecording) +void OBS::Stop(bool overrideKeepRecording, bool stopReplayBuffer) { if((!bStreaming && !bRecording && !bRunning && !bRecordingReplayBuffer) && (!bTestStream)) return; @@ -886,7 +898,7 @@ void OBS::Stop(bool overrideKeepRecording) int networkMode = AppConfig->GetInt(TEXT("Publish"), TEXT("Mode"), 2); - if(((!overrideKeepRecording && bRecording && bKeepRecording) || bRecordingReplayBuffer) && networkMode == 0) { + if((!overrideKeepRecording && ((bRecording && bKeepRecording) || (!stopReplayBuffer && bRecordingReplayBuffer))) && networkMode == 0) { videoEncoder->RequestKeyframe(); Log(TEXT("=====Stream End (recording continues): %s========================="), CurrentDateTimeString().Array()); @@ -967,6 +979,7 @@ void OBS::Stop(bool overrideKeepRecording) bStreaming = false; if(bRecording) StopRecording(); + if (bRecordingReplayBuffer) StopReplayBuffer(true); delete micAudio; micAudio = NULL; diff --git a/Source/OBSVideoCapture.cpp b/Source/OBSVideoCapture.cpp index e132e7042..439402584 100644 --- a/Source/OBSVideoCapture.cpp +++ b/Source/OBSVideoCapture.cpp @@ -217,7 +217,10 @@ void OBS::SendFrame(VideoSegment &curSegment, QWORD firstFrameTime) if (fileStream) fileStream->AddPacket(shared_data, curSegment.timestamp, curSegment.pts, packet.type); if (replayBufferStream) - replayBufferStream->AddPacket(shared_data, curSegment.timestamp, curSegment.pts, packet.type); + { + if (!HandleStreamStopInfo(replayBufferStop, packet.type, curSegment)) + replayBufferStream->AddPacket(shared_data, curSegment.timestamp, curSegment.pts, packet.type); + } } } } diff --git a/Source/ReplayBuffer.cpp b/Source/ReplayBuffer.cpp index c93be217a..220b6ca18 100644 --- a/Source/ReplayBuffer.cpp +++ b/Source/ReplayBuffer.cpp @@ -37,7 +37,7 @@ namespace using packet_vec_t = deque>; } -void CreateRecordingHelper(VideoFileStream *&stream, packet_list_t &packets); +void CreateRecordingHelper(unique_ptr &stream, packet_list_t &packets); static DWORD STDCALL SaveReplayBufferThread(void *arg); @@ -66,6 +66,8 @@ struct ReplayBuffer : VideoFileStream for (auto &thread : threads) if (WaitForSingleObject(thread.second.get(), seconds * 100) != WAIT_OBJECT_0) OSTerminateThread(thread.first.release(), 0); + else + App->AddPendingStreamThread(thread.first.release()); } virtual void AddPacket(const BYTE *data, UINT size, DWORD timestamp, DWORD pts, PacketType type) override @@ -369,7 +371,7 @@ struct RecordingHelper : VideoFileStream } }; -void CreateRecordingHelper(VideoFileStream *&stream, packet_list_t &packets) +void CreateRecordingHelper(unique_ptr &stream, packet_list_t &packets) { if (stream) { @@ -382,7 +384,7 @@ void CreateRecordingHelper(VideoFileStream *&stream, packet_list_t &packets) auto helper = make_unique(packet_vec_t{begin(packets), end(packets)}); if (helper->StartRecording()) - stream = helper.release(); + stream.reset(helper.release()); } pair> CreateReplayBuffer(int seconds)