Repo created
This commit is contained in:
parent
81b91f4139
commit
f8c34fa5ee
22732 changed files with 4815320 additions and 2 deletions
|
|
@ -0,0 +1,56 @@
|
|||
#include "DesktopInterface.h"
|
||||
|
||||
#include "platform/tdesktop/VideoCapturerInterfaceImpl.h"
|
||||
#include "platform/tdesktop/VideoCapturerTrackSource.h"
|
||||
|
||||
#include "api/video_codecs/builtin_video_encoder_factory.h"
|
||||
#include "api/video_codecs/builtin_video_decoder_factory.h"
|
||||
#include "pc/video_track_source_proxy.h"
|
||||
|
||||
#if TGCALLS_UWP_DESKTOP
|
||||
#include "modules/video_coding/codecs/h264/win/h264_mf_factory.h"
|
||||
#endif
|
||||
|
||||
namespace tgcalls {
|
||||
|
||||
std::unique_ptr<webrtc::VideoEncoderFactory> DesktopInterface::makeVideoEncoderFactory(bool preferHardwareEncoding, bool isScreencast) {
|
||||
#if TGCALLS_UWP_DESKTOP
|
||||
return std::make_unique<webrtc::H264MFEncoderFactory>();
|
||||
#else
|
||||
return webrtc::CreateBuiltinVideoEncoderFactory();
|
||||
#endif
|
||||
}
|
||||
|
||||
std::unique_ptr<webrtc::VideoDecoderFactory> DesktopInterface::makeVideoDecoderFactory() {
|
||||
#if TGCALLS_UWP_DESKTOP
|
||||
return std::make_unique<webrtc::H264MFDecoderFactory>();
|
||||
#else
|
||||
return webrtc::CreateBuiltinVideoDecoderFactory();
|
||||
#endif
|
||||
}
|
||||
|
||||
rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> DesktopInterface::makeVideoSource(rtc::Thread *signalingThread, rtc::Thread *workerThread) {
|
||||
const auto videoTrackSource = rtc::scoped_refptr<VideoCapturerTrackSource>(
|
||||
new rtc::RefCountedObject<VideoCapturerTrackSource>());
|
||||
return videoTrackSource
|
||||
? webrtc::VideoTrackSourceProxy::Create(signalingThread, workerThread, videoTrackSource)
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
bool DesktopInterface::supportsEncoding(const std::string &codecName) {
|
||||
return (codecName == cricket::kH264CodecName)
|
||||
|| (codecName == cricket::kVp8CodecName);
|
||||
}
|
||||
|
||||
void DesktopInterface::adaptVideoSource(rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> videoSource, int width, int height, int fps) {
|
||||
}
|
||||
|
||||
std::unique_ptr<VideoCapturerInterface> DesktopInterface::makeVideoCapturer(rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> source, std::string deviceId, std::function<void(VideoState)> stateUpdated, std::function<void(PlatformCaptureInfo)> captureInfoUpdated, std::shared_ptr<PlatformContext> platformContext, std::pair<int, int> &outResolution) {
|
||||
return std::make_unique<VideoCapturerInterfaceImpl>(source, deviceId, stateUpdated, platformContext, outResolution);
|
||||
}
|
||||
|
||||
std::unique_ptr<PlatformInterface> CreatePlatformInterface() {
|
||||
return std::make_unique<DesktopInterface>();
|
||||
}
|
||||
|
||||
} // namespace tgcalls
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef TGCALLS_DESKTOP_INTERFACE_H
|
||||
#define TGCALLS_DESKTOP_INTERFACE_H
|
||||
|
||||
#include "platform/PlatformInterface.h"
|
||||
#include "VideoCapturerInterface.h"
|
||||
|
||||
namespace tgcalls {
|
||||
|
||||
class DesktopInterface : public PlatformInterface {
|
||||
public:
|
||||
std::unique_ptr<webrtc::VideoEncoderFactory> makeVideoEncoderFactory(bool preferHardwareEncoding = false, bool isScreencast = false) override;
|
||||
std::unique_ptr<webrtc::VideoDecoderFactory> makeVideoDecoderFactory() override;
|
||||
bool supportsEncoding(const std::string &codecName) override;
|
||||
rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> makeVideoSource(rtc::Thread *signalingThread, rtc::Thread *workerThread) override;
|
||||
void adaptVideoSource(rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> videoSource, int width, int height, int fps) override;
|
||||
std::unique_ptr<VideoCapturerInterface> makeVideoCapturer(rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> source, std::string deviceId, std::function<void(VideoState)> stateUpdated, std::function<void(PlatformCaptureInfo)> captureInfoUpdated, std::shared_ptr<PlatformContext> platformContext, std::pair<int, int> &outResolution) override;
|
||||
|
||||
};
|
||||
|
||||
} // namespace tgcalls
|
||||
|
||||
#endif // TGCALLS_DESKTOP_INTERFACE_H
|
||||
|
|
@ -0,0 +1,253 @@
|
|||
#include "VideoCameraCapturer.h"
|
||||
|
||||
#include "api/video/i420_buffer.h"
|
||||
#include "api/video/video_frame_buffer.h"
|
||||
#include "api/video/video_rotation.h"
|
||||
#include "modules/video_capture/video_capture_factory.h"
|
||||
#include "rtc_base/checks.h"
|
||||
#include "rtc_base/logging.h"
|
||||
|
||||
#ifdef WEBRTC_LINUX // Breaks compilation on MSVC because of ERROR define.
|
||||
#include <modules/video_capture/video_capture_options.h>
|
||||
#endif // WEBRTC_LINUX
|
||||
|
||||
#include <stdint.h>
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
|
||||
namespace tgcalls {
|
||||
namespace {
|
||||
|
||||
constexpr auto kPreferredWidth = 1280;
|
||||
constexpr auto kPreferredHeight = 720;
|
||||
constexpr auto kPreferredFps = 30;
|
||||
|
||||
#ifdef WEBRTC_LINUX
|
||||
[[nodiscard]] webrtc::VideoCaptureOptions GetVideoCaptureOptions() {
|
||||
auto result = webrtc::VideoCaptureOptions();
|
||||
result.set_allow_v4l2(true);
|
||||
#ifdef WEBRTC_USE_PIPEWIRE
|
||||
//result.set_allow_pipewire(true);
|
||||
// This requires a call to result.Init(callback)
|
||||
// and waiting for the callback to finish.
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
VideoCameraCapturer::VideoCameraCapturer(
|
||||
std::shared_ptr<rtc::VideoSinkInterface<webrtc::VideoFrame>> sink)
|
||||
: _sink(sink) {
|
||||
}
|
||||
|
||||
VideoCameraCapturer::~VideoCameraCapturer() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
void VideoCameraCapturer::create() {
|
||||
_failed = false;
|
||||
|
||||
#ifdef WEBRTC_LINUX
|
||||
auto options = GetVideoCaptureOptions();
|
||||
const auto info = std::unique_ptr<
|
||||
webrtc::VideoCaptureModule::DeviceInfo
|
||||
>(webrtc::VideoCaptureFactory::CreateDeviceInfo(&options));
|
||||
#else // WEBRTC_LINUX
|
||||
const auto info = std::unique_ptr<
|
||||
webrtc::VideoCaptureModule::DeviceInfo
|
||||
>(webrtc::VideoCaptureFactory::CreateDeviceInfo());
|
||||
#endif // WEBRTC_LINUX
|
||||
|
||||
if (!info) {
|
||||
failed();
|
||||
return;
|
||||
}
|
||||
const auto count = info->NumberOfDevices();
|
||||
if (count <= 0) {
|
||||
failed();
|
||||
return;
|
||||
}
|
||||
const auto getId = [&](int index) {
|
||||
constexpr auto kLengthLimit = 256;
|
||||
char name[kLengthLimit] = { 0 };
|
||||
char id[kLengthLimit] = { 0 };
|
||||
return (info->GetDeviceName(index, name, kLengthLimit, id, kLengthLimit) == 0)
|
||||
? std::string(id)
|
||||
: std::string();
|
||||
};
|
||||
auto preferredId = std::string();
|
||||
for (auto i = 0; i != count; ++i) {
|
||||
const auto id = getId(i);
|
||||
if ((_requestedDeviceId == id)
|
||||
|| (preferredId.empty()
|
||||
&& (_requestedDeviceId.empty() || _requestedDeviceId == "default"))) {
|
||||
preferredId = id;
|
||||
}
|
||||
}
|
||||
if (create(info.get(), preferredId)) {
|
||||
return;
|
||||
}
|
||||
for (auto i = 0; i != count; ++i) {
|
||||
if (create(info.get(), getId(i))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
failed();
|
||||
}
|
||||
|
||||
void VideoCameraCapturer::failed() {
|
||||
_failed = true;
|
||||
if (_error) {
|
||||
_error();
|
||||
}
|
||||
}
|
||||
|
||||
bool VideoCameraCapturer::create(
|
||||
webrtc::VideoCaptureModule::DeviceInfo *info,
|
||||
const std::string &deviceId) {
|
||||
const auto deviceString = deviceId.c_str();
|
||||
#ifdef WEBRTC_LINUX
|
||||
auto options = GetVideoCaptureOptions();
|
||||
_module = webrtc::VideoCaptureFactory::Create(&options, deviceString);
|
||||
#else // WEBRTC_LINUX
|
||||
_module = webrtc::VideoCaptureFactory::Create(deviceString);
|
||||
#endif // WEBRTC_LINUX
|
||||
|
||||
if (!_module) {
|
||||
RTC_LOG(LS_ERROR)
|
||||
<< "Failed to create VideoCameraCapturer '" << deviceId << "'.";
|
||||
return false;
|
||||
}
|
||||
_module->RegisterCaptureDataCallback(this);
|
||||
|
||||
auto requested = webrtc::VideoCaptureCapability();
|
||||
requested.videoType = webrtc::VideoType::kI420;
|
||||
requested.width = kPreferredWidth;
|
||||
requested.height = kPreferredHeight;
|
||||
requested.maxFPS = kPreferredFps;
|
||||
info->GetBestMatchedCapability(
|
||||
_module->CurrentDeviceName(),
|
||||
requested,
|
||||
_capability);
|
||||
if (!_capability.width || !_capability.height || !_capability.maxFPS) {
|
||||
_capability.width = kPreferredWidth;
|
||||
_capability.height = kPreferredHeight;
|
||||
_capability.maxFPS = kPreferredFps;
|
||||
}
|
||||
#ifndef WEBRTC_WIN
|
||||
_capability.videoType = webrtc::VideoType::kI420;
|
||||
#endif // WEBRTC_WIN
|
||||
if (_module->StartCapture(_capability) != 0) {
|
||||
RTC_LOG(LS_ERROR)
|
||||
<< "Failed to start VideoCameraCapturer '" << _requestedDeviceId << "'.";
|
||||
destroy();
|
||||
return false;
|
||||
}
|
||||
_dimensions = std::make_pair(_capability.width, _capability.height);
|
||||
return true;
|
||||
}
|
||||
|
||||
void VideoCameraCapturer::setState(VideoState state) {
|
||||
if (_state == state) {
|
||||
return;
|
||||
}
|
||||
_state = state;
|
||||
if (_state == VideoState::Active) {
|
||||
create();
|
||||
} else {
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
void VideoCameraCapturer::setDeviceId(std::string deviceId) {
|
||||
if (_requestedDeviceId == deviceId) {
|
||||
return;
|
||||
}
|
||||
destroy();
|
||||
_requestedDeviceId = deviceId;
|
||||
if (_state == VideoState::Active) {
|
||||
create();
|
||||
}
|
||||
}
|
||||
|
||||
void VideoCameraCapturer::setPreferredCaptureAspectRatio(float aspectRatio) {
|
||||
_aspectRatio = aspectRatio;
|
||||
}
|
||||
|
||||
void VideoCameraCapturer::setOnFatalError(std::function<void()> error) {
|
||||
_error = std::move(error);
|
||||
if (_failed && _error) {
|
||||
_error();
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<int, int> VideoCameraCapturer::resolution() const {
|
||||
return _dimensions;
|
||||
}
|
||||
|
||||
void VideoCameraCapturer::destroy() {
|
||||
_failed = false;
|
||||
if (!_module) {
|
||||
return;
|
||||
}
|
||||
|
||||
_module->StopCapture();
|
||||
_module->DeRegisterCaptureDataCallback();
|
||||
_module = nullptr;
|
||||
}
|
||||
|
||||
void VideoCameraCapturer::OnFrame(const webrtc::VideoFrame &frame) {
|
||||
if (_state != VideoState::Active) {
|
||||
return;
|
||||
} else if (_aspectRatio <= 0.001) {
|
||||
_sink->OnFrame(frame);
|
||||
return;
|
||||
}
|
||||
const auto originalWidth = frame.width();
|
||||
const auto originalHeight = frame.height();
|
||||
auto width = (originalWidth > _aspectRatio * originalHeight)
|
||||
? int(std::round(_aspectRatio * originalHeight))
|
||||
: originalWidth;
|
||||
auto height = (originalWidth > _aspectRatio * originalHeight)
|
||||
? originalHeight
|
||||
: int(std::round(originalHeight / _aspectRatio));
|
||||
if ((width >= originalWidth && height >= originalHeight) || !width || !height) {
|
||||
_sink->OnFrame(frame);
|
||||
return;
|
||||
}
|
||||
|
||||
width &= ~int(1);
|
||||
height &= ~int(1);
|
||||
const auto left = (originalWidth - width) / 2;
|
||||
const auto top = (originalHeight - height) / 2;
|
||||
rtc::scoped_refptr<webrtc::I420Buffer> croppedBuffer =
|
||||
webrtc::I420Buffer::Create(width, height);
|
||||
croppedBuffer->CropAndScaleFrom(
|
||||
*frame.video_frame_buffer()->ToI420(),
|
||||
left,
|
||||
top,
|
||||
width,
|
||||
height);
|
||||
webrtc::VideoFrame::Builder croppedBuilder =
|
||||
webrtc::VideoFrame::Builder()
|
||||
.set_video_frame_buffer(croppedBuffer)
|
||||
.set_rotation(webrtc::kVideoRotation_0)
|
||||
.set_timestamp_us(frame.timestamp_us())
|
||||
.set_id(frame.id());
|
||||
if (frame.has_update_rect()) {
|
||||
croppedBuilder.set_update_rect(frame.update_rect().ScaleWithFrame(
|
||||
frame.width(),
|
||||
frame.height(),
|
||||
left,
|
||||
top,
|
||||
width,
|
||||
height,
|
||||
width,
|
||||
height));
|
||||
}
|
||||
_sink->OnFrame(croppedBuilder.build());
|
||||
}
|
||||
|
||||
} // namespace tgcalls
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
#ifndef TGCALLS_VIDEO_CAMERA_CAPTURER_H
|
||||
#define TGCALLS_VIDEO_CAMERA_CAPTURER_H
|
||||
|
||||
#include "api/scoped_refptr.h"
|
||||
#include "api/video/video_frame.h"
|
||||
#include "api/video/video_source_interface.h"
|
||||
#include "media/base/video_adapter.h"
|
||||
#include "modules/video_capture/video_capture.h"
|
||||
|
||||
#include "VideoCaptureInterface.h"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <stddef.h>
|
||||
|
||||
namespace tgcalls {
|
||||
|
||||
class VideoCameraCapturer
|
||||
: public rtc::VideoSinkInterface<webrtc::VideoFrame> {
|
||||
public:
|
||||
explicit VideoCameraCapturer(
|
||||
std::shared_ptr<rtc::VideoSinkInterface<webrtc::VideoFrame>> sink);
|
||||
~VideoCameraCapturer();
|
||||
|
||||
void setState(VideoState state);
|
||||
void setDeviceId(std::string deviceId);
|
||||
void setPreferredCaptureAspectRatio(float aspectRatio);
|
||||
void setOnFatalError(std::function<void()> error);
|
||||
|
||||
std::pair<int, int> resolution() const;
|
||||
|
||||
void OnFrame(const webrtc::VideoFrame &frame) override;
|
||||
|
||||
private:
|
||||
void create();
|
||||
bool create(
|
||||
webrtc::VideoCaptureModule::DeviceInfo *info,
|
||||
const std::string &deviceId);
|
||||
void destroy();
|
||||
void failed();
|
||||
|
||||
std::shared_ptr<rtc::VideoSinkInterface<webrtc::VideoFrame>> _sink;
|
||||
rtc::scoped_refptr<webrtc::VideoCaptureModule> _module;
|
||||
webrtc::VideoCaptureCapability _capability;
|
||||
|
||||
VideoState _state = VideoState::Inactive;
|
||||
std::string _requestedDeviceId;
|
||||
std::pair<int, int> _dimensions;
|
||||
std::function<void()> _error;
|
||||
float _aspectRatio = 0.;
|
||||
bool _failed = false;
|
||||
|
||||
};
|
||||
|
||||
} // namespace tgcalls
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
#include "tgcalls/platform/tdesktop/VideoCapturerInterfaceImpl.h"
|
||||
|
||||
#include "tgcalls/platform/tdesktop/VideoCapturerTrackSource.h"
|
||||
#include "tgcalls/platform/tdesktop/VideoCameraCapturer.h"
|
||||
|
||||
#ifndef TGCALLS_UWP_DESKTOP
|
||||
#include "tgcalls/desktop_capturer/DesktopCaptureSourceHelper.h"
|
||||
#endif // TGCALLS_DISABLE_DESKTOP_CAPTURE
|
||||
|
||||
#include "pc/video_track_source_proxy.h"
|
||||
|
||||
namespace tgcalls {
|
||||
namespace {
|
||||
|
||||
std::shared_ptr<rtc::VideoSinkInterface<webrtc::VideoFrame>> GetSink(
|
||||
const rtc::scoped_refptr<
|
||||
webrtc::VideoTrackSourceInterface> &nativeSource) {
|
||||
const auto proxy = static_cast<webrtc::VideoTrackSourceProxy*>(
|
||||
nativeSource.get());
|
||||
const auto internal = static_cast<VideoCapturerTrackSource*>(
|
||||
proxy->internal());
|
||||
return internal->sink();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
VideoCapturerInterfaceImpl::VideoCapturerInterfaceImpl(
|
||||
rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> source,
|
||||
std::string deviceId,
|
||||
std::function<void(VideoState)> stateUpdated,
|
||||
std::shared_ptr<PlatformContext> platformContext,
|
||||
std::pair<int, int> &outResolution)
|
||||
: _source(source)
|
||||
, _sink(GetSink(source))
|
||||
, _stateUpdated(stateUpdated) {
|
||||
#ifdef TGCALLS_UWP_DESKTOP
|
||||
if (deviceId == "GraphicsCaptureItem")
|
||||
{
|
||||
auto uwpContext = std::static_pointer_cast<UwpContext>(platformContext);
|
||||
|
||||
_screenCapturer = std::make_unique<UwpScreenCapturer>(_sink, uwpContext->item);
|
||||
_screenCapturer->setState(VideoState::Active);
|
||||
outResolution = _screenCapturer->resolution();
|
||||
}
|
||||
else
|
||||
#else
|
||||
if (const auto source = DesktopCaptureSourceForKey(deviceId)) {
|
||||
const auto data = DesktopCaptureSourceData{
|
||||
/*.aspectSize = */{ 1280, 720 },
|
||||
/*.fps = */24.,
|
||||
/*.captureMouse = */true,
|
||||
};
|
||||
_desktopCapturer = std::make_unique<DesktopCaptureSourceHelper>(
|
||||
source,
|
||||
data);
|
||||
_desktopCapturer->setOutput(_sink);
|
||||
_desktopCapturer->start();
|
||||
outResolution = { 1280, 960 };
|
||||
} else if (!ShouldBeDesktopCapture(deviceId))
|
||||
#endif // TGCALLS_UWP_DESKTOP
|
||||
{
|
||||
_cameraCapturer = std::make_unique<VideoCameraCapturer>(_sink);
|
||||
_cameraCapturer->setDeviceId(deviceId);
|
||||
_cameraCapturer->setState(VideoState::Active);
|
||||
outResolution = _cameraCapturer->resolution();
|
||||
}
|
||||
}
|
||||
|
||||
VideoCapturerInterfaceImpl::~VideoCapturerInterfaceImpl() {
|
||||
}
|
||||
|
||||
void VideoCapturerInterfaceImpl::setState(VideoState state) {
|
||||
#ifdef TGCALLS_UWP_DESKTOP
|
||||
if (_screenCapturer) {
|
||||
_screenCapturer->setState(state);
|
||||
} else
|
||||
#else
|
||||
if (_desktopCapturer) {
|
||||
if (state == VideoState::Active) {
|
||||
_desktopCapturer->start();
|
||||
} else {
|
||||
_desktopCapturer->stop();
|
||||
}
|
||||
} else
|
||||
#endif // TGCALLS_UWP_DESKTOP
|
||||
if (_cameraCapturer) {
|
||||
_cameraCapturer->setState(state);
|
||||
}
|
||||
if (_stateUpdated) {
|
||||
_stateUpdated(state);
|
||||
}
|
||||
}
|
||||
|
||||
void VideoCapturerInterfaceImpl::setPreferredCaptureAspectRatio(
|
||||
float aspectRatio) {
|
||||
if (_cameraCapturer) {
|
||||
_cameraCapturer->setPreferredCaptureAspectRatio(aspectRatio);
|
||||
}
|
||||
}
|
||||
|
||||
void VideoCapturerInterfaceImpl::setUncroppedOutput(
|
||||
std::shared_ptr<rtc::VideoSinkInterface<webrtc::VideoFrame>> sink) {
|
||||
if (_uncroppedSink != nullptr) {
|
||||
_source->RemoveSink(_uncroppedSink.get());
|
||||
}
|
||||
_uncroppedSink = sink;
|
||||
if (_uncroppedSink != nullptr) {
|
||||
_source->AddOrUpdateSink(
|
||||
_uncroppedSink.get(),
|
||||
rtc::VideoSinkWants());
|
||||
}
|
||||
}
|
||||
|
||||
void VideoCapturerInterfaceImpl::setOnFatalError(std::function<void()> error) {
|
||||
#ifdef TGCALLS_UWP_DESKTOP
|
||||
if (_screenCapturer) {
|
||||
_screenCapturer->setOnFatalError(std::move(error));
|
||||
} else if (!_screenCapturer && !_cameraCapturer && error) {
|
||||
error();
|
||||
}
|
||||
#else // TGCALLS_UWP_DESKTOP
|
||||
if (_desktopCapturer) {
|
||||
_desktopCapturer->setOnFatalError(std::move(error));
|
||||
} else if (!_desktopCapturer && !_cameraCapturer && error) {
|
||||
error();
|
||||
}
|
||||
#endif // TGCALLS_UWP_DESKTOP
|
||||
if (_cameraCapturer) {
|
||||
_cameraCapturer->setOnFatalError(std::move(error));
|
||||
}
|
||||
}
|
||||
|
||||
void VideoCapturerInterfaceImpl::setOnPause(std::function<void(bool)> pause) {
|
||||
#ifdef TGCALLS_UWP_DESKTOP
|
||||
if (_screenCapturer) {
|
||||
_screenCapturer->setOnPause(std::move(pause));
|
||||
}
|
||||
#else // TGCALLS_UWP_DESKTOP
|
||||
if (_desktopCapturer) {
|
||||
_desktopCapturer->setOnPause(std::move(pause));
|
||||
}
|
||||
#endif // TGCALLS_UWP_DESKTOP
|
||||
}
|
||||
|
||||
} // namespace tgcalls
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
#ifndef TGCALLS_VIDEO_CAPTURER_INTERFACE_IMPL_H
|
||||
#define TGCALLS_VIDEO_CAPTURER_INTERFACE_IMPL_H
|
||||
|
||||
#include "VideoCapturerInterface.h"
|
||||
|
||||
#ifdef TGCALLS_UWP_DESKTOP
|
||||
#include "platform/uwp/UwpContext.h"
|
||||
#include "platform/uwp/UwpScreenCapturer.h"
|
||||
#endif // TGCALLS_UWP_DESKTOP
|
||||
|
||||
#include "api/media_stream_interface.h"
|
||||
|
||||
namespace tgcalls {
|
||||
|
||||
class DesktopCaptureSourceHelper;
|
||||
class VideoCameraCapturer;
|
||||
class PlatformContext;
|
||||
|
||||
class VideoCapturerInterfaceImpl final : public VideoCapturerInterface {
|
||||
public:
|
||||
VideoCapturerInterfaceImpl(
|
||||
rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> source,
|
||||
std::string deviceId,
|
||||
std::function<void(VideoState)> stateUpdated,
|
||||
std::shared_ptr<PlatformContext> platformContext,
|
||||
std::pair<int, int> &outResolution);
|
||||
~VideoCapturerInterfaceImpl() override;
|
||||
|
||||
void setState(VideoState state) override;
|
||||
void setPreferredCaptureAspectRatio(float aspectRatio) override;
|
||||
void setUncroppedOutput(std::shared_ptr<rtc::VideoSinkInterface<webrtc::VideoFrame>> sink) override;
|
||||
int getRotation() override {
|
||||
return 0;
|
||||
}
|
||||
void setOnFatalError(std::function<void()> error) override;
|
||||
void setOnPause(std::function<void(bool)> pause) override;
|
||||
|
||||
private:
|
||||
rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> _source;
|
||||
std::shared_ptr<rtc::VideoSinkInterface<webrtc::VideoFrame>> _sink;
|
||||
#ifdef TGCALLS_UWP_DESKTOP
|
||||
std::unique_ptr<UwpScreenCapturer> _screenCapturer;
|
||||
#else // TGCALLS_UWP_DESKTOP
|
||||
std::unique_ptr<DesktopCaptureSourceHelper> _desktopCapturer;
|
||||
#endif // TGCALLS_UWP_DESKTOP
|
||||
std::unique_ptr<VideoCameraCapturer> _cameraCapturer;
|
||||
std::shared_ptr<rtc::VideoSinkInterface<webrtc::VideoFrame>> _uncroppedSink;
|
||||
std::function<void(VideoState)> _stateUpdated;
|
||||
std::function<void()> _onFatalError;
|
||||
|
||||
};
|
||||
|
||||
} // namespace tgcalls
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
#include "tgcalls/platform/tdesktop/VideoCapturerTrackSource.h"
|
||||
|
||||
namespace tgcalls {
|
||||
|
||||
VideoCapturerTrackSource::VideoCapturerTrackSource()
|
||||
: VideoTrackSource(/*remote=*/false)
|
||||
, _broadcaster(std::make_shared<rtc::VideoBroadcaster>()) {
|
||||
}
|
||||
|
||||
auto VideoCapturerTrackSource::sink()
|
||||
-> std::shared_ptr<rtc::VideoSinkInterface<webrtc::VideoFrame>> {
|
||||
return _broadcaster;
|
||||
}
|
||||
|
||||
rtc::VideoSourceInterface<webrtc::VideoFrame> *VideoCapturerTrackSource::source() {
|
||||
return _broadcaster.get();
|
||||
}
|
||||
|
||||
} // namespace tgcalls
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef TGCALLS_VIDEO_CAPTURER_TRACK_SOURCE_H
|
||||
#define TGCALLS_VIDEO_CAPTURER_TRACK_SOURCE_H
|
||||
|
||||
#include "pc/video_track_source.h"
|
||||
#include "api/video/video_sink_interface.h"
|
||||
#include "media/base/video_broadcaster.h"
|
||||
|
||||
#include "VideoCameraCapturer.h"
|
||||
|
||||
namespace tgcalls {
|
||||
|
||||
class VideoCameraCapturer;
|
||||
class DesktopCapturer;
|
||||
|
||||
class VideoCapturerTrackSource : public webrtc::VideoTrackSource {
|
||||
public:
|
||||
VideoCapturerTrackSource();
|
||||
|
||||
std::shared_ptr<rtc::VideoSinkInterface<webrtc::VideoFrame>> sink();
|
||||
|
||||
private:
|
||||
rtc::VideoSourceInterface<webrtc::VideoFrame> *source() override;
|
||||
|
||||
std::shared_ptr<rtc::VideoBroadcaster> _broadcaster;
|
||||
|
||||
};
|
||||
|
||||
} // namespace tgcalls
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue