From e84f2f08a17ec1e5c9ab5ef2be0f4c565768df92 Mon Sep 17 00:00:00 2001
From: philippegorley <philippe.gorley@savoirfairelinux.com>
Date: Thu, 1 Aug 2019 11:41:28 -0400
Subject: [PATCH] preferences: fix always recording setting

Change-Id: I13f4899b1e435b0a7add040db9d3416db477f1d4
---
 src/manager.cpp                          |  7 +++++++
 src/media/audio/audio_receive_thread.cpp |  7 ++++++-
 src/media/audio/audio_receive_thread.h   |  6 +++++-
 src/media/audio/audio_rtp_session.cpp    |  2 +-
 src/media/rtp_session.h                  |  9 +++++++++
 src/media/video/video_input.cpp          |  2 ++
 src/media/video/video_receive_thread.cpp |  7 ++++++-
 src/media/video/video_receive_thread.h   |  7 ++++++-
 src/media/video/video_rtp_session.cpp    |  2 +-
 src/sip/sipcall.cpp                      | 19 +++++++++++++++++++
 src/sip/sipcall.h                        |  7 +++++++
 11 files changed, 69 insertions(+), 6 deletions(-)

diff --git a/src/manager.cpp b/src/manager.cpp
index 3da74cb1b7..b52d16e1bb 100644
--- a/src/manager.cpp
+++ b/src/manager.cpp
@@ -983,6 +983,10 @@ Manager::answerCall(const std::string& call_id)
 
     addAudio(*call);
 
+    // Start recording if set in preference
+    if (audioPreference.getIsAlwaysRecording())
+        toggleRecordingCall(call_id);
+
     return result;
 }
 
@@ -1992,6 +1996,9 @@ Manager::peerAnsweredCall(Call& call)
         getRingBufferPool().flushAllBuffers();
         pimpl_->audiodriver_->flushUrgent();
     }
+
+    if (audioPreference.getIsAlwaysRecording())
+        toggleRecordingCall(call_id);
 }
 
 //THREAD=VoIP Call=Outgoing
diff --git a/src/media/audio/audio_receive_thread.cpp b/src/media/audio/audio_receive_thread.cpp
index e2c3ca0df7..5ba7bf7979 100644
--- a/src/media/audio/audio_receive_thread.cpp
+++ b/src/media/audio/audio_receive_thread.cpp
@@ -88,6 +88,10 @@ AudioReceiveThread::setup()
     Smartools::getInstance().setRemoteAudioCodec(audioDecoder_->getDecoderName());
 
     ringbuffer_ = Manager::instance().getRingBufferPool().getRingBuffer(id_);
+
+    if (onSetupSuccess_)
+        onSetupSuccess_(MEDIA_AUDIO);
+
     return true;
 }
 
@@ -135,8 +139,9 @@ AudioReceiveThread::getInfo() const
 }
 
 void
-AudioReceiveThread::startLoop()
+AudioReceiveThread::startLoop(const std::function<void(MediaType)>& cb)
 {
+    onSetupSuccess_ = cb;
     loop_.start();
 }
 
diff --git a/src/media/audio/audio_receive_thread.h b/src/media/audio/audio_receive_thread.h
index af1aea0732..418efcb5b7 100644
--- a/src/media/audio/audio_receive_thread.h
+++ b/src/media/audio/audio_receive_thread.h
@@ -22,11 +22,13 @@
 #include "audiobuffer.h"
 #include "media_buffer.h"
 #include "media_device.h"
+#include "media_codec.h"
 #include "noncopyable.h"
 #include "observer.h"
 #include "socket_pair.h"
 #include "threadloop.h"
 
+#include <functional>
 #include <sstream>
 
 namespace jami {
@@ -48,7 +50,7 @@ public:
     MediaStream getInfo() const;
 
     void addIOContext(SocketPair &socketPair);
-    void startLoop();
+    void startLoop(const std::function<void(MediaType)>& cb);
 
 private:
     NON_COPYABLE(AudioReceiveThread);
@@ -78,6 +80,8 @@ private:
 
     uint16_t mtu_;
 
+    std::function<void(MediaType)> onSetupSuccess_;
+
     ThreadLoop loop_;
     bool setup();
     void process();
diff --git a/src/media/audio/audio_rtp_session.cpp b/src/media/audio/audio_rtp_session.cpp
index 306157580b..005dbde587 100644
--- a/src/media/audio/audio_rtp_session.cpp
+++ b/src/media/audio/audio_rtp_session.cpp
@@ -135,7 +135,7 @@ AudioRtpSession::startReceiver()
                                                 receive_.receiving_sdp,
                                                 mtu_));
     receiveThread_->addIOContext(*socketPair_);
-    receiveThread_->startLoop();
+    receiveThread_->startLoop(onSuccessfulSetup_);
 }
 
 void
diff --git a/src/media/rtp_session.h b/src/media/rtp_session.h
index 5cf24a5721..7cba8b4529 100644
--- a/src/media/rtp_session.h
+++ b/src/media/rtp_session.h
@@ -3,6 +3,7 @@
  *
  *  Author: Tristan Matthews <tristan.matthews@savoirfairelinux.com>
  *  Author: Guillaume Roguez <Guillaume.Roguez@savoirfairelinux.com>
+ *  Author: Philippe Gorley <philippe.gorley@savoirfairelinux.com>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -25,6 +26,7 @@
 #include "sip/sip_utils.h"
 #include "media/media_codec.h"
 
+#include <functional>
 #include <string>
 #include <memory>
 #include <mutex>
@@ -55,6 +57,11 @@ public:
 
     void setMtu(uint16_t mtu) { mtu_ = mtu; }
 
+    void setSuccessfulSetupCb(const std::function<void(MediaType)>& cb)
+    {
+        onSuccessfulSetup_ = cb;
+    }
+
     virtual void initRecorder(std::shared_ptr<MediaRecorder>& rec) = 0;
     virtual void deinitRecorder(std::shared_ptr<MediaRecorder>& rec) = 0;
 
@@ -70,6 +77,8 @@ protected:
 
     uint16_t mtu_;
 
+    std::function<void(MediaType)> onSuccessfulSetup_;
+
     std::string getRemoteRtpUri() const {
         return "rtp://" + send_.addr.toString(true);
     }
diff --git a/src/media/video/video_input.cpp b/src/media/video/video_input.cpp
index 14ac429f7d..563827497c 100644
--- a/src/media/video/video_input.cpp
+++ b/src/media/video/video_input.cpp
@@ -3,6 +3,7 @@
  *
  *  Author: Tristan Matthews <tristan.matthews@savoirfairelinux.com>
  *  Author: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
+ *  Author: Philippe Gorley <philippe.gorley@savoirfairelinux.com>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -210,6 +211,7 @@ bool VideoInput::setup()
         JAMI_ERR("start sink failed");
 
     JAMI_DBG("VideoInput ready to capture");
+
     return true;
 }
 
diff --git a/src/media/video/video_receive_thread.cpp b/src/media/video/video_receive_thread.cpp
index 476fe843ca..d3135d6817 100644
--- a/src/media/video/video_receive_thread.cpp
+++ b/src/media/video/video_receive_thread.cpp
@@ -3,6 +3,7 @@
  *
  *  Author: Tristan Matthews <tristan.matthews@savoirfairelinux.com>
  *  Author: Guillaume Roguez <Guillaume.Roguez@savoirfairelinux.com>
+ *  Author: Philippe Gorley <philippe.gorley@savoirfairelinux.com>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -67,8 +68,9 @@ VideoReceiveThread::~VideoReceiveThread()
 }
 
 void
-VideoReceiveThread::startLoop()
+VideoReceiveThread::startLoop(const std::function<void(MediaType)>& cb)
 {
+    onSetupSuccess_ = cb;
     loop_.start();
 }
 
@@ -150,6 +152,9 @@ bool VideoReceiveThread::setup()
     // Send the resolution in smartInfo
     Smartools::getInstance().setResolution(id_, dstWidth_, dstHeight_);
 
+    if (onSetupSuccess_)
+        onSetupSuccess_(MEDIA_VIDEO);
+
     return true;
 }
 
diff --git a/src/media/video/video_receive_thread.h b/src/media/video/video_receive_thread.h
index 8e85e50817..2591e2dc53 100644
--- a/src/media/video/video_receive_thread.h
+++ b/src/media/video/video_receive_thread.h
@@ -3,6 +3,7 @@
  *
  *  Author: Tristan Matthews <tristan.matthews@savoirfairelinux.com>
  *  Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
+ *  Author: Philippe Gorley <philippe.gorley@savoirfairelinux.com>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -25,11 +26,13 @@
 #include "video_base.h"
 #include "media_codec.h"
 #include "media_io_handle.h"
+#include "media_codec.h"
 #include "media_device.h"
 #include "media_stream.h"
 #include "threadloop.h"
 #include "noncopyable.h"
 
+#include <functional>
 #include <map>
 #include <string>
 #include <climits>
@@ -49,7 +52,7 @@ class VideoReceiveThread : public VideoGenerator {
 public:
     VideoReceiveThread(const std::string &id, const std::string &sdp, uint16_t mtu);
     ~VideoReceiveThread();
-    void startLoop();
+    void startLoop(const std::function<void(MediaType)>& cb);
 
     void addIOContext(SocketPair& socketPair);
     void setRequestKeyFrameCallback(std::function<void (void)>);
@@ -98,6 +101,8 @@ private:
     static int interruptCb(void *ctx);
     static int readFunction(void *opaque, uint8_t *buf, int buf_size);
 
+    std::function<void(MediaType)> onSetupSuccess_;
+
     ThreadLoop loop_;
 
     // used by ThreadLoop
diff --git a/src/media/video/video_rtp_session.cpp b/src/media/video/video_rtp_session.cpp
index dad69d876a..9afab5fa01 100644
--- a/src/media/video/video_rtp_session.cpp
+++ b/src/media/video/video_rtp_session.cpp
@@ -164,7 +164,7 @@ void VideoRtpSession::startReceiver()
         // XXX keyframe requests can timeout if unanswered
         receiveThread_->setRequestKeyFrameCallback(requestKeyFrameCallback_);
         receiveThread_->addIOContext(*socketPair_);
-        receiveThread_->startLoop();
+        receiveThread_->startLoop(onSuccessfulSetup_);
     } else {
         JAMI_DBG("Video receiving disabled");
         if (receiveThread_)
diff --git a/src/sip/sipcall.cpp b/src/sip/sipcall.cpp
index e7c4b42a15..f9ac13590e 100644
--- a/src/sip/sipcall.cpp
+++ b/src/sip/sipcall.cpp
@@ -6,6 +6,7 @@
  *  Author: Yan Morin <yan.morin@savoirfairelinux.com>
  *  Author: Laurielle Lea <laurielle.lea@savoirfairelinux.com>
  *  Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
+ *  Author: Philippe Gorley <philippe.gorley@savoirfairelinux.com>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -974,6 +975,8 @@ SIPCall::startAllMedia()
 #endif
         rtp->updateMedia(remote, local);
 
+        rtp->setSuccessfulSetupCb([this](MediaType type){ rtpSetupSuccess(type); });
+
         // Not restarting media loop on hold as it's a huge waste of CPU ressources
         // because of the audio loop
         if (getState() != CallState::HOLD) {
@@ -1263,6 +1266,10 @@ SIPCall::getDetails() const
 bool
 SIPCall::toggleRecording()
 {
+    pendingRecord_ = true;
+    if (not readyToRecord_)
+        return true;
+
     // add streams to recorder before starting the record
     if (not Call::isRecording()) {
         std::stringstream ss;
@@ -1278,6 +1285,7 @@ SIPCall::toggleRecording()
     } else {
         deinitRecorder();
     }
+    pendingRecord_ = false;
     return Call::toggleRecording();
 }
 
@@ -1388,4 +1396,15 @@ SIPCall::newIceSocket(unsigned compId)
     return std::unique_ptr<IceSocket> {new IceSocket(mediaTransport_, compId)};
 }
 
+void
+SIPCall::rtpSetupSuccess(MediaType type)
+{
+    if ((not isAudioOnly() && type == MEDIA_VIDEO)
+        || (isAudioOnly() && type == MEDIA_AUDIO))
+        readyToRecord_ = true;
+
+    if (pendingRecord_ && readyToRecord_)
+        toggleRecording();
+}
+
 } // namespace jami
diff --git a/src/sip/sipcall.h b/src/sip/sipcall.h
index 31fe17ad5a..ab44cab6d8 100644
--- a/src/sip/sipcall.h
+++ b/src/sip/sipcall.h
@@ -5,6 +5,7 @@
  *  Author: Yan Morin <yan.morin@savoirfairelinux.com>
  *  Author: Laurielle Lea <laurielle.lea@savoirfairelinux.com>
  *  Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
+ *  Author: Philippe Gorley <philippe.gorley@savoirfairelinux.com>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -28,6 +29,7 @@
 #endif
 
 #include "call.h"
+#include "media_codec.h" // for MediaType enum
 #include "sip_utils.h"
 
 #ifdef ENABLE_VIDEO
@@ -241,6 +243,8 @@ public: // NOT SIP RELATED (good candidates to be moved elsewhere)
 
     void deinitRecorder();
 
+    void rtpSetupSuccess(MediaType type);
+
 private:
     NON_COPYABLE(SIPCall);
 
@@ -331,6 +335,9 @@ private:
     std::shared_ptr<IceTransport> tmpMediaTransport_;
 
     std::string peerUri_{};
+
+    bool readyToRecord_ {false};
+    bool pendingRecord_ {false};
 };
 
 // Helpers
-- 
GitLab