diff --git a/src/manager.cpp b/src/manager.cpp index 3da74cb1b77957ecd024c891590ca2e0c7a055d5..b52d16e1bbc1ef68d1eff6cdec26e7660e8a86c8 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 e2c3ca0df70f78eb4656fcdafa5385f7b71e154d..5ba7bf7979e2a939ba20e4063995daf92f75338f 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 af1aea0732aeaefc42f65276f3cd6355ccfb4759..418efcb5b7089b6ad9e88854b5854d9a2e5999de 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 306157580bc3bbcbe4b8a9512f8acd4b4b9ef695..005dbde58721061ad3379d89bb00205541d7f217 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 5cf24a5721f2577bff8d63364703806fb20cbb24..7cba8b4529fc2abab501e320956cd23b6a052e69 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 14ac429f7d58d28d35cb83edd999d60d6b348fbc..563827497cc169e5b7fbc33fc453e58643148c92 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 476fe843ca802c2ce2cf65e63944b2aa719dd3d1..d3135d681711778d53465aea30c96458467005d6 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 8e85e50817dde64b0aaa006227113066474c5388..2591e2dc530dd13270d5d32d30e047449f09f8c7 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 dad69d876ae461f00ec837a4843f88457631c92a..9afab5fa018a6d30295607a5173f0eee61be2251 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 e7c4b42a150609991e4479777d57a08d38f21d5f..f9ac13590ee7e1a07d7a1c69bf8a57bf7a4d62e9 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 31fe17ad5a29eae532cb76bbb5381fc1b38b9668..ab44cab6d88170da15d4a05820f6c156c8dc7c17 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