From 1b5bbb0dbd927eac955247ba909f8dee1ed4fb0f Mon Sep 17 00:00:00 2001
From: philippegorley <philippe.gorley@savoirfairelinux.com>
Date: Wed, 4 Jul 2018 16:57:21 -0400
Subject: [PATCH] recorder: fix threadloop management

Also fixes a regression where recorder instance couldn't be used more
than once per call.

Change-Id: Ia883e77a93ae3fcab7ead04f6001ddba1c1396ea
---
 src/media/media_recorder.cpp | 36 ++++++++++++++++++++++++++----------
 src/media/media_recorder.h   |  1 +
 2 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/src/media/media_recorder.cpp b/src/media/media_recorder.cpp
index 58a0c0f808..34c8eada2e 100644
--- a/src/media/media_recorder.cpp
+++ b/src/media/media_recorder.cpp
@@ -176,14 +176,11 @@ MediaRecorder::stopRecording()
 {
     if (isRecording_) {
         RING_DBG() << "Stop recording '" << getPath() << "'";
+        isRecording_ = false;
+        loop_.join();
         flush();
     }
-    isRecording_ = false;
-    if (loop_.isRunning())
-        loop_.join();
-    videoFilter_.reset();
-    audioFilter_.reset();
-    encoder_.reset();
+    resetToDefaults();
 }
 
 int
@@ -215,7 +212,9 @@ MediaRecorder::addStream(bool isVideo, bool fromPeer, MediaStream ms)
 int
 MediaRecorder::recordData(AVFrame* frame, bool isVideo, bool fromPeer)
 {
-    if (!isRecording_ || !isReady_)
+    // recorder may be recording, but not ready for the first frames
+    // return if thread is not running
+    if (!isRecording_ || !isReady_ || !loop_.isRunning())
         return 0;
 
     // save a copy of the frame, will be filtered/encoded in another thread
@@ -486,15 +485,32 @@ MediaRecorder::flush()
     return 0;
 }
 
+void
+MediaRecorder::resetToDefaults()
+{
+    streams_.clear();
+    videoIdx_ = audioIdx_ = -1;
+    nbExpectedStreams_ = 0;
+    nbReceivedVideoStreams_ = nbReceivedAudioStreams_ = 0;
+    isRecording_ = false;
+    isReady_ = false;
+    audioOnly_ = false;
+    videoFilter_.reset();
+    audioFilter_.reset();
+    encoder_.reset();
+}
+
 void
 MediaRecorder::process()
 {
-    if (!loop_.wait_for(FRAME_DEQUEUE_INTERVAL, [this]{ return !frames_.empty(); }))
-        return;
+    // wait until frames_ is not empty or until we are no longer recording
+    loop_.wait([this]{ return !frames_.empty(); });
 
-    if (loop_.isStopping() || !isRecording_ || !isReady_)
+    // if we exited because we stopped recording, stop our thread
+    if (loop_.isStopping())
         return;
 
+    // else encode a frame
     RecordFrame recframe;
     {
         std::lock_guard<std::mutex> q(qLock_);
diff --git a/src/media/media_recorder.h b/src/media/media_recorder.h
index eee2288e14..87bf1e1087 100644
--- a/src/media/media_recorder.h
+++ b/src/media/media_recorder.h
@@ -84,6 +84,7 @@ class MediaRecorder {
         void emptyFilterGraph();
         int sendToEncoder(AVFrame* frame, int streamIdx);
         int flush();
+        void resetToDefaults(); // clear saved data for next recording
 
         std::unique_ptr<MediaEncoder> encoder_;
         std::unique_ptr<MediaFilter> videoFilter_;
-- 
GitLab