VcmCapturer.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #pragma once
  2. #include "modules/video_capture/video_capture_factory.h"
  3. #include "media/base/video_broadcaster.h"
  4. class VcmCapturer : public rtc::VideoSinkInterface<webrtc::VideoFrame>, public rtc::VideoSourceInterface<webrtc::VideoFrame> {
  5. public:
  6. static VcmCapturer* Create(const std::string & videourl, const std::map<std::string, std::string> & opts, std::unique_ptr<webrtc::VideoDecoderFactory>& videoDecoderFactory) {
  7. std::unique_ptr<VcmCapturer> vcm_capturer(new VcmCapturer());
  8. size_t width = 0;
  9. size_t height = 0;
  10. size_t fps = 0;
  11. if (opts.find("width") != opts.end()) {
  12. width = std::stoi(opts.at("width"));
  13. }
  14. if (opts.find("height") != opts.end()) {
  15. height = std::stoi(opts.at("height"));
  16. }
  17. if (opts.find("fps") != opts.end()) {
  18. fps = std::stoi(opts.at("fps"));
  19. }
  20. if (!vcm_capturer->Init(width, height, fps, videourl)) {
  21. RTC_LOG(LS_WARNING) << "Failed to create VcmCapturer(w = " << width
  22. << ", h = " << height << ", fps = " << fps
  23. << ")";
  24. return nullptr;
  25. }
  26. return vcm_capturer.release();
  27. }
  28. virtual ~VcmCapturer() {
  29. Destroy();
  30. }
  31. void OnFrame(const webrtc::VideoFrame& frame) override {
  32. m_broadcaster.OnFrame(frame);
  33. }
  34. private:
  35. VcmCapturer() : m_vcm(nullptr) {}
  36. bool Init(size_t width,
  37. size_t height,
  38. size_t target_fps,
  39. const std::string & videourl) {
  40. std::unique_ptr<webrtc::VideoCaptureModule::DeviceInfo> device_info(webrtc::VideoCaptureFactory::CreateDeviceInfo());
  41. std::string deviceId;
  42. int num_videoDevices = device_info->NumberOfDevices();
  43. RTC_LOG(LS_INFO) << "nb video devices:" << num_videoDevices;
  44. const uint32_t kSize = 256;
  45. char name[kSize] = {0};
  46. char id[kSize] = {0};
  47. if (videourl.find("videocap://") == 0) {
  48. int deviceNumber = atoi(videourl.substr(strlen("videocap://")).c_str());
  49. RTC_LOG(LS_WARNING) << "device number:" << deviceNumber;
  50. if (device_info->GetDeviceName(deviceNumber, name, kSize, id, kSize) == 0)
  51. {
  52. deviceId = id;
  53. }
  54. } else {
  55. for (int i = 0; i < num_videoDevices; ++i) {
  56. if (device_info->GetDeviceName(i, name, kSize, id, kSize) == 0)
  57. {
  58. if (videourl == name) {
  59. deviceId = id;
  60. break;
  61. }
  62. }
  63. }
  64. }
  65. if (deviceId.empty()) {
  66. RTC_LOG(LS_WARNING) << "device not found:" << videourl;
  67. Destroy();
  68. return false;
  69. }
  70. m_vcm = webrtc::VideoCaptureFactory::Create(deviceId.c_str());
  71. m_vcm->RegisterCaptureDataCallback(this);
  72. webrtc::VideoCaptureCapability capability;
  73. capability.width = static_cast<int32_t>(width);
  74. capability.height = static_cast<int32_t>(height);
  75. capability.maxFPS = static_cast<int32_t>(target_fps);
  76. capability.videoType = webrtc::VideoType::kI420;
  77. if (device_info->GetBestMatchedCapability(m_vcm->CurrentDeviceName(), capability, capability)<0) {
  78. device_info->GetCapability(m_vcm->CurrentDeviceName(), 0, capability);
  79. }
  80. if (m_vcm->StartCapture(capability) != 0) {
  81. Destroy();
  82. return false;
  83. }
  84. RTC_CHECK(m_vcm->CaptureStarted());
  85. return true;
  86. }
  87. void Destroy() {
  88. if (m_vcm) {
  89. m_vcm->StopCapture();
  90. m_vcm->DeRegisterCaptureDataCallback();
  91. m_vcm = nullptr;
  92. }
  93. }
  94. void AddOrUpdateSink(rtc::VideoSinkInterface<webrtc::VideoFrame>* sink, const rtc::VideoSinkWants& wants) override {
  95. m_broadcaster.AddOrUpdateSink(sink, wants);
  96. }
  97. void RemoveSink(rtc::VideoSinkInterface<webrtc::VideoFrame>* sink) override {
  98. m_broadcaster.RemoveSink(sink);
  99. }
  100. rtc::scoped_refptr<webrtc::VideoCaptureModule> m_vcm;
  101. rtc::VideoBroadcaster m_broadcaster;
  102. };