diff --git a/include/rtc_audio_source.h b/include/rtc_audio_source.h index 43e39fd801..b27cfcbe50 100644 --- a/include/rtc_audio_source.h +++ b/include/rtc_audio_source.h @@ -2,6 +2,7 @@ #define LIB_WEBRTC_RTC_AUDIO_SOURCE_HXX #include "rtc_types.h" +#include "rtc_audio_frame.h" namespace libwebrtc { @@ -20,6 +21,15 @@ class RTCAudioSource : public RefCountInterface { virtual ~RTCAudioSource() {} }; +class VirtualAudioCapturer : public RefCountInterface { + public: + LIB_WEBRTC_API static scoped_refptr Create(); + + virtual void OnDataCaptured(scoped_refptr data) = 0; + + virtual scoped_refptr source() = 0; +}; + } // namespace libwebrtc #endif // LIB_WEBRTC_RTC_AUDIO_TRACK_HXX diff --git a/include/rtc_video_source.h b/include/rtc_video_source.h index cb61abbb49..3343966265 100644 --- a/include/rtc_video_source.h +++ b/include/rtc_video_source.h @@ -2,6 +2,7 @@ #define LIB_WEBRTC_RTC_VIDEO_SOURCE_HXX #include "rtc_types.h" +#include "rtc_video_frame.h" namespace libwebrtc { @@ -9,6 +10,16 @@ class RTCVideoSource : public RefCountInterface { public: ~RTCVideoSource() {} }; + +class VirtualVideoCapturer : public RefCountInterface { + public: + LIB_WEBRTC_API static scoped_refptr Create(); + + virtual void OnFrameCaptured(scoped_refptr frame) = 0; + + virtual scoped_refptr source() = 0; +}; + } // namespace libwebrtc #endif // LIB_WEBRTC_RTC_VIDEO_SOURCE_HXX diff --git a/src/rtc_audio_source_impl.cc b/src/rtc_audio_source_impl.cc index a9e2526c80..04bdbdeb9a 100644 --- a/src/rtc_audio_source_impl.cc +++ b/src/rtc_audio_source_impl.cc @@ -1,5 +1,7 @@ #include "rtc_audio_source_impl.h" +#include "pc/local_audio_source.h" + namespace libwebrtc { RTCAudioSourceImpl::RTCAudioSourceImpl( @@ -12,4 +14,55 @@ RTCAudioSourceImpl::~RTCAudioSourceImpl() { RTC_LOG(LS_INFO) << __FUNCTION__ << ": dtor "; } +class AdaptedVirtualAudioCapturer : public webrtc::LocalAudioSource { + public: + AdaptedVirtualAudioCapturer() {} + ~AdaptedVirtualAudioCapturer() {} + + void AddSink(webrtc::AudioTrackSinkInterface* sink) override { + webrtc::MutexLock lock(&mutex_); + sinks_.push_back(sink); + } + + void RemoveSink(webrtc::AudioTrackSinkInterface* sink) override { + webrtc::MutexLock lock(&mutex_); + sinks_.erase(std::remove(sinks_.begin(), sinks_.end(), sink), sinks_.end()); + } + + void OnCaptureData(scoped_refptr frame) { + webrtc::MutexLock lock(&mutex_); + for (auto sink : sinks_) { + sink->OnData((const void*)frame->data(), 16, frame->sample_rate_hz(), + frame->num_channels(), frame->samples_per_channel()); + } + } + + private: + mutable webrtc::Mutex mutex_; + std::vector sinks_; +}; + +class VirtualAudioCapturerImpl : public VirtualAudioCapturer { + public: + VirtualAudioCapturerImpl() {} + virtual ~VirtualAudioCapturerImpl() {} + + virtual void OnDataCaptured(scoped_refptr frame) override { + adapted_source_->OnCaptureData(frame); + } + + virtual scoped_refptr source() override { + return rtc_audio_source_; + } + + private: + scoped_refptr rtc_audio_source_; + rtc::scoped_refptr adapted_source_; +}; + +scoped_refptr VirtualAudioCapturer::Create() { + return scoped_refptr( + new RefCountedObject()); +} + } // namespace libwebrtc diff --git a/src/rtc_video_frame_impl.h b/src/rtc_video_frame_impl.h index 3af6845abb..0fbe094ee1 100644 --- a/src/rtc_video_frame_impl.h +++ b/src/rtc_video_frame_impl.h @@ -51,6 +51,8 @@ class VideoFrameBufferImpl : public RTCVideoFrame { void set_rotation(webrtc::VideoRotation rotation) { rotation_ = rotation; } + webrtc::VideoRotation rtc_rotation() { return rotation_; } + private: rtc::scoped_refptr buffer_; int64_t timestamp_us_ = 0; diff --git a/src/rtc_video_source_impl.cc b/src/rtc_video_source_impl.cc index ef4ec9c5a6..df3c438f2b 100644 --- a/src/rtc_video_source_impl.cc +++ b/src/rtc_video_source_impl.cc @@ -6,6 +6,58 @@ namespace libwebrtc { +class AdaptedVirtualVideoCapturer : public rtc::AdaptedVideoTrackSource { + public: + AdaptedVirtualVideoCapturer() {} + ~AdaptedVirtualVideoCapturer() override {} + + bool is_screencast() const override { return false; } + + absl::optional needs_denoising() const override { return false; } + + SourceState state() const override { return kLive; } + + bool remote() const override { return false; } + + void OnFrameCaptured(scoped_refptr frame) { + VideoFrameBufferImpl* impl = + static_cast(frame.get()); + auto newFrame = webrtc::VideoFrame::Builder() + .set_video_frame_buffer(impl->buffer()) + .set_rotation(impl->rtc_rotation()) + .set_timestamp_us(impl->timestamp_us()) + .build(); + OnFrame(newFrame); + } +}; + +class VirtualVideoCapturerImpl : public VirtualVideoCapturer { + public: + VirtualVideoCapturerImpl() { + adapted_source_ = new rtc::RefCountedObject(); + rtc_source_ = scoped_refptr( + new RefCountedObject(adapted_source_)); + } + virtual ~VirtualVideoCapturerImpl() {} + + virtual scoped_refptr source() override { + return rtc_source_; + } + + virtual void OnFrameCaptured(scoped_refptr frame) override { + adapted_source_->OnFrameCaptured(frame); + } + + private: + rtc::scoped_refptr adapted_source_; + scoped_refptr rtc_source_; +}; + +scoped_refptr VirtualVideoCapturer::Create() { + return scoped_refptr( + new RefCountedObject()); +} + RTCVideoSourceImpl::RTCVideoSourceImpl( rtc::scoped_refptr rtc_source_track) : rtc_source_track_(rtc_source_track) { diff --git a/src/rtc_video_source_impl.h b/src/rtc_video_source_impl.h index 568355701c..9433379d3f 100644 --- a/src/rtc_video_source_impl.h +++ b/src/rtc_video_source_impl.h @@ -2,6 +2,7 @@ #define LIB_WEBRTC_VIDEO_SOURCE_IMPL_HXX #include "api/media_stream_interface.h" +#include "media/base/adapted_video_track_source.h" #include "media/base/video_broadcaster.h" #include "media/base/video_source_base.h" #include "rtc_peerconnection_factory_impl.h"