blob: 80ace3d5a2a45736d7bbc7eea50f89ed0e332b58 [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"
mflodman@webrtc.org5574dac2014-04-07 10:56:31 +000020#include "webrtc/system_wrappers/interface/logging.h"
pbos@webrtc.orgf5d4cb12013-05-17 13:44:48 +000021#include "webrtc/system_wrappers/interface/rw_lock_wrapper.h"
22#include "webrtc/system_wrappers/interface/trace.h"
23#include "webrtc/video_engine/include/vie_errors.h"
24#include "webrtc/video_engine/vie_capturer.h"
25#include "webrtc/video_engine/vie_defines.h"
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000026
niklase@google.com470e71d2011-07-07 08:21:25 +000027namespace webrtc {
28
andresp@webrtc.org7707d062013-05-13 10:50:50 +000029ViEInputManager::ViEInputManager(const int engine_id, const Config& config)
30 : config_(config),
31 engine_id_(engine_id),
mflodman@webrtc.orgd32c4472011-12-22 14:17:53 +000032 map_cs_(CriticalSectionWrapper::CreateCriticalSection()),
pbos@webrtc.org927296f2013-03-08 13:12:29 +000033 device_info_cs_(CriticalSectionWrapper::CreateCriticalSection()),
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000034 vie_frame_provider_map_(),
35 capture_device_info_(NULL),
36 module_process_thread_(NULL) {
37 WEBRTC_TRACE(webrtc::kTraceMemory, webrtc::kTraceVideo, ViEId(engine_id_),
38 "%s", __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +000039
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000040 for (int idx = 0; idx < kViEMaxCaptureDevices; idx++) {
41 free_capture_device_id_[idx] = true;
42 }
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000043}
niklase@google.com470e71d2011-07-07 08:21:25 +000044
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000045ViEInputManager::~ViEInputManager() {
46 WEBRTC_TRACE(webrtc::kTraceMemory, webrtc::kTraceVideo, ViEId(engine_id_),
47 "%s", __FUNCTION__);
pbos@webrtc.org4ca7d3f2013-08-12 19:51:57 +000048 for (FrameProviderMap::iterator it = vie_frame_provider_map_.begin();
49 it != vie_frame_provider_map_.end();
50 ++it) {
51 delete it->second;
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000052 }
53
pbos@webrtc.org4ca7d3f2013-08-12 19:51:57 +000054 delete capture_device_info_;
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000055}
56void ViEInputManager::SetModuleProcessThread(
mflodman@webrtc.org8baed512012-06-21 12:11:50 +000057 ProcessThread* module_process_thread) {
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000058 assert(!module_process_thread_);
mflodman@webrtc.org8baed512012-06-21 12:11:50 +000059 module_process_thread_ = module_process_thread;
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000060}
61
62int ViEInputManager::NumberOfCaptureDevices() {
63 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_), "%s",
niklase@google.com470e71d2011-07-07 08:21:25 +000064 __FUNCTION__);
pbos@webrtc.org927296f2013-03-08 13:12:29 +000065 CriticalSectionScoped cs(device_info_cs_.get());
66 if (capture_device_info_ == NULL)
67 capture_device_info_ = VideoCaptureFactory::CreateDeviceInfo(
68 ViEModuleId(engine_id_));
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000069 assert(capture_device_info_);
70 return capture_device_info_->NumberOfDevices();
niklase@google.com470e71d2011-07-07 08:21:25 +000071}
72
pbos@webrtc.orgb238d122013-04-09 13:41:51 +000073int ViEInputManager::GetDeviceName(uint32_t device_number,
leozwang@webrtc.org1745e932012-03-01 16:30:40 +000074 char* device_nameUTF8,
pbos@webrtc.orgb238d122013-04-09 13:41:51 +000075 uint32_t device_name_length,
leozwang@webrtc.org1745e932012-03-01 16:30:40 +000076 char* device_unique_idUTF8,
pbos@webrtc.orgb238d122013-04-09 13:41:51 +000077 uint32_t device_unique_idUTF8Length) {
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000078 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_),
79 "%s(device_number: %d)", __FUNCTION__, device_number);
pbos@webrtc.org927296f2013-03-08 13:12:29 +000080 CriticalSectionScoped cs(device_info_cs_.get());
81 if (capture_device_info_ == NULL)
82 capture_device_info_ = VideoCaptureFactory::CreateDeviceInfo(
83 ViEModuleId(engine_id_));
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000084 assert(capture_device_info_);
85 return capture_device_info_->GetDeviceName(device_number, device_nameUTF8,
86 device_name_length,
87 device_unique_idUTF8,
88 device_unique_idUTF8Length);
niklase@google.com470e71d2011-07-07 08:21:25 +000089}
90
niklase@google.com470e71d2011-07-07 08:21:25 +000091int ViEInputManager::NumberOfCaptureCapabilities(
leozwang@webrtc.org1745e932012-03-01 16:30:40 +000092 const char* device_unique_idUTF8) {
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000093 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_), "%s",
niklase@google.com470e71d2011-07-07 08:21:25 +000094 __FUNCTION__);
pbos@webrtc.org927296f2013-03-08 13:12:29 +000095 CriticalSectionScoped cs(device_info_cs_.get());
96 if (capture_device_info_ == NULL)
97 capture_device_info_ = VideoCaptureFactory::CreateDeviceInfo(
98 ViEModuleId(engine_id_));
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000099 assert(capture_device_info_);
100 return capture_device_info_->NumberOfCapabilities(device_unique_idUTF8);
niklase@google.com470e71d2011-07-07 08:21:25 +0000101}
102
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000103int ViEInputManager::GetCaptureCapability(
leozwang@webrtc.org1745e932012-03-01 16:30:40 +0000104 const char* device_unique_idUTF8,
pbos@webrtc.orgb238d122013-04-09 13:41:51 +0000105 const uint32_t device_capability_number,
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000106 CaptureCapability& capability) {
107 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_),
108 "%s(device_unique_idUTF8: %s, device_capability_number: %d)",
109 __FUNCTION__, device_unique_idUTF8, device_capability_number);
pbos@webrtc.org927296f2013-03-08 13:12:29 +0000110 CriticalSectionScoped cs(device_info_cs_.get());
111 if (capture_device_info_ == NULL)
112 capture_device_info_ = VideoCaptureFactory::CreateDeviceInfo(
113 ViEModuleId(engine_id_));
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000114 assert(capture_device_info_);
115 VideoCaptureCapability module_capability;
116 int result = capture_device_info_->GetCapability(device_unique_idUTF8,
117 device_capability_number,
118 module_capability);
119 if (result != 0)
niklase@google.com470e71d2011-07-07 08:21:25 +0000120 return result;
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000121
122 // Copy from module type to public type.
123 capability.expectedCaptureDelay = module_capability.expectedCaptureDelay;
124 capability.height = module_capability.height;
125 capability.width = module_capability.width;
126 capability.interlaced = module_capability.interlaced;
127 capability.rawType = module_capability.rawType;
128 capability.codecType = module_capability.codecType;
129 capability.maxFPS = module_capability.maxFPS;
130 return result;
niklase@google.com470e71d2011-07-07 08:21:25 +0000131}
132
leozwang@webrtc.org1745e932012-03-01 16:30:40 +0000133int ViEInputManager::GetOrientation(const char* device_unique_idUTF8,
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000134 RotateCapturedFrame& orientation) {
135 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_),
136 "%s(device_unique_idUTF8: %s,)", __FUNCTION__,
137 device_unique_idUTF8);
pbos@webrtc.org927296f2013-03-08 13:12:29 +0000138 CriticalSectionScoped cs(device_info_cs_.get());
139 if (capture_device_info_ == NULL)
140 capture_device_info_ = VideoCaptureFactory::CreateDeviceInfo(
141 ViEModuleId(engine_id_));
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000142 assert(capture_device_info_);
143 VideoCaptureRotation module_orientation;
144 int result = capture_device_info_->GetOrientation(device_unique_idUTF8,
145 module_orientation);
146 // Copy from module type to public type.
147 switch (module_orientation) {
148 case kCameraRotate0:
149 orientation = RotateCapturedFrame_0;
150 break;
151 case kCameraRotate90:
152 orientation = RotateCapturedFrame_90;
153 break;
154 case kCameraRotate180:
155 orientation = RotateCapturedFrame_180;
156 break;
157 case kCameraRotate270:
158 orientation = RotateCapturedFrame_270;
159 break;
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000160 }
161 return result;
niklase@google.com470e71d2011-07-07 08:21:25 +0000162}
163
niklase@google.com470e71d2011-07-07 08:21:25 +0000164int ViEInputManager::DisplayCaptureSettingsDialogBox(
leozwang@webrtc.org1745e932012-03-01 16:30:40 +0000165 const char* device_unique_idUTF8,
166 const char* dialog_titleUTF8,
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000167 void* parent_window,
pbos@webrtc.orgb238d122013-04-09 13:41:51 +0000168 uint32_t positionX,
169 uint32_t positionY) {
pbos@webrtc.org927296f2013-03-08 13:12:29 +0000170 CriticalSectionScoped cs(device_info_cs_.get());
171 if (capture_device_info_ == NULL)
172 capture_device_info_ = VideoCaptureFactory::CreateDeviceInfo(
173 ViEModuleId(engine_id_));
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000174 assert(capture_device_info_);
175 return capture_device_info_->DisplayCaptureSettingsDialogBox(
176 device_unique_idUTF8, dialog_titleUTF8, parent_window, positionX,
177 positionY);
niklase@google.com470e71d2011-07-07 08:21:25 +0000178}
179
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000180int ViEInputManager::CreateCaptureDevice(
leozwang@webrtc.org1745e932012-03-01 16:30:40 +0000181 const char* device_unique_idUTF8,
pbos@webrtc.orgb238d122013-04-09 13:41:51 +0000182 const uint32_t device_unique_idUTF8Length,
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000183 int& capture_id) {
184 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_),
185 "%s(device_unique_id: %s)", __FUNCTION__, device_unique_idUTF8);
mflodman@webrtc.orgd32c4472011-12-22 14:17:53 +0000186 CriticalSectionScoped cs(map_cs_.get());
niklase@google.com470e71d2011-07-07 08:21:25 +0000187
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000188 // Make sure the device is not already allocated.
pbos@webrtc.org4ca7d3f2013-08-12 19:51:57 +0000189 for (FrameProviderMap::iterator it = vie_frame_provider_map_.begin();
190 it != vie_frame_provider_map_.end();
191 ++it) {
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000192 // Make sure this is a capture device.
pbos@webrtc.org4ca7d3f2013-08-12 19:51:57 +0000193 if (it->first >= kViECaptureIdBase && it->first <= kViECaptureIdMax) {
194 ViECapturer* vie_capture = static_cast<ViECapturer*>(it->second);
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000195 assert(vie_capture);
196 // TODO(mflodman) Can we change input to avoid this cast?
197 const char* device_name =
198 reinterpret_cast<const char*>(vie_capture->CurrentDeviceName());
pbos@webrtc.org4ca7d3f2013-08-12 19:51:57 +0000199 if (strncmp(device_name, device_unique_idUTF8,
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000200 strlen(device_name)) == 0) {
201 return kViECaptureDeviceAlreadyAllocated;
202 }
203 }
204 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000205
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000206 // Make sure the device name is valid.
207 bool found_device = false;
pbos@webrtc.org927296f2013-03-08 13:12:29 +0000208 CriticalSectionScoped cs_devinfo(device_info_cs_.get());
209 if (capture_device_info_ == NULL)
210 capture_device_info_ = VideoCaptureFactory::CreateDeviceInfo(
211 ViEModuleId(engine_id_));
212 assert(capture_device_info_);
pbos@webrtc.orgb238d122013-04-09 13:41:51 +0000213 for (uint32_t device_index = 0;
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000214 device_index < capture_device_info_->NumberOfDevices(); ++device_index) {
215 if (device_unique_idUTF8Length > kVideoCaptureUniqueNameLength) {
216 // User's string length is longer than the max.
217 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000218 }
219
leozwang@webrtc.org1745e932012-03-01 16:30:40 +0000220 char found_name[kVideoCaptureDeviceNameLength] = "";
221 char found_unique_name[kVideoCaptureUniqueNameLength] = "";
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000222 capture_device_info_->GetDeviceName(device_index, found_name,
223 kVideoCaptureDeviceNameLength,
224 found_unique_name,
225 kVideoCaptureUniqueNameLength);
226
227 // TODO(mflodman) Can we change input to avoid this cast?
228 const char* cast_id = reinterpret_cast<const char*>(device_unique_idUTF8);
229 if (strncmp(cast_id, reinterpret_cast<const char*>(found_unique_name),
230 strlen(cast_id)) == 0) {
231 WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideo, ViEId(engine_id_),
232 "%s:%d Capture device was found by unique ID: %s. Returning",
233 __FUNCTION__, __LINE__, device_unique_idUTF8);
234 found_device = true;
235 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000236 }
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000237 }
238 if (!found_device) {
239 WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideo, ViEId(engine_id_),
240 "%s:%d Capture device NOT found by unique ID: %s. Returning",
241 __FUNCTION__, __LINE__, device_unique_idUTF8);
242 return kViECaptureDeviceDoesNotExist;
243 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000244
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000245 int newcapture_id = 0;
mflodman@webrtc.org8baed512012-06-21 12:11:50 +0000246 if (GetFreeCaptureId(&newcapture_id) == false) {
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000247 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_),
248 "%s: Maximum supported number of capture devices already in "
249 "use", __FUNCTION__);
250 return kViECaptureDeviceMaxNoDevicesAllocated;
251 }
252 ViECapturer* vie_capture = ViECapturer::CreateViECapture(
andresp@webrtc.org7707d062013-05-13 10:50:50 +0000253 newcapture_id, engine_id_, config_, device_unique_idUTF8,
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000254 device_unique_idUTF8Length, *module_process_thread_);
255 if (!vie_capture) {
256 ReturnCaptureId(newcapture_id);
257 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_),
258 "%s: Could not create capture module for %s", __FUNCTION__,
259 device_unique_idUTF8);
260 return kViECaptureDeviceUnknownError;
261 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000262
pbos@webrtc.org4ca7d3f2013-08-12 19:51:57 +0000263 vie_frame_provider_map_[newcapture_id] = vie_capture;
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000264 capture_id = newcapture_id;
265 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_),
266 "%s(device_unique_id: %s, capture_id: %d)", __FUNCTION__,
267 device_unique_idUTF8, capture_id);
268 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000269}
270
mflodman@webrtc.org8baed512012-06-21 12:11:50 +0000271int ViEInputManager::CreateCaptureDevice(VideoCaptureModule* capture_module,
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000272 int& capture_id) {
273 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_), "%s",
niklase@google.com470e71d2011-07-07 08:21:25 +0000274 __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +0000275
mflodman@webrtc.orgd32c4472011-12-22 14:17:53 +0000276 CriticalSectionScoped cs(map_cs_.get());
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000277 int newcapture_id = 0;
mflodman@webrtc.org8baed512012-06-21 12:11:50 +0000278 if (!GetFreeCaptureId(&newcapture_id)) {
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000279 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_),
280 "%s: Maximum supported number of capture devices already in "
281 "use", __FUNCTION__);
282 return kViECaptureDeviceMaxNoDevicesAllocated;
283 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000284
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000285 ViECapturer* vie_capture = ViECapturer::CreateViECapture(
andresp@webrtc.org7707d062013-05-13 10:50:50 +0000286 newcapture_id, engine_id_, config_,
287 capture_module, *module_process_thread_);
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000288 if (!vie_capture) {
289 ReturnCaptureId(newcapture_id);
290 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_),
291 "%s: Could attach capture module.", __FUNCTION__);
292 return kViECaptureDeviceUnknownError;
293 }
pbos@webrtc.org4ca7d3f2013-08-12 19:51:57 +0000294 vie_frame_provider_map_[newcapture_id] = vie_capture;
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000295 capture_id = newcapture_id;
296 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_),
297 "%s, capture_id: %d", __FUNCTION__, capture_id);
298 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000299}
300
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000301int ViEInputManager::DestroyCaptureDevice(const int capture_id) {
302 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_),
303 "%s(capture_id: %d)", __FUNCTION__, capture_id);
304 ViECapturer* vie_capture = NULL;
305 {
306 // We need exclusive access to the object to delete it.
307 // Take this write lock first since the read lock is taken before map_cs_.
mflodman@webrtc.orgcee447a2012-06-28 07:29:46 +0000308 ViEManagerWriteScoped wl(this);
mflodman@webrtc.orgd32c4472011-12-22 14:17:53 +0000309 CriticalSectionScoped cs(map_cs_.get());
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000310
311 vie_capture = ViECapturePtr(capture_id);
312 if (!vie_capture) {
313 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_),
314 "%s(capture_id: %d) - No such capture device id",
315 __FUNCTION__, capture_id);
316 return -1;
317 }
pbos@webrtc.orgb238d122013-04-09 13:41:51 +0000318 uint32_t num_callbacks =
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000319 vie_capture->NumberOfRegisteredFrameCallbacks();
320 if (num_callbacks > 0) {
321 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideo,
322 ViEId(engine_id_), "%s(capture_id: %d) - %u registered "
323 "callbacks when destroying capture device",
324 __FUNCTION__, capture_id, num_callbacks);
325 }
pbos@webrtc.org4ca7d3f2013-08-12 19:51:57 +0000326 vie_frame_provider_map_.erase(capture_id);
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000327 ReturnCaptureId(capture_id);
328 // Leave cs before deleting the capture object. This is because deleting the
329 // object might cause deletions of renderers so we prefer to not have a lock
330 // at that time.
331 }
332 delete vie_capture;
333 return 0;
334}
335
336int ViEInputManager::CreateExternalCaptureDevice(
337 ViEExternalCapture*& external_capture,
338 int& capture_id) {
339 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_), "%s",
340 __FUNCTION__);
mflodman@webrtc.orgd32c4472011-12-22 14:17:53 +0000341 CriticalSectionScoped cs(map_cs_.get());
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000342
343 int newcapture_id = 0;
mflodman@webrtc.org8baed512012-06-21 12:11:50 +0000344 if (GetFreeCaptureId(&newcapture_id) == false) {
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000345 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_),
346 "%s: Maximum supported number of capture devices already in "
347 "use", __FUNCTION__);
348 return kViECaptureDeviceMaxNoDevicesAllocated;
349 }
350
351 ViECapturer* vie_capture = ViECapturer::CreateViECapture(
andresp@webrtc.org7707d062013-05-13 10:50:50 +0000352 newcapture_id, engine_id_, config_, NULL, 0, *module_process_thread_);
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000353 if (!vie_capture) {
354 ReturnCaptureId(newcapture_id);
355 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_),
356 "%s: Could not create capture module for external capture.",
357 __FUNCTION__);
358 return kViECaptureDeviceUnknownError;
359 }
360
pbos@webrtc.org4ca7d3f2013-08-12 19:51:57 +0000361 vie_frame_provider_map_[newcapture_id] = vie_capture;
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000362 capture_id = newcapture_id;
363 external_capture = vie_capture;
364 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_),
365 "%s, capture_id: %d)", __FUNCTION__, capture_id);
366 return 0;
367}
368
mflodman@webrtc.org8baed512012-06-21 12:11:50 +0000369bool ViEInputManager::GetFreeCaptureId(int* freecapture_id) {
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000370 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_), "%s",
371 __FUNCTION__);
372 for (int id = 0; id < kViEMaxCaptureDevices; id++) {
373 if (free_capture_device_id_[id]) {
374 // We found a free capture device id.
375 free_capture_device_id_[id] = false;
mflodman@webrtc.org8baed512012-06-21 12:11:50 +0000376 *freecapture_id = id + kViECaptureIdBase;
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000377 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_),
mflodman@webrtc.org8baed512012-06-21 12:11:50 +0000378 "%s: new id: %d", __FUNCTION__, *freecapture_id);
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000379 return true;
380 }
381 }
382 return false;
383}
niklase@google.com470e71d2011-07-07 08:21:25 +0000384
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000385void ViEInputManager::ReturnCaptureId(int capture_id) {
386 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_),
387 "%s(%d)", __FUNCTION__, capture_id);
mflodman@webrtc.orgd32c4472011-12-22 14:17:53 +0000388 CriticalSectionScoped cs(map_cs_.get());
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000389 if (capture_id >= kViECaptureIdBase &&
390 capture_id < kViEMaxCaptureDevices + kViECaptureIdBase) {
391 free_capture_device_id_[capture_id - kViECaptureIdBase] = true;
392 }
393 return;
394}
niklase@google.com470e71d2011-07-07 08:21:25 +0000395
niklase@google.com470e71d2011-07-07 08:21:25 +0000396ViEFrameProviderBase* ViEInputManager::ViEFrameProvider(
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000397 const ViEFrameCallback* capture_observer) const {
398 assert(capture_observer);
mflodman@webrtc.orgd32c4472011-12-22 14:17:53 +0000399 CriticalSectionScoped cs(map_cs_.get());
niklase@google.com470e71d2011-07-07 08:21:25 +0000400
pbos@webrtc.org4ca7d3f2013-08-12 19:51:57 +0000401 for (FrameProviderMap::const_iterator it = vie_frame_provider_map_.begin();
402 it != vie_frame_provider_map_.end();
403 ++it) {
404 if (it->second->IsFrameCallbackRegistered(capture_observer))
405 return it->second;
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000406 }
pbos@webrtc.org4ca7d3f2013-08-12 19:51:57 +0000407
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000408 // No capture device set for this channel.
409 return NULL;
410}
411
412ViEFrameProviderBase* ViEInputManager::ViEFrameProvider(int provider_id) const {
mflodman@webrtc.orgd32c4472011-12-22 14:17:53 +0000413 CriticalSectionScoped cs(map_cs_.get());
pbos@webrtc.org4ca7d3f2013-08-12 19:51:57 +0000414
415 FrameProviderMap::const_iterator it =
416 vie_frame_provider_map_.find(provider_id);
417 if (it == vie_frame_provider_map_.end())
niklase@google.com470e71d2011-07-07 08:21:25 +0000418 return NULL;
pbos@webrtc.org4ca7d3f2013-08-12 19:51:57 +0000419 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000420}
421
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000422ViECapturer* ViEInputManager::ViECapturePtr(int capture_id) const {
423 if (!(capture_id >= kViECaptureIdBase &&
mflodman@webrtc.org5574dac2014-04-07 10:56:31 +0000424 capture_id <= kViECaptureIdBase + kViEMaxCaptureDevices)) {
425 LOG(LS_ERROR) << "Capture device doesn't exist " << capture_id << ".";
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000426 return NULL;
mflodman@webrtc.org5574dac2014-04-07 10:56:31 +0000427 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000428
pbos@webrtc.org4ca7d3f2013-08-12 19:51:57 +0000429 return static_cast<ViECapturer*>(ViEFrameProvider(capture_id));
niklase@google.com470e71d2011-07-07 08:21:25 +0000430}
431
niklase@google.com470e71d2011-07-07 08:21:25 +0000432ViEInputManagerScoped::ViEInputManagerScoped(
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000433 const ViEInputManager& vie_input_manager)
434 : ViEManagerScopedBase(vie_input_manager) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000435}
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000436
437ViECapturer* ViEInputManagerScoped::Capture(int capture_id) const {
438 return static_cast<const ViEInputManager*>(vie_manager_)->ViECapturePtr(
439 capture_id);
niklase@google.com470e71d2011-07-07 08:21:25 +0000440}
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000441
niklase@google.com470e71d2011-07-07 08:21:25 +0000442ViEFrameProviderBase* ViEInputManagerScoped::FrameProvider(
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000443 const ViEFrameCallback* capture_observer) const {
444 return static_cast<const ViEInputManager*>(vie_manager_)->ViEFrameProvider(
445 capture_observer);
niklase@google.com470e71d2011-07-07 08:21:25 +0000446}
447
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000448ViEFrameProviderBase* ViEInputManagerScoped::FrameProvider(
449 int provider_id) const {
450 return static_cast<const ViEInputManager*>(vie_manager_)->ViEFrameProvider(
451 provider_id);
niklase@google.com470e71d2011-07-07 08:21:25 +0000452}
453
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000454} // namespace webrtc