From fc83b1f8daf502d53eef941af0d6ace81b5c123c Mon Sep 17 00:00:00 2001 From: philippegorley <philippe.gorley@savoirfairelinux.com> Date: Wed, 5 Dec 2018 11:31:59 -0500 Subject: [PATCH] media: make observers/obervables use MediaFrame Makes it so observers don't need to implement Observer<T> twice to receive audio and video frames. Change-Id: Id73c384342bd786b4f83950937b4dbd13a31fc41 --- src/media/audio/audio_input.cpp | 3 ++- src/media/audio/audio_input.h | 2 +- src/media/audio/audio_receive_thread.cpp | 4 ++- src/media/audio/audio_receive_thread.h | 2 +- src/media/audio/audio_sender.cpp | 6 +++-- src/media/audio/audio_sender.h | 6 ++--- src/media/media_recorder.cpp | 31 +++++++++--------------- src/media/media_recorder.h | 8 ++---- src/media/video/sinkclient.cpp | 6 ++--- src/media/video/sinkclient.h | 4 +-- src/media/video/video_base.cpp | 2 +- src/media/video/video_base.h | 6 +++-- src/media/video/video_mixer.cpp | 12 ++++----- src/media/video/video_mixer.h | 6 ++--- src/media/video/video_sender.cpp | 6 ++--- src/media/video/video_sender.h | 4 +-- 16 files changed, 51 insertions(+), 57 deletions(-) diff --git a/src/media/audio/audio_input.cpp b/src/media/audio/audio_input.cpp index f0e2e63f0e..96a9bc3f76 100644 --- a/src/media/audio/audio_input.cpp +++ b/src/media/audio/audio_input.cpp @@ -28,6 +28,7 @@ #include <future> #include <chrono> +#include <memory> namespace ring { @@ -69,7 +70,7 @@ AudioInput::process() frame->pointer()->pts = sent_samples; sent_samples += frame->pointer()->nb_samples; - notify(frame); + notify(std::static_pointer_cast<MediaFrame>(frame)); } bool diff --git a/src/media/audio/audio_input.h b/src/media/audio/audio_input.h index 8baecb1731..5d442fb2bc 100644 --- a/src/media/audio/audio_input.h +++ b/src/media/audio/audio_input.h @@ -36,7 +36,7 @@ namespace ring { struct MediaStream; class Resampler; -class AudioInput : public Observable<std::shared_ptr<AudioFrame>> +class AudioInput : public Observable<std::shared_ptr<MediaFrame>> { public: AudioInput(const std::string& id); diff --git a/src/media/audio/audio_receive_thread.cpp b/src/media/audio/audio_receive_thread.cpp index bfd12b56d2..9865b5a357 100644 --- a/src/media/audio/audio_receive_thread.cpp +++ b/src/media/audio/audio_receive_thread.cpp @@ -30,6 +30,8 @@ #include "ringbufferpool.h" #include "smartools.h" +#include <memory> + namespace ring { AudioReceiveThread::AudioReceiveThread(const std::string& id, @@ -96,7 +98,7 @@ AudioReceiveThread::process() case MediaDecoder::Status::FrameFinished: audioDecoder_->writeToRingBuffer(*decodedFrame, *ringbuffer_, mainBuffFormat); - notify(decodedFrame); + notify(std::static_pointer_cast<MediaFrame>(decodedFrame)); return; case MediaDecoder::Status::DecodeError: RING_WARN("decoding failure, trying to reset decoder..."); diff --git a/src/media/audio/audio_receive_thread.h b/src/media/audio/audio_receive_thread.h index 11f3068c04..f67dd3fd0a 100644 --- a/src/media/audio/audio_receive_thread.h +++ b/src/media/audio/audio_receive_thread.h @@ -36,7 +36,7 @@ class MediaIOHandle; struct MediaStream; class RingBuffer; -class AudioReceiveThread : public Observable<std::shared_ptr<AudioFrame>> +class AudioReceiveThread : public Observable<std::shared_ptr<MediaFrame>> { public: AudioReceiveThread(const std::string &id, diff --git a/src/media/audio/audio_sender.cpp b/src/media/audio/audio_sender.cpp index 04c62f8dba..340d4ae5a6 100644 --- a/src/media/audio/audio_sender.cpp +++ b/src/media/audio/audio_sender.cpp @@ -30,6 +30,8 @@ #include "resampler.h" #include "smartools.h" +#include <memory> + namespace ring { AudioSender::AudioSender(const std::string& id, @@ -94,7 +96,7 @@ AudioSender::setup(SocketPair& socketPair) } void -AudioSender::update(Observable<std::shared_ptr<ring::AudioFrame>>* /*obs*/, const std::shared_ptr<ring::AudioFrame>& framePtr) +AudioSender::update(Observable<std::shared_ptr<ring::MediaFrame>>* /*obs*/, const std::shared_ptr<ring::MediaFrame>& framePtr) { auto frame = framePtr->pointer(); auto ms = MediaStream("a:local", frame->format, rational<int>(1, frame->sample_rate), @@ -103,7 +105,7 @@ AudioSender::update(Observable<std::shared_ptr<ring::AudioFrame>>* /*obs*/, cons ms.firstTimestamp = frame->pts; sent_samples += frame->nb_samples; - if (audioEncoder_->encodeAudio(*framePtr) < 0) + if (audioEncoder_->encodeAudio(*std::static_pointer_cast<AudioFrame>(framePtr)) < 0) RING_ERR("encoding failed"); } diff --git a/src/media/audio/audio_sender.h b/src/media/audio/audio_sender.h index 3b2e9736af..673b48927b 100644 --- a/src/media/audio/audio_sender.h +++ b/src/media/audio/audio_sender.h @@ -33,7 +33,7 @@ class MediaEncoder; class MediaIOHandle; class Resampler; -class AudioSender : public Observer<std::shared_ptr<AudioFrame>> { +class AudioSender : public Observer<std::shared_ptr<MediaFrame>> { public: AudioSender(const std::string& id, const std::string& dest, @@ -47,8 +47,8 @@ public: void setMuted(bool isMuted); uint16_t getLastSeqValue(); - void update(Observable<std::shared_ptr<ring::AudioFrame>>*, - const std::shared_ptr<ring::AudioFrame>&) override; + void update(Observable<std::shared_ptr<ring::MediaFrame>>*, + const std::shared_ptr<ring::MediaFrame>&) override; private: NON_COPYABLE(AudioSender); diff --git a/src/media/media_recorder.cpp b/src/media/media_recorder.cpp index 04c0f4f3c7..baf35522ec 100644 --- a/src/media/media_recorder.cpp +++ b/src/media/media_recorder.cpp @@ -141,36 +141,27 @@ MediaRecorder::addStream(const MediaStream& ms) } void -MediaRecorder::update(Observable<std::shared_ptr<AudioFrame>>* ob, const std::shared_ptr<AudioFrame>& a) +MediaRecorder::update(Observable<std::shared_ptr<MediaFrame>>* ob, const std::shared_ptr<MediaFrame>& m) { if (!isRecording_) return; std::string name; if (dynamic_cast<AudioReceiveThread*>(ob)) name = "a:remote"; - else // ob is of type AudioInput* + else if (dynamic_cast<AudioInput*>(ob)) name = "a:local"; - // copy frame to not mess with the original frame's pts - AudioFrame clone; - clone.copyFrom(*a); - clone.pointer()->pts -= streams_[name].firstTimestamp; - audioFilter_->feedInput(clone.pointer(), name); -} - -void MediaRecorder::update(Observable<std::shared_ptr<VideoFrame>>* ob, const std::shared_ptr<VideoFrame>& v) -{ - if (!isRecording_) - return; - std::string name; - if (dynamic_cast<video::VideoReceiveThread*>(ob)) + else if (dynamic_cast<video::VideoReceiveThread*>(ob)) name = "v:remote"; - else // ob is of type VideoInput* + else if (dynamic_cast<video::VideoInput*>(ob)) name = "v:local"; - // copy frame to not mess with the original frame's pts - VideoFrame clone; - clone.copyFrom(*v); + // copy frame to not mess with the original frame's pts (does not actually copy frame data) + MediaFrame clone; + clone.copyFrom(*m); clone.pointer()->pts -= streams_[name].firstTimestamp; - videoFilter_->feedInput(clone.pointer(), name); + if (clone.pointer()->width > 0 && clone.pointer()->height > 0) + videoFilter_->feedInput(clone.pointer(), name); + else + audioFilter_->feedInput(clone.pointer(), name); } int diff --git a/src/media/media_recorder.h b/src/media/media_recorder.h index c4796db8c2..0bcb632f0a 100644 --- a/src/media/media_recorder.h +++ b/src/media/media_recorder.h @@ -41,10 +41,7 @@ namespace ring { -class MediaRecorder : public Observer<std::shared_ptr<AudioFrame>> -#ifdef RING_VIDEO - , public video::VideoFramePassiveReader -#endif +class MediaRecorder : public Observer<std::shared_ptr<MediaFrame>> , public std::enable_shared_from_this<MediaRecorder> { public: @@ -104,8 +101,7 @@ public: /** * Updates the recorder with an audio or video frame. */ - void update(Observable<std::shared_ptr<AudioFrame>>* ob, const std::shared_ptr<AudioFrame>& a) override; - void update(Observable<std::shared_ptr<VideoFrame>>* ob, const std::shared_ptr<VideoFrame>& v) override; + void update(Observable<std::shared_ptr<MediaFrame>>* ob, const std::shared_ptr<MediaFrame>& a) override; private: NON_COPYABLE(MediaRecorder); diff --git a/src/media/video/sinkclient.cpp b/src/media/video/sinkclient.cpp index ef4265a911..6736fe154c 100644 --- a/src/media/video/sinkclient.cpp +++ b/src/media/video/sinkclient.cpp @@ -313,10 +313,10 @@ SinkClient::SinkClient(const std::string& id, bool mixer) {} void -SinkClient::update(Observable<std::shared_ptr<VideoFrame>>* /*obs*/, - const std::shared_ptr<VideoFrame>& frame_p) +SinkClient::update(Observable<std::shared_ptr<MediaFrame>>* /*obs*/, + const std::shared_ptr<MediaFrame>& frame_p) { - auto& f = *frame_p; + auto& f = *std::static_pointer_cast<VideoFrame>(frame_p); #ifdef DEBUG_FPS auto currentTime = std::chrono::system_clock::now(); diff --git a/src/media/video/sinkclient.h b/src/media/video/sinkclient.h index 8068e8623c..e7a8136ab4 100644 --- a/src/media/video/sinkclient.h +++ b/src/media/video/sinkclient.h @@ -63,8 +63,8 @@ class SinkClient : public VideoFramePassiveReader } // as VideoFramePassiveReader - void update(Observable<std::shared_ptr<ring::VideoFrame>>*, - const std::shared_ptr<ring::VideoFrame>&) override; + void update(Observable<std::shared_ptr<ring::MediaFrame>>*, + const std::shared_ptr<ring::MediaFrame>&) override; bool start() noexcept; bool stop() noexcept; diff --git a/src/media/video/video_base.cpp b/src/media/video/video_base.cpp index 4b8759c0a6..9aca094471 100644 --- a/src/media/video/video_base.cpp +++ b/src/media/video/video_base.cpp @@ -44,7 +44,7 @@ VideoGenerator::publishFrame() { std::lock_guard<std::mutex> lk(mutex_); lastFrame_ = std::move(writableFrame_); - notify(lastFrame_); + notify(std::static_pointer_cast<MediaFrame>(lastFrame_)); } void diff --git a/src/media/video/video_base.h b/src/media/video/video_base.h index 6954d1aac7..d7e38727be 100644 --- a/src/media/video/video_base.h +++ b/src/media/video/video_base.h @@ -49,17 +49,19 @@ struct AVIOContext; #endif namespace DRing { +class MediaFrame; class VideoFrame; } namespace ring { +using MediaFrame = DRing::MediaFrame; using VideoFrame = DRing::VideoFrame; } namespace ring { namespace video { -struct VideoFrameActiveWriter: Observable<std::shared_ptr<VideoFrame>> {}; -struct VideoFramePassiveReader: Observer<std::shared_ptr<VideoFrame>> {}; +struct VideoFrameActiveWriter: Observable<std::shared_ptr<MediaFrame>> {}; +struct VideoFramePassiveReader: Observer<std::shared_ptr<MediaFrame>> {}; /*=== VideoGenerator =========================================================*/ diff --git a/src/media/video/video_mixer.cpp b/src/media/video/video_mixer.cpp index 6757bf4c28..365f57dfd9 100644 --- a/src/media/video/video_mixer.cpp +++ b/src/media/video/video_mixer.cpp @@ -33,7 +33,7 @@ namespace ring { namespace video { struct VideoMixer::VideoMixerSource { - Observable<std::shared_ptr<VideoFrame>>* source = nullptr; + Observable<std::shared_ptr<MediaFrame>>* source = nullptr; std::unique_ptr<VideoFrame> update_frame; std::unique_ptr<VideoFrame> render_frame; void atomic_swap_render(std::unique_ptr<VideoFrame>& other) { @@ -77,7 +77,7 @@ VideoMixer::~VideoMixer() } void -VideoMixer::attached(Observable<std::shared_ptr<VideoFrame>>* ob) +VideoMixer::attached(Observable<std::shared_ptr<MediaFrame>>* ob) { auto lock(rwMutex_.write()); @@ -87,7 +87,7 @@ VideoMixer::attached(Observable<std::shared_ptr<VideoFrame>>* ob) } void -VideoMixer::detached(Observable<std::shared_ptr<VideoFrame>>* ob) +VideoMixer::detached(Observable<std::shared_ptr<MediaFrame>>* ob) { auto lock(rwMutex_.write()); @@ -100,8 +100,8 @@ VideoMixer::detached(Observable<std::shared_ptr<VideoFrame>>* ob) } void -VideoMixer::update(Observable<std::shared_ptr<VideoFrame>>* ob, - const std::shared_ptr<VideoFrame>& frame_p) +VideoMixer::update(Observable<std::shared_ptr<MediaFrame>>* ob, + const std::shared_ptr<MediaFrame>& frame_p) { auto lock(rwMutex_.read()); @@ -111,7 +111,7 @@ VideoMixer::update(Observable<std::shared_ptr<VideoFrame>>* ob, x->update_frame.reset(new VideoFrame); else x->update_frame->reset(); - x->update_frame->copyFrom(*frame_p); // copy frame content, it will be destroyed after return + x->update_frame->copyFrom(*std::static_pointer_cast<VideoFrame>(frame_p)); // copy frame content, it will be destroyed after return x->atomic_swap_render(x->update_frame); return; } diff --git a/src/media/video/video_mixer.h b/src/media/video/video_mixer.h index a7ccc08df4..57454026bc 100644 --- a/src/media/video/video_mixer.h +++ b/src/media/video/video_mixer.h @@ -49,9 +49,9 @@ public: int getPixelFormat() const override; // as VideoFramePassiveReader - void update(Observable<std::shared_ptr<VideoFrame>>* ob, const std::shared_ptr<VideoFrame>& v) override; - void attached(Observable<std::shared_ptr<VideoFrame>>* ob) override; - void detached(Observable<std::shared_ptr<VideoFrame>>* ob) override; + void update(Observable<std::shared_ptr<MediaFrame>>* ob, const std::shared_ptr<MediaFrame>& v) override; + void attached(Observable<std::shared_ptr<MediaFrame>>* ob) override; + void detached(Observable<std::shared_ptr<MediaFrame>>* ob) override; private: NON_COPYABLE(VideoMixer); diff --git a/src/media/video/video_sender.cpp b/src/media/video/video_sender.cpp index 93cfe1e0bf..d7133641b7 100644 --- a/src/media/video/video_sender.cpp +++ b/src/media/video/video_sender.cpp @@ -78,10 +78,10 @@ VideoSender::encodeAndSendVideo(VideoFrame& input_frame) } void -VideoSender::update(Observable<std::shared_ptr<VideoFrame>>* /*obs*/, - const std::shared_ptr<VideoFrame>& frame_p) +VideoSender::update(Observable<std::shared_ptr<MediaFrame>>* /*obs*/, + const std::shared_ptr<MediaFrame>& frame_p) { - encodeAndSendVideo(*frame_p); + encodeAndSendVideo(*std::static_pointer_cast<VideoFrame>(frame_p)); } void diff --git a/src/media/video/video_sender.h b/src/media/video/video_sender.h index 322aa61892..cf8eb81744 100644 --- a/src/media/video/video_sender.h +++ b/src/media/video/video_sender.h @@ -54,8 +54,8 @@ public: void forceKeyFrame(); // as VideoFramePassiveReader - void update(Observable<std::shared_ptr<VideoFrame>>* obs, - const std::shared_ptr<VideoFrame>& frame_p) override; + void update(Observable<std::shared_ptr<MediaFrame>>* obs, + const std::shared_ptr<MediaFrame>& frame_p) override; void setMuted(bool isMuted); uint16_t getLastSeqValue(); -- GitLab