blob: 937d1c5e4c042f90d1e523f2a1cecf8a7522e942 [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
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000011#include "video_engine/vie_input_manager.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000012
13#include <cassert>
14
mflodman@webrtc.org8baed512012-06-21 12:11:50 +000015#include "common_types.h" // NOLINT
andrew@webrtc.org94caca72012-10-30 21:58:00 +000016#include "webrtc/modules/video_capture/include/video_capture_factory.h"
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000017#include "modules/video_coding/main/interface/video_coding.h"
18#include "modules/video_coding/main/interface/video_coding_defines.h"
19#include "system_wrappers/interface/critical_section_wrapper.h"
20#include "system_wrappers/interface/rw_lock_wrapper.h"
21#include "system_wrappers/interface/trace.h"
mflodman@webrtc.orga4863db2011-12-22 08:51:52 +000022#include "video_engine/include/vie_errors.h"
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000023#include "video_engine/vie_capturer.h"
24#include "video_engine/vie_defines.h"
25#include "video_engine/vie_file_player.h"
26
niklase@google.com470e71d2011-07-07 08:21:25 +000027namespace webrtc {
28
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000029ViEInputManager::ViEInputManager(const int engine_id)
30 : engine_id_(engine_id),
mflodman@webrtc.orgd32c4472011-12-22 14:17:53 +000031 map_cs_(CriticalSectionWrapper::CreateCriticalSection()),
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000032 vie_frame_provider_map_(),
33 capture_device_info_(NULL),
34 module_process_thread_(NULL) {
35 WEBRTC_TRACE(webrtc::kTraceMemory, webrtc::kTraceVideo, ViEId(engine_id_),
36 "%s", __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +000037
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000038 for (int idx = 0; idx < kViEMaxCaptureDevices; idx++) {
39 free_capture_device_id_[idx] = true;
40 }
41 capture_device_info_ = VideoCaptureFactory::CreateDeviceInfo(
42 ViEModuleId(engine_id_));
43 for (int idx = 0; idx < kViEMaxFilePlayers; idx++) {
44 free_file_id_[idx] = true;
45 }
46}
niklase@google.com470e71d2011-07-07 08:21:25 +000047
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000048ViEInputManager::~ViEInputManager() {
49 WEBRTC_TRACE(webrtc::kTraceMemory, webrtc::kTraceVideo, ViEId(engine_id_),
50 "%s", __FUNCTION__);
51 while (vie_frame_provider_map_.Size() != 0) {
52 MapItem* item = vie_frame_provider_map_.First();
53 assert(item);
54 ViEFrameProviderBase* frame_provider =
55 static_cast<ViEFrameProviderBase*>(item->GetItem());
56 vie_frame_provider_map_.Erase(item);
57 delete frame_provider;
58 }
59
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000060 if (capture_device_info_) {
61 delete capture_device_info_;
62 capture_device_info_ = NULL;
63 }
64}
65void ViEInputManager::SetModuleProcessThread(
mflodman@webrtc.org8baed512012-06-21 12:11:50 +000066 ProcessThread* module_process_thread) {
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000067 assert(!module_process_thread_);
mflodman@webrtc.org8baed512012-06-21 12:11:50 +000068 module_process_thread_ = module_process_thread;
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000069}
70
71int ViEInputManager::NumberOfCaptureDevices() {
72 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_), "%s",
niklase@google.com470e71d2011-07-07 08:21:25 +000073 __FUNCTION__);
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000074 assert(capture_device_info_);
75 return capture_device_info_->NumberOfDevices();
niklase@google.com470e71d2011-07-07 08:21:25 +000076}
77
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000078int ViEInputManager::GetDeviceName(WebRtc_UWord32 device_number,
leozwang@webrtc.org1745e932012-03-01 16:30:40 +000079 char* device_nameUTF8,
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000080 WebRtc_UWord32 device_name_length,
leozwang@webrtc.org1745e932012-03-01 16:30:40 +000081 char* device_unique_idUTF8,
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000082 WebRtc_UWord32 device_unique_idUTF8Length) {
83 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_),
84 "%s(device_number: %d)", __FUNCTION__, device_number);
85 assert(capture_device_info_);
86 return capture_device_info_->GetDeviceName(device_number, device_nameUTF8,
87 device_name_length,
88 device_unique_idUTF8,
89 device_unique_idUTF8Length);
niklase@google.com470e71d2011-07-07 08:21:25 +000090}
91
niklase@google.com470e71d2011-07-07 08:21:25 +000092int ViEInputManager::NumberOfCaptureCapabilities(
leozwang@webrtc.org1745e932012-03-01 16:30:40 +000093 const char* device_unique_idUTF8) {
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000094 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_), "%s",
niklase@google.com470e71d2011-07-07 08:21:25 +000095 __FUNCTION__);
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +000096 assert(capture_device_info_);
97 return capture_device_info_->NumberOfCapabilities(device_unique_idUTF8);
niklase@google.com470e71d2011-07-07 08:21:25 +000098}
99
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000100int ViEInputManager::GetCaptureCapability(
leozwang@webrtc.org1745e932012-03-01 16:30:40 +0000101 const char* device_unique_idUTF8,
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000102 const WebRtc_UWord32 device_capability_number,
103 CaptureCapability& capability) {
104 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_),
105 "%s(device_unique_idUTF8: %s, device_capability_number: %d)",
106 __FUNCTION__, device_unique_idUTF8, device_capability_number);
107 assert(capture_device_info_);
108 VideoCaptureCapability module_capability;
109 int result = capture_device_info_->GetCapability(device_unique_idUTF8,
110 device_capability_number,
111 module_capability);
112 if (result != 0)
niklase@google.com470e71d2011-07-07 08:21:25 +0000113 return result;
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000114
115 // Copy from module type to public type.
116 capability.expectedCaptureDelay = module_capability.expectedCaptureDelay;
117 capability.height = module_capability.height;
118 capability.width = module_capability.width;
119 capability.interlaced = module_capability.interlaced;
120 capability.rawType = module_capability.rawType;
121 capability.codecType = module_capability.codecType;
122 capability.maxFPS = module_capability.maxFPS;
123 return result;
niklase@google.com470e71d2011-07-07 08:21:25 +0000124}
125
leozwang@webrtc.org1745e932012-03-01 16:30:40 +0000126int ViEInputManager::GetOrientation(const char* device_unique_idUTF8,
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000127 RotateCapturedFrame& orientation) {
128 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_),
129 "%s(device_unique_idUTF8: %s,)", __FUNCTION__,
130 device_unique_idUTF8);
131 assert(capture_device_info_);
132 VideoCaptureRotation module_orientation;
133 int result = capture_device_info_->GetOrientation(device_unique_idUTF8,
134 module_orientation);
135 // Copy from module type to public type.
136 switch (module_orientation) {
137 case kCameraRotate0:
138 orientation = RotateCapturedFrame_0;
139 break;
140 case kCameraRotate90:
141 orientation = RotateCapturedFrame_90;
142 break;
143 case kCameraRotate180:
144 orientation = RotateCapturedFrame_180;
145 break;
146 case kCameraRotate270:
147 orientation = RotateCapturedFrame_270;
148 break;
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000149 }
150 return result;
niklase@google.com470e71d2011-07-07 08:21:25 +0000151}
152
niklase@google.com470e71d2011-07-07 08:21:25 +0000153int ViEInputManager::DisplayCaptureSettingsDialogBox(
leozwang@webrtc.org1745e932012-03-01 16:30:40 +0000154 const char* device_unique_idUTF8,
155 const char* dialog_titleUTF8,
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000156 void* parent_window,
157 WebRtc_UWord32 positionX,
158 WebRtc_UWord32 positionY) {
159 assert(capture_device_info_);
160 return capture_device_info_->DisplayCaptureSettingsDialogBox(
161 device_unique_idUTF8, dialog_titleUTF8, parent_window, positionX,
162 positionY);
niklase@google.com470e71d2011-07-07 08:21:25 +0000163}
164
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000165int ViEInputManager::CreateCaptureDevice(
leozwang@webrtc.org1745e932012-03-01 16:30:40 +0000166 const char* device_unique_idUTF8,
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000167 const WebRtc_UWord32 device_unique_idUTF8Length,
168 int& capture_id) {
169 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_),
170 "%s(device_unique_id: %s)", __FUNCTION__, device_unique_idUTF8);
mflodman@webrtc.orgd32c4472011-12-22 14:17:53 +0000171 CriticalSectionScoped cs(map_cs_.get());
niklase@google.com470e71d2011-07-07 08:21:25 +0000172
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000173 // Make sure the device is not already allocated.
174 for (MapItem* item = vie_frame_provider_map_.First(); item != NULL;
175 item = vie_frame_provider_map_.Next(item)) {
176 // Make sure this is a capture device.
177 if (item->GetId() >= kViECaptureIdBase &&
178 item->GetId() <= kViECaptureIdMax) {
179 ViECapturer* vie_capture = static_cast<ViECapturer*>(item->GetItem());
180 assert(vie_capture);
181 // TODO(mflodman) Can we change input to avoid this cast?
182 const char* device_name =
183 reinterpret_cast<const char*>(vie_capture->CurrentDeviceName());
184 if (strncmp(device_name,
185 reinterpret_cast<const char*>(device_unique_idUTF8),
186 strlen(device_name)) == 0) {
187 return kViECaptureDeviceAlreadyAllocated;
188 }
189 }
190 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000191
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000192 // Make sure the device name is valid.
193 bool found_device = false;
194 for (WebRtc_UWord32 device_index = 0;
195 device_index < capture_device_info_->NumberOfDevices(); ++device_index) {
196 if (device_unique_idUTF8Length > kVideoCaptureUniqueNameLength) {
197 // User's string length is longer than the max.
198 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000199 }
200
leozwang@webrtc.org1745e932012-03-01 16:30:40 +0000201 char found_name[kVideoCaptureDeviceNameLength] = "";
202 char found_unique_name[kVideoCaptureUniqueNameLength] = "";
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000203 capture_device_info_->GetDeviceName(device_index, found_name,
204 kVideoCaptureDeviceNameLength,
205 found_unique_name,
206 kVideoCaptureUniqueNameLength);
207
208 // TODO(mflodman) Can we change input to avoid this cast?
209 const char* cast_id = reinterpret_cast<const char*>(device_unique_idUTF8);
210 if (strncmp(cast_id, reinterpret_cast<const char*>(found_unique_name),
211 strlen(cast_id)) == 0) {
212 WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideo, ViEId(engine_id_),
213 "%s:%d Capture device was found by unique ID: %s. Returning",
214 __FUNCTION__, __LINE__, device_unique_idUTF8);
215 found_device = true;
216 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000217 }
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000218 }
219 if (!found_device) {
220 WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideo, ViEId(engine_id_),
221 "%s:%d Capture device NOT found by unique ID: %s. Returning",
222 __FUNCTION__, __LINE__, device_unique_idUTF8);
223 return kViECaptureDeviceDoesNotExist;
224 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000225
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000226 int newcapture_id = 0;
mflodman@webrtc.org8baed512012-06-21 12:11:50 +0000227 if (GetFreeCaptureId(&newcapture_id) == false) {
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000228 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_),
229 "%s: Maximum supported number of capture devices already in "
230 "use", __FUNCTION__);
231 return kViECaptureDeviceMaxNoDevicesAllocated;
232 }
233 ViECapturer* vie_capture = ViECapturer::CreateViECapture(
234 newcapture_id, engine_id_, device_unique_idUTF8,
235 device_unique_idUTF8Length, *module_process_thread_);
236 if (!vie_capture) {
237 ReturnCaptureId(newcapture_id);
238 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_),
239 "%s: Could not create capture module for %s", __FUNCTION__,
240 device_unique_idUTF8);
241 return kViECaptureDeviceUnknownError;
242 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000243
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000244 if (vie_frame_provider_map_.Insert(newcapture_id, vie_capture) != 0) {
245 ReturnCaptureId(newcapture_id);
246 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_),
247 "%s: Could not insert capture module for %s", __FUNCTION__,
248 device_unique_idUTF8);
249 return kViECaptureDeviceUnknownError;
250 }
251 capture_id = newcapture_id;
252 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_),
253 "%s(device_unique_id: %s, capture_id: %d)", __FUNCTION__,
254 device_unique_idUTF8, capture_id);
255 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000256}
257
mflodman@webrtc.org8baed512012-06-21 12:11:50 +0000258int ViEInputManager::CreateCaptureDevice(VideoCaptureModule* capture_module,
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000259 int& capture_id) {
260 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_), "%s",
niklase@google.com470e71d2011-07-07 08:21:25 +0000261 __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +0000262
mflodman@webrtc.orgd32c4472011-12-22 14:17:53 +0000263 CriticalSectionScoped cs(map_cs_.get());
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000264 int newcapture_id = 0;
mflodman@webrtc.org8baed512012-06-21 12:11:50 +0000265 if (!GetFreeCaptureId(&newcapture_id)) {
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000266 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_),
267 "%s: Maximum supported number of capture devices already in "
268 "use", __FUNCTION__);
269 return kViECaptureDeviceMaxNoDevicesAllocated;
270 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000271
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000272 ViECapturer* vie_capture = ViECapturer::CreateViECapture(
273 newcapture_id, engine_id_, capture_module, *module_process_thread_);
274 if (!vie_capture) {
275 ReturnCaptureId(newcapture_id);
276 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_),
277 "%s: Could attach capture module.", __FUNCTION__);
278 return kViECaptureDeviceUnknownError;
279 }
280 if (vie_frame_provider_map_.Insert(newcapture_id, vie_capture) != 0) {
281 ReturnCaptureId(newcapture_id);
282 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_),
283 "%s: Could not insert capture module", __FUNCTION__);
284 return kViECaptureDeviceUnknownError;
285 }
286 capture_id = newcapture_id;
287 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_),
288 "%s, capture_id: %d", __FUNCTION__, capture_id);
289 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000290}
291
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000292int ViEInputManager::DestroyCaptureDevice(const int capture_id) {
293 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_),
294 "%s(capture_id: %d)", __FUNCTION__, capture_id);
295 ViECapturer* vie_capture = NULL;
296 {
297 // We need exclusive access to the object to delete it.
298 // Take this write lock first since the read lock is taken before map_cs_.
mflodman@webrtc.orgcee447a2012-06-28 07:29:46 +0000299 ViEManagerWriteScoped wl(this);
mflodman@webrtc.orgd32c4472011-12-22 14:17:53 +0000300 CriticalSectionScoped cs(map_cs_.get());
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000301
302 vie_capture = ViECapturePtr(capture_id);
303 if (!vie_capture) {
304 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_),
305 "%s(capture_id: %d) - No such capture device id",
306 __FUNCTION__, capture_id);
307 return -1;
308 }
309 WebRtc_UWord32 num_callbacks =
310 vie_capture->NumberOfRegisteredFrameCallbacks();
311 if (num_callbacks > 0) {
312 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideo,
313 ViEId(engine_id_), "%s(capture_id: %d) - %u registered "
314 "callbacks when destroying capture device",
315 __FUNCTION__, capture_id, num_callbacks);
316 }
317 vie_frame_provider_map_.Erase(capture_id);
318 ReturnCaptureId(capture_id);
319 // Leave cs before deleting the capture object. This is because deleting the
320 // object might cause deletions of renderers so we prefer to not have a lock
321 // at that time.
322 }
323 delete vie_capture;
324 return 0;
325}
326
327int ViEInputManager::CreateExternalCaptureDevice(
328 ViEExternalCapture*& external_capture,
329 int& capture_id) {
330 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_), "%s",
331 __FUNCTION__);
mflodman@webrtc.orgd32c4472011-12-22 14:17:53 +0000332 CriticalSectionScoped cs(map_cs_.get());
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000333
334 int newcapture_id = 0;
mflodman@webrtc.org8baed512012-06-21 12:11:50 +0000335 if (GetFreeCaptureId(&newcapture_id) == false) {
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000336 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_),
337 "%s: Maximum supported number of capture devices already in "
338 "use", __FUNCTION__);
339 return kViECaptureDeviceMaxNoDevicesAllocated;
340 }
341
342 ViECapturer* vie_capture = ViECapturer::CreateViECapture(
343 newcapture_id, engine_id_, NULL, 0, *module_process_thread_);
344 if (!vie_capture) {
345 ReturnCaptureId(newcapture_id);
346 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_),
347 "%s: Could not create capture module for external capture.",
348 __FUNCTION__);
349 return kViECaptureDeviceUnknownError;
350 }
351
352 if (vie_frame_provider_map_.Insert(newcapture_id, vie_capture) != 0) {
353 ReturnCaptureId(newcapture_id);
354 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_),
355 "%s: Could not insert capture module for external capture.",
356 __FUNCTION__);
357 return kViECaptureDeviceUnknownError;
358 }
359 capture_id = newcapture_id;
360 external_capture = vie_capture;
361 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_),
362 "%s, capture_id: %d)", __FUNCTION__, capture_id);
363 return 0;
364}
365
leozwang@webrtc.org1745e932012-03-01 16:30:40 +0000366int ViEInputManager::CreateFilePlayer(const char* file_nameUTF8,
niklase@google.com470e71d2011-07-07 08:21:25 +0000367 const bool loop,
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000368 const webrtc::FileFormats file_format,
369 VoiceEngine* voe_ptr, int& file_id) {
370 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_),
371 "%s(device_unique_id: %s)", __FUNCTION__, file_nameUTF8);
niklase@google.com470e71d2011-07-07 08:21:25 +0000372
mflodman@webrtc.orgd32c4472011-12-22 14:17:53 +0000373 CriticalSectionScoped cs(map_cs_.get());
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000374 int new_file_id = 0;
mflodman@webrtc.org8baed512012-06-21 12:11:50 +0000375 if (GetFreeFileId(&new_file_id) == false) {
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000376 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_),
377 "%s: Maximum supported number of file players already in use",
378 __FUNCTION__);
379 return kViEFileMaxNoOfFilesOpened;
380 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000381
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000382 ViEFilePlayer* vie_file_player = ViEFilePlayer::CreateViEFilePlayer(
mflodman@webrtc.org8baed512012-06-21 12:11:50 +0000383 new_file_id, engine_id_, file_nameUTF8, loop, file_format, voe_ptr);
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000384 if (!vie_file_player) {
385 ReturnFileId(new_file_id);
386 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_),
387 "%s: Could not open file %s for playback", __FUNCTION__,
388 file_nameUTF8);
389 return kViEFileUnknownError;
390 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000391
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000392 if (vie_frame_provider_map_.Insert(new_file_id, vie_file_player) != 0) {
393 ReturnCaptureId(new_file_id);
394 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_),
395 "%s: Could not insert file player for %s", __FUNCTION__,
396 file_nameUTF8);
397 delete vie_file_player;
398 return kViEFileUnknownError;
399 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000400
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000401 file_id = new_file_id;
402 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_),
403 "%s(filename: %s, file_id: %d)", __FUNCTION__, file_nameUTF8,
404 new_file_id);
405 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000406}
407
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000408int ViEInputManager::DestroyFilePlayer(int file_id) {
409 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_),
410 "%s(file_id: %d)", __FUNCTION__, file_id);
niklase@google.com470e71d2011-07-07 08:21:25 +0000411
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000412 ViEFilePlayer* vie_file_player = NULL;
413 {
414 // We need exclusive access to the object to delete it.
415 // Take this write lock first since the read lock is taken before map_cs_.
mflodman@webrtc.orgcee447a2012-06-28 07:29:46 +0000416 ViEManagerWriteScoped wl(this);
niklase@google.com470e71d2011-07-07 08:21:25 +0000417
mflodman@webrtc.orgd32c4472011-12-22 14:17:53 +0000418 CriticalSectionScoped cs(map_cs_.get());
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000419 vie_file_player = ViEFilePlayerPtr(file_id);
420 if (!vie_file_player) {
421 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_),
422 "%s(file_id: %d) - No such file player", __FUNCTION__,
423 file_id);
424 return -1;
425 }
426 int num_callbacks = vie_file_player->NumberOfRegisteredFrameCallbacks();
427 if (num_callbacks > 0) {
428 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideo,
429 ViEId(engine_id_), "%s(file_id: %d) - %u registered "
430 "callbacks when destroying file player", __FUNCTION__,
431 file_id, num_callbacks);
432 }
433 vie_frame_provider_map_.Erase(file_id);
434 ReturnFileId(file_id);
435 // Leave cs before deleting the file object. This is because deleting the
436 // object might cause deletions of renderers so we prefer to not have a lock
437 // at that time.
438 }
439 delete vie_file_player;
440 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000441}
442
mflodman@webrtc.org8baed512012-06-21 12:11:50 +0000443bool ViEInputManager::GetFreeCaptureId(int* freecapture_id) {
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000444 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_), "%s",
445 __FUNCTION__);
446 for (int id = 0; id < kViEMaxCaptureDevices; id++) {
447 if (free_capture_device_id_[id]) {
448 // We found a free capture device id.
449 free_capture_device_id_[id] = false;
mflodman@webrtc.org8baed512012-06-21 12:11:50 +0000450 *freecapture_id = id + kViECaptureIdBase;
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000451 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_),
mflodman@webrtc.org8baed512012-06-21 12:11:50 +0000452 "%s: new id: %d", __FUNCTION__, *freecapture_id);
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000453 return true;
454 }
455 }
456 return false;
457}
niklase@google.com470e71d2011-07-07 08:21:25 +0000458
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000459void ViEInputManager::ReturnCaptureId(int capture_id) {
460 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_),
461 "%s(%d)", __FUNCTION__, capture_id);
mflodman@webrtc.orgd32c4472011-12-22 14:17:53 +0000462 CriticalSectionScoped cs(map_cs_.get());
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000463 if (capture_id >= kViECaptureIdBase &&
464 capture_id < kViEMaxCaptureDevices + kViECaptureIdBase) {
465 free_capture_device_id_[capture_id - kViECaptureIdBase] = true;
466 }
467 return;
468}
niklase@google.com470e71d2011-07-07 08:21:25 +0000469
mflodman@webrtc.org8baed512012-06-21 12:11:50 +0000470bool ViEInputManager::GetFreeFileId(int* free_file_id) {
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000471 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_), "%s",
niklase@google.com470e71d2011-07-07 08:21:25 +0000472 __FUNCTION__);
473
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000474 for (int id = 0; id < kViEMaxFilePlayers; id++) {
475 if (free_file_id_[id]) {
476 // We found a free capture device id.
477 free_file_id_[id] = false;
mflodman@webrtc.org8baed512012-06-21 12:11:50 +0000478 *free_file_id = id + kViEFileIdBase;
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000479 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_),
mflodman@webrtc.org8baed512012-06-21 12:11:50 +0000480 "%s: new id: %d", __FUNCTION__, *free_file_id);
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000481 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000482 }
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000483 }
484 return false;
niklase@google.com470e71d2011-07-07 08:21:25 +0000485}
486
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000487void ViEInputManager::ReturnFileId(int file_id) {
488 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(engine_id_),
489 "%s(%d)", __FUNCTION__, file_id);
niklase@google.com470e71d2011-07-07 08:21:25 +0000490
mflodman@webrtc.orgd32c4472011-12-22 14:17:53 +0000491 CriticalSectionScoped cs(map_cs_.get());
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000492 if (file_id >= kViEFileIdBase &&
493 file_id < kViEMaxFilePlayers + kViEFileIdBase) {
494 free_file_id_[file_id - kViEFileIdBase] = true;
495 }
496 return;
niklase@google.com470e71d2011-07-07 08:21:25 +0000497}
498
niklase@google.com470e71d2011-07-07 08:21:25 +0000499ViEFrameProviderBase* ViEInputManager::ViEFrameProvider(
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000500 const ViEFrameCallback* capture_observer) const {
501 assert(capture_observer);
mflodman@webrtc.orgd32c4472011-12-22 14:17:53 +0000502 CriticalSectionScoped cs(map_cs_.get());
niklase@google.com470e71d2011-07-07 08:21:25 +0000503
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000504 for (MapItem* provider_item = vie_frame_provider_map_.First(); provider_item
505 != NULL; provider_item = vie_frame_provider_map_.Next(provider_item)) {
506 ViEFrameProviderBase* vie_frame_provider =
507 static_cast<ViEFrameProviderBase*>(provider_item->GetItem());
508 assert(vie_frame_provider != NULL);
niklase@google.com470e71d2011-07-07 08:21:25 +0000509
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000510 if (vie_frame_provider->IsFrameCallbackRegistered(capture_observer)) {
511 // We found it.
512 return vie_frame_provider;
niklase@google.com470e71d2011-07-07 08:21:25 +0000513 }
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000514 }
515 // No capture device set for this channel.
516 return NULL;
517}
518
519ViEFrameProviderBase* ViEInputManager::ViEFrameProvider(int provider_id) const {
mflodman@webrtc.orgd32c4472011-12-22 14:17:53 +0000520 CriticalSectionScoped cs(map_cs_.get());
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000521 MapItem* map_item = vie_frame_provider_map_.Find(provider_id);
522 if (!map_item) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000523 return NULL;
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000524 }
525 ViEFrameProviderBase* vie_frame_provider =
526 static_cast<ViEFrameProviderBase*>(map_item->GetItem());
527 return vie_frame_provider;
niklase@google.com470e71d2011-07-07 08:21:25 +0000528}
529
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000530ViECapturer* ViEInputManager::ViECapturePtr(int capture_id) const {
531 if (!(capture_id >= kViECaptureIdBase &&
532 capture_id <= kViECaptureIdBase + kViEMaxCaptureDevices))
533 return NULL;
niklase@google.com470e71d2011-07-07 08:21:25 +0000534
mflodman@webrtc.orgd32c4472011-12-22 14:17:53 +0000535 CriticalSectionScoped cs(map_cs_.get());
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000536 MapItem* map_item = vie_frame_provider_map_.Find(capture_id);
537 if (!map_item) {
538 return NULL;
539 }
540 ViECapturer* vie_capture = static_cast<ViECapturer*>(map_item->GetItem());
541 return vie_capture;
niklase@google.com470e71d2011-07-07 08:21:25 +0000542}
543
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000544ViEFilePlayer* ViEInputManager::ViEFilePlayerPtr(int file_id) const {
545 if (file_id < kViEFileIdBase || file_id > kViEFileIdMax) {
546 return NULL;
547 }
mflodman@webrtc.orgd32c4472011-12-22 14:17:53 +0000548 CriticalSectionScoped cs(map_cs_.get());
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000549 MapItem* map_item = vie_frame_provider_map_.Find(file_id);
550 if (!map_item) {
551 return NULL;
552 }
553 ViEFilePlayer* vie_file_player =
554 static_cast<ViEFilePlayer*>(map_item->GetItem());
555 return vie_file_player;
niklase@google.com470e71d2011-07-07 08:21:25 +0000556}
557
niklase@google.com470e71d2011-07-07 08:21:25 +0000558ViEInputManagerScoped::ViEInputManagerScoped(
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000559 const ViEInputManager& vie_input_manager)
560 : ViEManagerScopedBase(vie_input_manager) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000561}
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000562
563ViECapturer* ViEInputManagerScoped::Capture(int capture_id) const {
564 return static_cast<const ViEInputManager*>(vie_manager_)->ViECapturePtr(
565 capture_id);
niklase@google.com470e71d2011-07-07 08:21:25 +0000566}
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000567
niklase@google.com470e71d2011-07-07 08:21:25 +0000568ViEFrameProviderBase* ViEInputManagerScoped::FrameProvider(
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000569 const ViEFrameCallback* capture_observer) const {
570 return static_cast<const ViEInputManager*>(vie_manager_)->ViEFrameProvider(
571 capture_observer);
niklase@google.com470e71d2011-07-07 08:21:25 +0000572}
573
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000574ViEFrameProviderBase* ViEInputManagerScoped::FrameProvider(
575 int provider_id) const {
576 return static_cast<const ViEInputManager*>(vie_manager_)->ViEFrameProvider(
577 provider_id);
niklase@google.com470e71d2011-07-07 08:21:25 +0000578}
579
mflodman@webrtc.orge8be22c2011-12-15 10:19:29 +0000580ViEFilePlayer* ViEInputManagerScoped::FilePlayer(int file_id) const {
581 return static_cast<const ViEInputManager*>(vie_manager_)->ViEFilePlayerPtr(
582 file_id);
583}
584
585} // namespace webrtc