Nagram/TMessagesProj/jni/voip/tgcalls/VideoCaptureInterfaceImpl.cpp

147 lines
5.1 KiB
C++
Raw Normal View History

2020-10-01 01:59:32 +00:00
#include <tgnet/FileLog.h>
2020-08-14 16:58:22 +00:00
#include "VideoCaptureInterfaceImpl.h"
#include "VideoCapturerInterface.h"
#include "Manager.h"
#include "MediaManager.h"
#include "platform/PlatformInterface.h"
namespace tgcalls {
2020-10-01 01:59:32 +00:00
VideoCaptureInterfaceObject::VideoCaptureInterfaceObject(std::string deviceId, std::shared_ptr<PlatformContext> platformContext)
: _videoSource(PlatformInterface::SharedInstance()->makeVideoSource(Manager::getMediaThread(), MediaManager::getWorkerThread())) {
2020-08-14 16:58:22 +00:00
_platformContext = platformContext;
2020-10-01 01:59:32 +00:00
switchToDevice(deviceId);
2020-08-14 16:58:22 +00:00
}
VideoCaptureInterfaceObject::~VideoCaptureInterfaceObject() {
2020-08-15 21:06:36 +00:00
if (_videoCapturer && _currentUncroppedSink != nullptr) {
2020-08-14 16:58:22 +00:00
_videoCapturer->setUncroppedOutput(nullptr);
}
}
2020-10-01 01:59:32 +00:00
webrtc::VideoTrackSourceInterface *VideoCaptureInterfaceObject::source() {
return _videoSource;
}
void VideoCaptureInterfaceObject::switchToDevice(std::string deviceId) {
2020-08-14 16:58:22 +00:00
if (_videoCapturer && _currentUncroppedSink) {
_videoCapturer->setUncroppedOutput(nullptr);
}
2020-08-15 21:06:36 +00:00
if (_videoSource) {
2020-10-01 01:59:32 +00:00
//this should outlive the capturer
_videoCapturer = PlatformInterface::SharedInstance()->makeVideoCapturer(_videoSource, deviceId, [this](VideoState state) {
2020-08-15 21:06:36 +00:00
if (this->_stateUpdated) {
this->_stateUpdated(state);
}
2020-10-01 01:59:32 +00:00
}, [this](PlatformCaptureInfo info) {
if (this->_shouldBeAdaptedToReceiverAspectRate != info.shouldBeAdaptedToReceiverAspectRate) {
this->_shouldBeAdaptedToReceiverAspectRate = info.shouldBeAdaptedToReceiverAspectRate;
this->updateAspectRateAdaptation();
}
}, _platformContext, _videoCapturerResolution);
2020-08-15 21:06:36 +00:00
}
if (_videoCapturer) {
2020-10-01 01:59:32 +00:00
// if (_preferredAspectRatio > 0) {
// _videoCapturer->setPreferredCaptureAspectRatio(_preferredAspectRatio);
// }
2020-08-15 21:06:36 +00:00
if (_currentUncroppedSink) {
_videoCapturer->setUncroppedOutput(_currentUncroppedSink);
2020-08-14 16:58:22 +00:00
}
2020-08-15 21:06:36 +00:00
_videoCapturer->setState(_state);
}
2020-08-14 16:58:22 +00:00
}
void VideoCaptureInterfaceObject::setState(VideoState state) {
if (_state != state) {
_state = state;
2020-08-15 21:06:36 +00:00
if (_videoCapturer) {
_videoCapturer->setState(state);
}
2020-08-14 16:58:22 +00:00
}
}
void VideoCaptureInterfaceObject::setPreferredAspectRatio(float aspectRatio) {
2020-10-01 01:59:32 +00:00
_preferredAspectRatio = aspectRatio;
updateAspectRateAdaptation();
}
void VideoCaptureInterfaceObject::updateAspectRateAdaptation() {
if (_videoCapturer) {
if (_videoCapturerResolution.first != 0 && _videoCapturerResolution.second != 0) {
if (_preferredAspectRatio > 0.01 && _shouldBeAdaptedToReceiverAspectRate) {
float originalWidth = (float)_videoCapturerResolution.first;
float originalHeight = (float)_videoCapturerResolution.second;
float aspectRatio = _preferredAspectRatio;
float width = (originalWidth > aspectRatio * originalHeight)
? int(std::round(aspectRatio * originalHeight))
: originalWidth;
float height = (originalWidth > aspectRatio * originalHeight)
? originalHeight
: int(std::round(originalHeight / aspectRatio));
PlatformInterface::SharedInstance()->adaptVideoSource(_videoSource, (int)width, (int)height, 30);
} else {
PlatformInterface::SharedInstance()->adaptVideoSource(_videoSource, _videoCapturerResolution.first, _videoCapturerResolution.second, 30);
}
2020-08-15 21:06:36 +00:00
}
2020-10-01 01:59:32 +00:00
}
2020-08-14 16:58:22 +00:00
}
void VideoCaptureInterfaceObject::setOutput(std::shared_ptr<rtc::VideoSinkInterface<webrtc::VideoFrame>> sink) {
2020-08-15 21:06:36 +00:00
if (_videoCapturer) {
_videoCapturer->setUncroppedOutput(sink);
}
2020-08-14 16:58:22 +00:00
_currentUncroppedSink = sink;
}
void VideoCaptureInterfaceObject::setStateUpdated(std::function<void(VideoState)> stateUpdated) {
_stateUpdated = stateUpdated;
}
2020-10-01 01:59:32 +00:00
VideoCaptureInterfaceImpl::VideoCaptureInterfaceImpl(std::string deviceId, std::shared_ptr<PlatformContext> platformContext) :
_platformContext(platformContext),
_impl(Manager::getMediaThread(), [deviceId, platformContext]() {
return new VideoCaptureInterfaceObject(deviceId, platformContext);
2020-08-14 16:58:22 +00:00
}) {
}
VideoCaptureInterfaceImpl::~VideoCaptureInterfaceImpl() = default;
2020-10-01 01:59:32 +00:00
void VideoCaptureInterfaceImpl::switchToDevice(std::string deviceId) {
_impl.perform(RTC_FROM_HERE, [deviceId](VideoCaptureInterfaceObject *impl) {
impl->switchToDevice(deviceId);
2020-08-14 16:58:22 +00:00
});
}
void VideoCaptureInterfaceImpl::setState(VideoState state) {
_impl.perform(RTC_FROM_HERE, [state](VideoCaptureInterfaceObject *impl) {
impl->setState(state);
});
}
void VideoCaptureInterfaceImpl::setPreferredAspectRatio(float aspectRatio) {
_impl.perform(RTC_FROM_HERE, [aspectRatio](VideoCaptureInterfaceObject *impl) {
impl->setPreferredAspectRatio(aspectRatio);
});
}
void VideoCaptureInterfaceImpl::setOutput(std::shared_ptr<rtc::VideoSinkInterface<webrtc::VideoFrame>> sink) {
_impl.perform(RTC_FROM_HERE, [sink](VideoCaptureInterfaceObject *impl) {
impl->setOutput(sink);
});
}
2020-08-21 23:59:49 +00:00
std::shared_ptr<PlatformContext> VideoCaptureInterfaceImpl::getPlatformContext() {
return _platformContext;
}
2020-08-14 16:58:22 +00:00
ThreadLocalObject<VideoCaptureInterfaceObject> *VideoCaptureInterfaceImpl::object() {
return &_impl;
}
2020-10-01 01:59:32 +00:00
} // namespace tgcalls