blob: f5727c56485665b597dbfcebc91e9212b22380f3 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
mflodman@webrtc.orgc80d9d92012-02-06 10:11:25 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
pbos@webrtc.orgf5d4cb12013-05-17 13:44:48 +000011#include "webrtc/video_engine/vie_input_manager.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000012
pbos@webrtc.org12dc1a32013-08-05 16:22:53 +000013#include <assert.h>
niklase@google.com470e71d2011-07-07 08:21:25 +000014
pbos@webrtc.orgf5d4cb12013-05-17 13:44:48 +000015#include "webrtc/common_types.h"
andrew@webrtc.org94caca72012-10-30 21:58:00 +000016#include "webrtc/modules/video_capture/include/video_capture_factory.h"
pbos@webrtc.orgf5d4cb12013-05-17 13:44:48 +000017#include "webrtc/modules/video_coding/main/interface/video_coding.h"
18#include "webrtc/modules/video_coding/main/interface/video_coding_defines.h"
19#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
20#include "webrtc/system_wrappers/interface/rw_lock_wrapper.h"
21#include "webrtc/system_wrappers/interface/trace.h"
22#include "webrtc/video_engine/include/vie_errors.h"
23#include "webrtc/video_engine/vie_capturer.h"
24#include "webrtc/video_engine/vie_defines.h"
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000025
niklase@google.com470e71d2011-07-07 08:21:25 +000026namespace webrtc {
27
andresp@webrtc.org7707d062013-05-13 10:50:50 +000028ViEInputManager::ViEInputManager(const int engine_id, const Config& config)
29 : config_(config),
30 engine_id_(engine_id),
mflodman@webrtc.orgd32c4472011-12-22 14:17:53 +000031 map_cs_(CriticalSectionWrapper::CreateCriticalSection()),
pbos@webrtc.org927296f2013-03-08 13:12:29 +000032 device_info_cs_(CriticalSectionWrapper::CreateCriticalSection()),
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000033 vie_frame_provider_map_(),
34 capture_device_info_(NULL),
35 module_process_thread_(NULL) {
36 WEBRTC_TRACE(webrtc::kTraceMemory, webrtc::kTraceVideo, ViEId(engine_id_),
37 "%s", __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +000038
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000039 for (int idx = 0; idx < kViEMaxCaptureDevices; idx++) {
40 free_capture_device_id_[idx] = true;
41 }
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000042}
niklase@google.com470e71d2011-07-07 08:21:25 +000043
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000044ViEInputManager::~ViEInputManager() {
45 WEBRTC_TRACE(webrtc::kTraceMemory, webrtc::kTraceVideo, ViEId(engine_id_),
46 "%s", __FUNCTION__);
pbos@webrtc.org4ca7d3f2013-08-12 19:51:57 +000047 for (FrameProviderMap::iterator it = vie_frame_provider_map_.begin();
48 it != vie_frame_provider_map_.end();
49 ++it) {
50 delete it->second;
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000051 }
52
pbos@webrtc.org4ca7d3f2013-08-12 19:51:57 +000053 delete capture_device_info_;
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000054}
55void ViEInputManager::SetModuleProcessThread(
mflodman@webrtc.org8baed512012-06-21 12:11:50 +000056 ProcessThread* module_process_thread) {
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000057 assert(!module_process_thread_);
mflodman@webrtc.org8baed512012-06-21 12:11:50 +000058 module_process_thread_ = module_process_thread;
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000059}
60
61int ViEInputManager::NumberOfCaptureDevices() {
62 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_), "%s",
niklase@google.com470e71d2011-07-07 08:21:25 +000063 __FUNCTION__);
pbos@webrtc.org927296f2013-03-08 13:12:29 +000064 CriticalSectionScoped cs(device_info_cs_.get());
65 if (capture_device_info_ == NULL)
66 capture_device_info_ = VideoCaptureFactory::CreateDeviceInfo(
67 ViEModuleId(engine_id_));
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000068 assert(capture_device_info_);
69 return capture_device_info_->NumberOfDevices();
niklase@google.com470e71d2011-07-07 08:21:25 +000070}
71
pbos@webrtc.orgb238d122013-04-09 13:41:51 +000072int ViEInputManager::GetDeviceName(uint32_t device_number,
leozwang@webrtc.org1745e932012-03-01 16:30:40 +000073 char* device_nameUTF8,
pbos@webrtc.orgb238d122013-04-09 13:41:51 +000074 uint32_t device_name_length,
leozwang@webrtc.org1745e932012-03-01 16:30:40 +000075 char* device_unique_idUTF8,
pbos@webrtc.orgb238d122013-04-09 13:41:51 +000076 uint32_t device_unique_idUTF8Length) {
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000077 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_),
78 "%s(device_number: %d)", __FUNCTION__, device_number);
pbos@webrtc.org927296f2013-03-08 13:12:29 +000079 CriticalSectionScoped cs(device_info_cs_.get());
80 if (capture_device_info_ == NULL)
81 capture_device_info_ = VideoCaptureFactory::CreateDeviceInfo(
82 ViEModuleId(engine_id_));
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000083 assert(capture_device_info_);
84 return capture_device_info_->GetDeviceName(device_number, device_nameUTF8,
85 device_name_length,
86 device_unique_idUTF8,
87 device_unique_idUTF8Length);
niklase@google.com470e71d2011-07-07 08:21:25 +000088}
89
niklase@google.com470e71d2011-07-07 08:21:25 +000090int ViEInputManager::NumberOfCaptureCapabilities(
leozwang@webrtc.org1745e932012-03-01 16:30:40 +000091 const char* device_unique_idUTF8) {
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000092 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_), "%s",
niklase@google.com470e71d2011-07-07 08:21:25 +000093 __FUNCTION__);
pbos@webrtc.org927296f2013-03-08 13:12:29 +000094 CriticalSectionScoped cs(device_info_cs_.get());
95 if (capture_device_info_ == NULL)
96 capture_device_info_ = VideoCaptureFactory::CreateDeviceInfo(
97 ViEModuleId(engine_id_));
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000098 assert(capture_device_info_);
99 return capture_device_info_->NumberOfCapabilities(device_unique_idUTF8);
niklase@google.com470e71d2011-07-07 08:21:25 +0000100}
101
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000102int ViEInputManager::GetCaptureCapability(
leozwang@webrtc.org1745e932012-03-01 16:30:40 +0000103 const char* device_unique_idUTF8,
pbos@webrtc.orgb238d122013-04-09 13:41:51 +0000104 const uint32_t device_capability_number,
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000105 CaptureCapability& capability) {
106 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_),
107 "%s(device_unique_idUTF8: %s, device_capability_number: %d)",
108 __FUNCTION__, device_unique_idUTF8, device_capability_number);
pbos@webrtc.org927296f2013-03-08 13:12:29 +0000109 CriticalSectionScoped cs(device_info_cs_.get());
110 if (capture_device_info_ == NULL)
111 capture_device_info_ = VideoCaptureFactory::CreateDeviceInfo(
112 ViEModuleId(engine_id_));
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000113 assert(capture_device_info_);
114 VideoCaptureCapability module_capability;
115 int result = capture_device_info_->GetCapability(device_unique_idUTF8,
116 device_capability_number,
117 module_capability);
118 if (result != 0)
niklase@google.com470e71d2011-07-07 08:21:25 +0000119 return result;
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000120
121 // Copy from module type to public type.
122 capability.expectedCaptureDelay = module_capability.expectedCaptureDelay;
123 capability.height = module_capability.height;
124 capability.width = module_capability.width;
125 capability.interlaced = module_capability.interlaced;
126 capability.rawType = module_capability.rawType;
127 capability.codecType = module_capability.codecType;
128 capability.maxFPS = module_capability.maxFPS;
129 return result;
niklase@google.com470e71d2011-07-07 08:21:25 +0000130}
131
leozwang@webrtc.org1745e932012-03-01 16:30:40 +0000132int ViEInputManager::GetOrientation(const char* device_unique_idUTF8,
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000133 RotateCapturedFrame& orientation) {
134 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_),
135 "%s(device_unique_idUTF8: %s,)", __FUNCTION__,
136 device_unique_idUTF8);
pbos@webrtc.org927296f2013-03-08 13:12:29 +0000137 CriticalSectionScoped cs(device_info_cs_.get());
138 if (capture_device_info_ == NULL)
139 capture_device_info_ = VideoCaptureFactory::CreateDeviceInfo(
140 ViEModuleId(engine_id_));
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000141 assert(capture_device_info_);
142 VideoCaptureRotation module_orientation;
143 int result = capture_device_info_->GetOrientation(device_unique_idUTF8,
144 module_orientation);
145 // Copy from module type to public type.
146 switch (module_orientation) {
147 case kCameraRotate0:
148 orientation = RotateCapturedFrame_0;
149 break;
150 case kCameraRotate90:
151 orientation = RotateCapturedFrame_90;
152 break;
153 case kCameraRotate180:
154 orientation = RotateCapturedFrame_180;
155 break;
156 case kCameraRotate270:
157 orientation = RotateCapturedFrame_270;
158 break;
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000159 }
160 return result;
niklase@google.com470e71d2011-07-07 08:21:25 +0000161}
162
niklase@google.com470e71d2011-07-07 08:21:25 +0000163int ViEInputManager::DisplayCaptureSettingsDialogBox(
leozwang@webrtc.org1745e932012-03-01 16:30:40 +0000164 const char* device_unique_idUTF8,
165 const char* dialog_titleUTF8,
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000166 void* parent_window,
pbos@webrtc.orgb238d122013-04-09 13:41:51 +0000167 uint32_t positionX,
168 uint32_t positionY) {
pbos@webrtc.org927296f2013-03-08 13:12:29 +0000169 CriticalSectionScoped cs(device_info_cs_.get());
170 if (capture_device_info_ == NULL)
171 capture_device_info_ = VideoCaptureFactory::CreateDeviceInfo(
172 ViEModuleId(engine_id_));
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000173 assert(capture_device_info_);
174 return capture_device_info_->DisplayCaptureSettingsDialogBox(
175 device_unique_idUTF8, dialog_titleUTF8, parent_window, positionX,
176 positionY);
niklase@google.com470e71d2011-07-07 08:21:25 +0000177}
178
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000179int ViEInputManager::CreateCaptureDevice(
leozwang@webrtc.org1745e932012-03-01 16:30:40 +0000180 const char* device_unique_idUTF8,
pbos@webrtc.orgb238d122013-04-09 13:41:51 +0000181 const uint32_t device_unique_idUTF8Length,
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000182 int& capture_id) {
183 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_),
184 "%s(device_unique_id: %s)", __FUNCTION__, device_unique_idUTF8);
mflodman@webrtc.orgd32c4472011-12-22 14:17:53 +0000185 CriticalSectionScoped cs(map_cs_.get());
niklase@google.com470e71d2011-07-07 08:21:25 +0000186
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000187 // Make sure the device is not already allocated.
pbos@webrtc.org4ca7d3f2013-08-12 19:51:57 +0000188 for (FrameProviderMap::iterator it = vie_frame_provider_map_.begin();
189 it != vie_frame_provider_map_.end();
190 ++it) {
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000191 // Make sure this is a capture device.
pbos@webrtc.org4ca7d3f2013-08-12 19:51:57 +0000192 if (it->first >= kViECaptureIdBase && it->first <= kViECaptureIdMax) {
193 ViECapturer* vie_capture = static_cast<ViECapturer*>(it->second);
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000194 assert(vie_capture);
195 // TODO(mflodman) Can we change input to avoid this cast?
196 const char* device_name =
197 reinterpret_cast<const char*>(vie_capture->CurrentDeviceName());
pbos@webrtc.org4ca7d3f2013-08-12 19:51:57 +0000198 if (strncmp(device_name, device_unique_idUTF8,
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000199 strlen(device_name)) == 0) {
200 return kViECaptureDeviceAlreadyAllocated;
201 }
202 }
203 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000204
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000205 // Make sure the device name is valid.
206 bool found_device = false;
pbos@webrtc.org927296f2013-03-08 13:12:29 +0000207 CriticalSectionScoped cs_devinfo(device_info_cs_.get());
208 if (capture_device_info_ == NULL)
209 capture_device_info_ = VideoCaptureFactory::CreateDeviceInfo(
210 ViEModuleId(engine_id_));
211 assert(capture_device_info_);
pbos@webrtc.orgb238d122013-04-09 13:41:51 +0000212 for (uint32_t device_index = 0;
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000213 device_index < capture_device_info_->NumberOfDevices(); ++device_index) {
214 if (device_unique_idUTF8Length > kVideoCaptureUniqueNameLength) {
215 // User's string length is longer than the max.
216 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000217 }
218
leozwang@webrtc.org1745e932012-03-01 16:30:40 +0000219 char found_name[kVideoCaptureDeviceNameLength] = "";
220 char found_unique_name[kVideoCaptureUniqueNameLength] = "";
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000221 capture_device_info_->GetDeviceName(device_index, found_name,
222 kVideoCaptureDeviceNameLength,
223 found_unique_name,
224 kVideoCaptureUniqueNameLength);
225
226 // TODO(mflodman) Can we change input to avoid this cast?
227 const char* cast_id = reinterpret_cast<const char*>(device_unique_idUTF8);
228 if (strncmp(cast_id, reinterpret_cast<const char*>(found_unique_name),
229 strlen(cast_id)) == 0) {
230 WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideo, ViEId(engine_id_),
231 "%s:%d Capture device was found by unique ID: %s. Returning",
232 __FUNCTION__, __LINE__, device_unique_idUTF8);
233 found_device = true;
234 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000235 }
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000236 }
237 if (!found_device) {
238 WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideo, ViEId(engine_id_),
239 "%s:%d Capture device NOT found by unique ID: %s. Returning",
240 __FUNCTION__, __LINE__, device_unique_idUTF8);
241 return kViECaptureDeviceDoesNotExist;
242 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000243
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000244 int newcapture_id = 0;
mflodman@webrtc.org8baed512012-06-21 12:11:50 +0000245 if (GetFreeCaptureId(&newcapture_id) == false) {
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000246 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_),
247 "%s: Maximum supported number of capture devices already in "
248 "use", __FUNCTION__);
249 return kViECaptureDeviceMaxNoDevicesAllocated;
250 }
251 ViECapturer* vie_capture = ViECapturer::CreateViECapture(
andresp@webrtc.org7707d062013-05-13 10:50:50 +0000252 newcapture_id, engine_id_, config_, device_unique_idUTF8,
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000253 device_unique_idUTF8Length, *module_process_thread_);
254 if (!vie_capture) {
255 ReturnCaptureId(newcapture_id);
256 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_),
257 "%s: Could not create capture module for %s", __FUNCTION__,
258 device_unique_idUTF8);
259 return kViECaptureDeviceUnknownError;
260 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000261
pbos@webrtc.org4ca7d3f2013-08-12 19:51:57 +0000262 vie_frame_provider_map_[newcapture_id] = vie_capture;
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000263 capture_id = newcapture_id;
264 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_),
265 "%s(device_unique_id: %s, capture_id: %d)", __FUNCTION__,
266 device_unique_idUTF8, capture_id);
267 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000268}
269
mflodman@webrtc.org8baed512012-06-21 12:11:50 +0000270int ViEInputManager::CreateCaptureDevice(VideoCaptureModule* capture_module,
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000271 int& capture_id) {
272 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_), "%s",
niklase@google.com470e71d2011-07-07 08:21:25 +0000273 __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +0000274
mflodman@webrtc.orgd32c4472011-12-22 14:17:53 +0000275 CriticalSectionScoped cs(map_cs_.get());
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000276 int newcapture_id = 0;
mflodman@webrtc.org8baed512012-06-21 12:11:50 +0000277 if (!GetFreeCaptureId(&newcapture_id)) {
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000278 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_),
279 "%s: Maximum supported number of capture devices already in "
280 "use", __FUNCTION__);
281 return kViECaptureDeviceMaxNoDevicesAllocated;
282 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000283
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000284 ViECapturer* vie_capture = ViECapturer::CreateViECapture(
andresp@webrtc.org7707d062013-05-13 10:50:50 +0000285 newcapture_id, engine_id_, config_,
286 capture_module, *module_process_thread_);
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000287 if (!vie_capture) {
288 ReturnCaptureId(newcapture_id);
289 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_),
290 "%s: Could attach capture module.", __FUNCTION__);
291 return kViECaptureDeviceUnknownError;
292 }
pbos@webrtc.org4ca7d3f2013-08-12 19:51:57 +0000293 vie_frame_provider_map_[newcapture_id] = vie_capture;
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000294 capture_id = newcapture_id;
295 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_),
296 "%s, capture_id: %d", __FUNCTION__, capture_id);
297 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000298}
299
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000300int ViEInputManager::DestroyCaptureDevice(const int capture_id) {
301 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_),
302 "%s(capture_id: %d)", __FUNCTION__, capture_id);
303 ViECapturer* vie_capture = NULL;
304 {
305 // We need exclusive access to the object to delete it.
306 // Take this write lock first since the read lock is taken before map_cs_.
mflodman@webrtc.orgcee447a2012-06-28 07:29:46 +0000307 ViEManagerWriteScoped wl(this);
mflodman@webrtc.orgd32c4472011-12-22 14:17:53 +0000308 CriticalSectionScoped cs(map_cs_.get());
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000309
310 vie_capture = ViECapturePtr(capture_id);
311 if (!vie_capture) {
312 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_),
313 "%s(capture_id: %d) - No such capture device id",
314 __FUNCTION__, capture_id);
315 return -1;
316 }
pbos@webrtc.orgb238d122013-04-09 13:41:51 +0000317 uint32_t num_callbacks =
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000318 vie_capture->NumberOfRegisteredFrameCallbacks();
319 if (num_callbacks > 0) {
320 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideo,
321 ViEId(engine_id_), "%s(capture_id: %d) - %u registered "
322 "callbacks when destroying capture device",
323 __FUNCTION__, capture_id, num_callbacks);
324 }
pbos@webrtc.org4ca7d3f2013-08-12 19:51:57 +0000325 vie_frame_provider_map_.erase(capture_id);
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000326 ReturnCaptureId(capture_id);
327 // Leave cs before deleting the capture object. This is because deleting the
328 // object might cause deletions of renderers so we prefer to not have a lock
329 // at that time.
330 }
331 delete vie_capture;
332 return 0;
333}
334
335int ViEInputManager::CreateExternalCaptureDevice(
336 ViEExternalCapture*& external_capture,
337 int& capture_id) {
338 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_), "%s",
339 __FUNCTION__);
mflodman@webrtc.orgd32c4472011-12-22 14:17:53 +0000340 CriticalSectionScoped cs(map_cs_.get());
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000341
342 int newcapture_id = 0;
mflodman@webrtc.org8baed512012-06-21 12:11:50 +0000343 if (GetFreeCaptureId(&newcapture_id) == false) {
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000344 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_),
345 "%s: Maximum supported number of capture devices already in "
346 "use", __FUNCTION__);
347 return kViECaptureDeviceMaxNoDevicesAllocated;
348 }
349
350 ViECapturer* vie_capture = ViECapturer::CreateViECapture(
andresp@webrtc.org7707d062013-05-13 10:50:50 +0000351 newcapture_id, engine_id_, config_, NULL, 0, *module_process_thread_);
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000352 if (!vie_capture) {
353 ReturnCaptureId(newcapture_id);
354 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_),
355 "%s: Could not create capture module for external capture.",
356 __FUNCTION__);
357 return kViECaptureDeviceUnknownError;
358 }
359
pbos@webrtc.org4ca7d3f2013-08-12 19:51:57 +0000360 vie_frame_provider_map_[newcapture_id] = vie_capture;
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000361 capture_id = newcapture_id;
362 external_capture = vie_capture;
363 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_),
364 "%s, capture_id: %d)", __FUNCTION__, capture_id);
365 return 0;
366}
367
mflodman@webrtc.org8baed512012-06-21 12:11:50 +0000368bool ViEInputManager::GetFreeCaptureId(int* freecapture_id) {
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000369 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_), "%s",
370 __FUNCTION__);
371 for (int id = 0; id < kViEMaxCaptureDevices; id++) {
372 if (free_capture_device_id_[id]) {
373 // We found a free capture device id.
374 free_capture_device_id_[id] = false;
mflodman@webrtc.org8baed512012-06-21 12:11:50 +0000375 *freecapture_id = id + kViECaptureIdBase;
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000376 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_),
mflodman@webrtc.org8baed512012-06-21 12:11:50 +0000377 "%s: new id: %d", __FUNCTION__, *freecapture_id);
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000378 return true;
379 }
380 }
381 return false;
382}
niklase@google.com470e71d2011-07-07 08:21:25 +0000383
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000384void ViEInputManager::ReturnCaptureId(int capture_id) {
385 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_),
386 "%s(%d)", __FUNCTION__, capture_id);
mflodman@webrtc.orgd32c4472011-12-22 14:17:53 +0000387 CriticalSectionScoped cs(map_cs_.get());
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000388 if (capture_id >= kViECaptureIdBase &&
389 capture_id < kViEMaxCaptureDevices + kViECaptureIdBase) {
390 free_capture_device_id_[capture_id - kViECaptureIdBase] = true;
391 }
392 return;
393}
niklase@google.com470e71d2011-07-07 08:21:25 +0000394
niklase@google.com470e71d2011-07-07 08:21:25 +0000395ViEFrameProviderBase* ViEInputManager::ViEFrameProvider(
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000396 const ViEFrameCallback* capture_observer) const {
397 assert(capture_observer);
mflodman@webrtc.orgd32c4472011-12-22 14:17:53 +0000398 CriticalSectionScoped cs(map_cs_.get());
niklase@google.com470e71d2011-07-07 08:21:25 +0000399
pbos@webrtc.org4ca7d3f2013-08-12 19:51:57 +0000400 for (FrameProviderMap::const_iterator it = vie_frame_provider_map_.begin();
401 it != vie_frame_provider_map_.end();
402 ++it) {
403 if (it->second->IsFrameCallbackRegistered(capture_observer))
404 return it->second;
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000405 }
pbos@webrtc.org4ca7d3f2013-08-12 19:51:57 +0000406
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000407 // No capture device set for this channel.
408 return NULL;
409}
410
411ViEFrameProviderBase* ViEInputManager::ViEFrameProvider(int provider_id) const {
mflodman@webrtc.orgd32c4472011-12-22 14:17:53 +0000412 CriticalSectionScoped cs(map_cs_.get());
pbos@webrtc.org4ca7d3f2013-08-12 19:51:57 +0000413
414 FrameProviderMap::const_iterator it =
415 vie_frame_provider_map_.find(provider_id);
416 if (it == vie_frame_provider_map_.end())
niklase@google.com470e71d2011-07-07 08:21:25 +0000417 return NULL;
pbos@webrtc.org4ca7d3f2013-08-12 19:51:57 +0000418 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000419}
420
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000421ViECapturer* ViEInputManager::ViECapturePtr(int capture_id) const {
422 if (!(capture_id >= kViECaptureIdBase &&
423 capture_id <= kViECaptureIdBase + kViEMaxCaptureDevices))
424 return NULL;
niklase@google.com470e71d2011-07-07 08:21:25 +0000425
pbos@webrtc.org4ca7d3f2013-08-12 19:51:57 +0000426 return static_cast<ViECapturer*>(ViEFrameProvider(capture_id));
niklase@google.com470e71d2011-07-07 08:21:25 +0000427}
428
niklase@google.com470e71d2011-07-07 08:21:25 +0000429ViEInputManagerScoped::ViEInputManagerScoped(
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000430 const ViEInputManager& vie_input_manager)
431 : ViEManagerScopedBase(vie_input_manager) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000432}
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000433
434ViECapturer* ViEInputManagerScoped::Capture(int capture_id) const {
435 return static_cast<const ViEInputManager*>(vie_manager_)->ViECapturePtr(
436 capture_id);
niklase@google.com470e71d2011-07-07 08:21:25 +0000437}
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000438
niklase@google.com470e71d2011-07-07 08:21:25 +0000439ViEFrameProviderBase* ViEInputManagerScoped::FrameProvider(
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000440 const ViEFrameCallback* capture_observer) const {
441 return static_cast<const ViEInputManager*>(vie_manager_)->ViEFrameProvider(
442 capture_observer);
niklase@google.com470e71d2011-07-07 08:21:25 +0000443}
444
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000445ViEFrameProviderBase* ViEInputManagerScoped::FrameProvider(
446 int provider_id) const {
447 return static_cast<const ViEInputManager*>(vie_manager_)->ViEFrameProvider(
448 provider_id);
niklase@google.com470e71d2011-07-07 08:21:25 +0000449}
450
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000451} // namespace webrtc