VideoCaptureInterfaceImpl.cpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. #include "VideoCaptureInterfaceImpl.h"
  2. #include "VideoCapturerInterface.h"
  3. #include "Manager.h"
  4. #include "MediaManager.h"
  5. #include "platform/PlatformInterface.h"
  6. #include "StaticThreads.h"
  7. namespace tgcalls {
  8. VideoCaptureInterfaceObject::VideoCaptureInterfaceObject(std::string deviceId, bool isScreenCapture, std::shared_ptr<PlatformContext> platformContext, Threads &threads)
  9. : _videoSource(PlatformInterface::SharedInstance()->makeVideoSource(threads.getMediaThread(), threads.getWorkerThread())) {
  10. _platformContext = platformContext;
  11. switchToDevice(deviceId, isScreenCapture);
  12. }
  13. VideoCaptureInterfaceObject::~VideoCaptureInterfaceObject() {
  14. if (_videoCapturer) {
  15. _videoCapturer->setUncroppedOutput(nullptr);
  16. }
  17. }
  18. webrtc::scoped_refptr<webrtc::VideoTrackSourceInterface> VideoCaptureInterfaceObject::source() {
  19. return _videoSource;
  20. }
  21. int VideoCaptureInterfaceObject::getRotation() {
  22. if (_videoCapturer) {
  23. return _videoCapturer->getRotation();
  24. } else {
  25. return 0;
  26. }
  27. }
  28. bool VideoCaptureInterfaceObject::isScreenCapture() {
  29. return _isScreenCapture;
  30. }
  31. void VideoCaptureInterfaceObject::switchToDevice(std::string deviceId, bool isScreenCapture) {
  32. if (_videoCapturer) {
  33. _videoCapturer->setUncroppedOutput(nullptr);
  34. }
  35. _isScreenCapture = isScreenCapture;
  36. if (_videoSource) {
  37. //this should outlive the capturer
  38. _videoCapturer = nullptr;
  39. _videoCapturer = PlatformInterface::SharedInstance()->makeVideoCapturer(_videoSource, deviceId, [this](VideoState state) {
  40. if (this->_stateUpdated) {
  41. this->_stateUpdated(state);
  42. }
  43. if (this->_onIsActiveUpdated) {
  44. switch (state) {
  45. case VideoState::Active: {
  46. this->_onIsActiveUpdated(true);
  47. break;
  48. }
  49. default: {
  50. this->_onIsActiveUpdated(false);
  51. break;
  52. }
  53. }
  54. }
  55. }, [this](PlatformCaptureInfo info) {
  56. if (this->_shouldBeAdaptedToReceiverAspectRate != info.shouldBeAdaptedToReceiverAspectRate) {
  57. this->_shouldBeAdaptedToReceiverAspectRate = info.shouldBeAdaptedToReceiverAspectRate;
  58. }
  59. if (this->_rotationUpdated) {
  60. this->_rotationUpdated(info.rotation);
  61. }
  62. this->updateAspectRateAdaptation();
  63. }, _platformContext, _videoCapturerResolution);
  64. }
  65. if (_videoCapturer) {
  66. if (_preferredAspectRatio > 0) {
  67. _videoCapturer->setPreferredCaptureAspectRatio(_preferredAspectRatio);
  68. }
  69. if (const auto currentUncroppedSink = _currentUncroppedSink.lock()) {
  70. _videoCapturer->setUncroppedOutput(currentUncroppedSink);
  71. }
  72. if (_onFatalError) {
  73. _videoCapturer->setOnFatalError(_onFatalError);
  74. }
  75. if (_onPause) {
  76. _videoCapturer->setOnPause(_onPause);
  77. }
  78. _videoCapturer->setState(_state);
  79. }
  80. }
  81. void VideoCaptureInterfaceObject::withNativeImplementation(std::function<void(void *)> completion) {
  82. if (_videoCapturer) {
  83. _videoCapturer->withNativeImplementation(completion);
  84. } else {
  85. completion(nullptr);
  86. }
  87. }
  88. void VideoCaptureInterfaceObject::setState(VideoState state) {
  89. if (_state != state) {
  90. _state = state;
  91. if (_videoCapturer) {
  92. _videoCapturer->setState(state);
  93. }
  94. }
  95. }
  96. void VideoCaptureInterfaceObject::setPreferredAspectRatio(float aspectRatio) {
  97. _preferredAspectRatio = aspectRatio;
  98. updateAspectRateAdaptation();
  99. }
  100. void VideoCaptureInterfaceObject::updateAspectRateAdaptation() {
  101. if (_videoCapturer) {
  102. if (_videoCapturerResolution.first != 0 && _videoCapturerResolution.second != 0) {
  103. if (_preferredAspectRatio > 0.01 && _shouldBeAdaptedToReceiverAspectRate) {
  104. float originalWidth = (float)_videoCapturerResolution.first;
  105. float originalHeight = (float)_videoCapturerResolution.second;
  106. float aspectRatio = _preferredAspectRatio;
  107. float width = (originalWidth > aspectRatio * originalHeight)
  108. ? int(std::round(aspectRatio * originalHeight))
  109. : originalWidth;
  110. float height = (originalWidth > aspectRatio * originalHeight)
  111. ? originalHeight
  112. : int(std::round(originalHeight / aspectRatio));
  113. PlatformInterface::SharedInstance()->adaptVideoSource(_videoSource, (int)width, (int)height, 25);
  114. } else {
  115. PlatformInterface::SharedInstance()->adaptVideoSource(_videoSource, _videoCapturerResolution.first, _videoCapturerResolution.second, 25);
  116. }
  117. }
  118. }
  119. }
  120. void VideoCaptureInterfaceObject::setOutput(std::shared_ptr<rtc::VideoSinkInterface<webrtc::VideoFrame>> sink) {
  121. if (_videoCapturer) {
  122. _videoCapturer->setUncroppedOutput(sink);
  123. }
  124. _currentUncroppedSink = sink;
  125. }
  126. void VideoCaptureInterfaceObject::setOnFatalError(std::function<void()> error) {
  127. if (_videoCapturer) {
  128. _videoCapturer->setOnFatalError(error);
  129. }
  130. _onFatalError = error;
  131. }
  132. void VideoCaptureInterfaceObject::setOnPause(std::function<void(bool)> pause) {
  133. if (_videoCapturer) {
  134. _videoCapturer->setOnPause(pause);
  135. }
  136. _onPause = pause;
  137. }
  138. void VideoCaptureInterfaceObject::setOnIsActiveUpdated(std::function<void(bool)> onIsActiveUpdated) {
  139. _onIsActiveUpdated = onIsActiveUpdated;
  140. }
  141. void VideoCaptureInterfaceObject::setStateUpdated(std::function<void(VideoState)> stateUpdated) {
  142. _stateUpdated = stateUpdated;
  143. }
  144. void VideoCaptureInterfaceObject::setRotationUpdated(std::function<void(int)> rotationUpdated) {
  145. _rotationUpdated = rotationUpdated;
  146. }
  147. VideoCaptureInterfaceImpl::VideoCaptureInterfaceImpl(std::string deviceId, bool isScreenCapture, std::shared_ptr<PlatformContext> platformContext, std::shared_ptr<Threads> threads) :
  148. _impl(threads->getMediaThread(), [deviceId, isScreenCapture, platformContext, threads]() {
  149. return std::make_shared<VideoCaptureInterfaceObject>(deviceId, isScreenCapture, platformContext, *threads);
  150. }) {
  151. }
  152. VideoCaptureInterfaceImpl::~VideoCaptureInterfaceImpl() = default;
  153. void VideoCaptureInterfaceImpl::switchToDevice(std::string deviceId, bool isScreenCapture) {
  154. _impl.perform([deviceId, isScreenCapture](VideoCaptureInterfaceObject *impl) {
  155. impl->switchToDevice(deviceId, isScreenCapture);
  156. });
  157. }
  158. void VideoCaptureInterfaceImpl::withNativeImplementation(std::function<void(void *)> completion) {
  159. _impl.perform([completion](VideoCaptureInterfaceObject *impl) {
  160. impl->withNativeImplementation(completion);
  161. });
  162. }
  163. void VideoCaptureInterfaceImpl::setState(VideoState state) {
  164. _impl.perform([state](VideoCaptureInterfaceObject *impl) {
  165. impl->setState(state);
  166. });
  167. }
  168. void VideoCaptureInterfaceImpl::setPreferredAspectRatio(float aspectRatio) {
  169. _impl.perform([aspectRatio](VideoCaptureInterfaceObject *impl) {
  170. impl->setPreferredAspectRatio(aspectRatio);
  171. });
  172. }
  173. void VideoCaptureInterfaceImpl::setOnFatalError(std::function<void()> error) {
  174. _impl.perform([error](VideoCaptureInterfaceObject *impl) {
  175. impl->setOnFatalError(error);
  176. });
  177. }
  178. void VideoCaptureInterfaceImpl::setOnPause(std::function<void(bool)> pause) {
  179. _impl.perform([pause](VideoCaptureInterfaceObject *impl) {
  180. impl->setOnPause(pause);
  181. });
  182. }
  183. void VideoCaptureInterfaceImpl::setOnIsActiveUpdated(std::function<void(bool)> onIsActiveUpdated) {
  184. _impl.perform([onIsActiveUpdated](VideoCaptureInterfaceObject *impl) {
  185. impl->setOnIsActiveUpdated(onIsActiveUpdated);
  186. });
  187. }
  188. void VideoCaptureInterfaceImpl::setOutput(std::shared_ptr<rtc::VideoSinkInterface<webrtc::VideoFrame>> sink) {
  189. _impl.perform([sink](VideoCaptureInterfaceObject *impl) {
  190. impl->setOutput(sink);
  191. });
  192. }
  193. ThreadLocalObject<VideoCaptureInterfaceObject> *VideoCaptureInterfaceImpl::object() {
  194. return &_impl;
  195. }
  196. } // namespace tgcalls