diff --git a/src/client/videomanager.cpp b/src/client/videomanager.cpp index 9143ba12a95003ba03ff9d10cd4ebf5e40eff00c..7875cbb2c6c76532dc3a53f146fe3c0f8fc05ca8 100644 --- a/src/client/videomanager.cpp +++ b/src/client/videomanager.cpp @@ -493,6 +493,15 @@ registerSinkTarget(const std::string& sinkId, const SinkTarget& target) RING_WARN("No sink found for id '%s'", sinkId.c_str()); } +void +registerAVSinkTarget(const std::string& sinkId, const AVSinkTarget& target) +{ + if (auto sink = ring::Manager::instance().getSinkClient(sinkId)) + sink->registerAVTarget(target); + else + RING_WARN("No sink found for id '%s'", sinkId.c_str()); +} + std::map<std::string, std::string> getRenderer(const std::string& callId) { diff --git a/src/dring/videomanager_interface.h b/src/dring/videomanager_interface.h index 44bb0d144bc8688056bd3e70a8e042c2db472125..2fdf7ae0f3ad2e57ceccddcb53e639c5e3b20842 100644 --- a/src/dring/videomanager_interface.h +++ b/src/dring/videomanager_interface.h @@ -151,6 +151,11 @@ private: void setGeometry(int format, int width, int height) noexcept; }; +struct DRING_PUBLIC AVSinkTarget { + std::function<void(std::unique_ptr<VideoFrame>)> push; + int /* AVPixelFormat */ preferredFormat {-1 /* AV_PIX_FMT_NONE */}; +}; + using VideoCapabilities = std::map<std::string, std::map<std::string, std::vector<std::string>>>; DRING_PUBLIC std::vector<std::string> getDeviceList(); @@ -171,6 +176,7 @@ DRING_PUBLIC void stopAudioDevice(); DRING_PUBLIC bool switchInput(const std::string& resource); DRING_PUBLIC bool switchToCamera(); DRING_PUBLIC void registerSinkTarget(const std::string& sinkId, const SinkTarget& target); +DRING_PUBLIC void registerAVSinkTarget(const std::string& sinkId, const AVSinkTarget& target); DRING_PUBLIC std::map<std::string, std::string> getRenderer(const std::string& callId); DRING_PUBLIC std::string startLocalRecorder(const bool& audioOnly, const std::string& filepath); diff --git a/src/media/video/sinkclient.cpp b/src/media/video/sinkclient.cpp index 466c2f2798d77f172b0fc5a96cdafc25f5853f44..ae3d37c93345c6119f2e031e46b80098ee0b42e4 100644 --- a/src/media/video/sinkclient.cpp +++ b/src/media/video/sinkclient.cpp @@ -336,9 +336,13 @@ SinkClient::update(Observable<std::shared_ptr<MediaFrame>>* /*obs*/, shm_->renderFrame(f); #endif + if (avTarget_.push) { + auto outFrame = std::make_unique<VideoFrame>(); + outFrame->copyFrom(f); + avTarget_.push(std::move(outFrame)); + } if (target_.pull) { VideoFrame dst; - VideoScaler scaler; const int width = f.width(); const int height = f.height(); #if defined(__ANDROID__) || (defined(__APPLE__) && !TARGET_OS_IPHONE) diff --git a/src/media/video/sinkclient.h b/src/media/video/sinkclient.h index 839e5e845eb91c1f4d2f32d5a18d00c2d65f4c9d..5d76751523bef426b683c79633b494bb0e584f04 100644 --- a/src/media/video/sinkclient.h +++ b/src/media/video/sinkclient.h @@ -62,6 +62,10 @@ class SinkClient : public VideoFramePassiveReader return height_; } + AVPixelFormat getPreferredFormat() const noexcept { + return (AVPixelFormat)avTarget_.preferredFormat; + } + // as VideoFramePassiveReader void update(Observable<std::shared_ptr<ring::MediaFrame>>*, const std::shared_ptr<ring::MediaFrame>&) override; @@ -74,6 +78,9 @@ class SinkClient : public VideoFramePassiveReader void registerTarget(const DRing::SinkTarget& target) noexcept { target_ = target; } + void registerAVTarget(const DRing::AVSinkTarget& target) noexcept { + avTarget_ = target; + } private: const std::string id_; @@ -82,6 +89,7 @@ class SinkClient : public VideoFramePassiveReader int height_ {0}; bool started_ {false}; // used to arbitrate client's stop signal. DRing::SinkTarget target_; + DRing::AVSinkTarget avTarget_; std::unique_ptr<VideoScaler> scaler_; #ifdef DEBUG_FPS