niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 1 | /* |
mflodman@webrtc.org | c80d9d9 | 2012-02-06 10:11:25 +0000 | [diff] [blame] | 2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 3 | * |
| 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.org | f5d4cb1 | 2013-05-17 13:44:48 +0000 | [diff] [blame] | 11 | #include "webrtc/video_engine/vie_input_manager.h" |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 12 | |
pbos@webrtc.org | 12dc1a3 | 2013-08-05 16:22:53 +0000 | [diff] [blame] | 13 | #include <assert.h> |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 14 | |
pbos@webrtc.org | f5d4cb1 | 2013-05-17 13:44:48 +0000 | [diff] [blame] | 15 | #include "webrtc/common_types.h" |
andrew@webrtc.org | 94caca7 | 2012-10-30 21:58:00 +0000 | [diff] [blame] | 16 | #include "webrtc/modules/video_capture/include/video_capture_factory.h" |
pbos@webrtc.org | f5d4cb1 | 2013-05-17 13:44:48 +0000 | [diff] [blame] | 17 | #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.org | 5574dac | 2014-04-07 10:56:31 +0000 | [diff] [blame] | 20 | #include "webrtc/system_wrappers/interface/logging.h" |
pbos@webrtc.org | f5d4cb1 | 2013-05-17 13:44:48 +0000 | [diff] [blame] | 21 | #include "webrtc/system_wrappers/interface/rw_lock_wrapper.h" |
pbos@webrtc.org | f5d4cb1 | 2013-05-17 13:44:48 +0000 | [diff] [blame] | 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.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 25 | |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 26 | namespace webrtc { |
| 27 | |
andresp@webrtc.org | 7707d06 | 2013-05-13 10:50:50 +0000 | [diff] [blame] | 28 | ViEInputManager::ViEInputManager(const int engine_id, const Config& config) |
| 29 | : config_(config), |
| 30 | engine_id_(engine_id), |
mflodman@webrtc.org | d32c447 | 2011-12-22 14:17:53 +0000 | [diff] [blame] | 31 | map_cs_(CriticalSectionWrapper::CreateCriticalSection()), |
pbos@webrtc.org | 927296f | 2013-03-08 13:12:29 +0000 | [diff] [blame] | 32 | device_info_cs_(CriticalSectionWrapper::CreateCriticalSection()), |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 33 | vie_frame_provider_map_(), |
| 34 | capture_device_info_(NULL), |
| 35 | module_process_thread_(NULL) { |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 36 | for (int idx = 0; idx < kViEMaxCaptureDevices; idx++) { |
| 37 | free_capture_device_id_[idx] = true; |
| 38 | } |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 39 | } |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 40 | |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 41 | ViEInputManager::~ViEInputManager() { |
pbos@webrtc.org | 4ca7d3f | 2013-08-12 19:51:57 +0000 | [diff] [blame] | 42 | for (FrameProviderMap::iterator it = vie_frame_provider_map_.begin(); |
| 43 | it != vie_frame_provider_map_.end(); |
| 44 | ++it) { |
| 45 | delete it->second; |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 46 | } |
| 47 | |
pbos@webrtc.org | 4ca7d3f | 2013-08-12 19:51:57 +0000 | [diff] [blame] | 48 | delete capture_device_info_; |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 49 | } |
| 50 | void ViEInputManager::SetModuleProcessThread( |
mflodman@webrtc.org | 8baed51 | 2012-06-21 12:11:50 +0000 | [diff] [blame] | 51 | ProcessThread* module_process_thread) { |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 52 | assert(!module_process_thread_); |
mflodman@webrtc.org | 8baed51 | 2012-06-21 12:11:50 +0000 | [diff] [blame] | 53 | module_process_thread_ = module_process_thread; |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 54 | } |
| 55 | |
| 56 | int ViEInputManager::NumberOfCaptureDevices() { |
pbos@webrtc.org | 927296f | 2013-03-08 13:12:29 +0000 | [diff] [blame] | 57 | CriticalSectionScoped cs(device_info_cs_.get()); |
| 58 | if (capture_device_info_ == NULL) |
| 59 | capture_device_info_ = VideoCaptureFactory::CreateDeviceInfo( |
| 60 | ViEModuleId(engine_id_)); |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 61 | assert(capture_device_info_); |
| 62 | return capture_device_info_->NumberOfDevices(); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 63 | } |
| 64 | |
pbos@webrtc.org | b238d12 | 2013-04-09 13:41:51 +0000 | [diff] [blame] | 65 | int ViEInputManager::GetDeviceName(uint32_t device_number, |
leozwang@webrtc.org | 1745e93 | 2012-03-01 16:30:40 +0000 | [diff] [blame] | 66 | char* device_nameUTF8, |
pbos@webrtc.org | b238d12 | 2013-04-09 13:41:51 +0000 | [diff] [blame] | 67 | uint32_t device_name_length, |
leozwang@webrtc.org | 1745e93 | 2012-03-01 16:30:40 +0000 | [diff] [blame] | 68 | char* device_unique_idUTF8, |
pbos@webrtc.org | b238d12 | 2013-04-09 13:41:51 +0000 | [diff] [blame] | 69 | uint32_t device_unique_idUTF8Length) { |
pbos@webrtc.org | 927296f | 2013-03-08 13:12:29 +0000 | [diff] [blame] | 70 | CriticalSectionScoped cs(device_info_cs_.get()); |
| 71 | if (capture_device_info_ == NULL) |
| 72 | capture_device_info_ = VideoCaptureFactory::CreateDeviceInfo( |
| 73 | ViEModuleId(engine_id_)); |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 74 | assert(capture_device_info_); |
| 75 | return capture_device_info_->GetDeviceName(device_number, device_nameUTF8, |
| 76 | device_name_length, |
| 77 | device_unique_idUTF8, |
| 78 | device_unique_idUTF8Length); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 79 | } |
| 80 | |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 81 | int ViEInputManager::NumberOfCaptureCapabilities( |
leozwang@webrtc.org | 1745e93 | 2012-03-01 16:30:40 +0000 | [diff] [blame] | 82 | const char* device_unique_idUTF8) { |
pbos@webrtc.org | 927296f | 2013-03-08 13:12:29 +0000 | [diff] [blame] | 83 | CriticalSectionScoped cs(device_info_cs_.get()); |
| 84 | if (capture_device_info_ == NULL) |
| 85 | capture_device_info_ = VideoCaptureFactory::CreateDeviceInfo( |
| 86 | ViEModuleId(engine_id_)); |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 87 | assert(capture_device_info_); |
| 88 | return capture_device_info_->NumberOfCapabilities(device_unique_idUTF8); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 89 | } |
| 90 | |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 91 | int ViEInputManager::GetCaptureCapability( |
leozwang@webrtc.org | 1745e93 | 2012-03-01 16:30:40 +0000 | [diff] [blame] | 92 | const char* device_unique_idUTF8, |
pbos@webrtc.org | b238d12 | 2013-04-09 13:41:51 +0000 | [diff] [blame] | 93 | const uint32_t device_capability_number, |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 94 | CaptureCapability& capability) { |
pbos@webrtc.org | 927296f | 2013-03-08 13:12:29 +0000 | [diff] [blame] | 95 | CriticalSectionScoped cs(device_info_cs_.get()); |
| 96 | if (capture_device_info_ == NULL) |
| 97 | capture_device_info_ = VideoCaptureFactory::CreateDeviceInfo( |
| 98 | ViEModuleId(engine_id_)); |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 99 | assert(capture_device_info_); |
| 100 | VideoCaptureCapability module_capability; |
| 101 | int result = capture_device_info_->GetCapability(device_unique_idUTF8, |
| 102 | device_capability_number, |
| 103 | module_capability); |
| 104 | if (result != 0) |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 105 | return result; |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 106 | |
| 107 | // Copy from module type to public type. |
| 108 | capability.expectedCaptureDelay = module_capability.expectedCaptureDelay; |
| 109 | capability.height = module_capability.height; |
| 110 | capability.width = module_capability.width; |
| 111 | capability.interlaced = module_capability.interlaced; |
| 112 | capability.rawType = module_capability.rawType; |
| 113 | capability.codecType = module_capability.codecType; |
| 114 | capability.maxFPS = module_capability.maxFPS; |
| 115 | return result; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 116 | } |
| 117 | |
leozwang@webrtc.org | 1745e93 | 2012-03-01 16:30:40 +0000 | [diff] [blame] | 118 | int ViEInputManager::GetOrientation(const char* device_unique_idUTF8, |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 119 | RotateCapturedFrame& orientation) { |
pbos@webrtc.org | 927296f | 2013-03-08 13:12:29 +0000 | [diff] [blame] | 120 | CriticalSectionScoped cs(device_info_cs_.get()); |
| 121 | if (capture_device_info_ == NULL) |
| 122 | capture_device_info_ = VideoCaptureFactory::CreateDeviceInfo( |
| 123 | ViEModuleId(engine_id_)); |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 124 | assert(capture_device_info_); |
| 125 | VideoCaptureRotation module_orientation; |
| 126 | int result = capture_device_info_->GetOrientation(device_unique_idUTF8, |
| 127 | module_orientation); |
| 128 | // Copy from module type to public type. |
| 129 | switch (module_orientation) { |
| 130 | case kCameraRotate0: |
| 131 | orientation = RotateCapturedFrame_0; |
| 132 | break; |
| 133 | case kCameraRotate90: |
| 134 | orientation = RotateCapturedFrame_90; |
| 135 | break; |
| 136 | case kCameraRotate180: |
| 137 | orientation = RotateCapturedFrame_180; |
| 138 | break; |
| 139 | case kCameraRotate270: |
| 140 | orientation = RotateCapturedFrame_270; |
| 141 | break; |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 142 | } |
| 143 | return result; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 144 | } |
| 145 | |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 146 | int ViEInputManager::DisplayCaptureSettingsDialogBox( |
leozwang@webrtc.org | 1745e93 | 2012-03-01 16:30:40 +0000 | [diff] [blame] | 147 | const char* device_unique_idUTF8, |
| 148 | const char* dialog_titleUTF8, |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 149 | void* parent_window, |
pbos@webrtc.org | b238d12 | 2013-04-09 13:41:51 +0000 | [diff] [blame] | 150 | uint32_t positionX, |
| 151 | uint32_t positionY) { |
pbos@webrtc.org | 927296f | 2013-03-08 13:12:29 +0000 | [diff] [blame] | 152 | CriticalSectionScoped cs(device_info_cs_.get()); |
| 153 | if (capture_device_info_ == NULL) |
| 154 | capture_device_info_ = VideoCaptureFactory::CreateDeviceInfo( |
| 155 | ViEModuleId(engine_id_)); |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 156 | assert(capture_device_info_); |
| 157 | return capture_device_info_->DisplayCaptureSettingsDialogBox( |
| 158 | device_unique_idUTF8, dialog_titleUTF8, parent_window, positionX, |
| 159 | positionY); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 160 | } |
| 161 | |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 162 | int ViEInputManager::CreateCaptureDevice( |
leozwang@webrtc.org | 1745e93 | 2012-03-01 16:30:40 +0000 | [diff] [blame] | 163 | const char* device_unique_idUTF8, |
pbos@webrtc.org | b238d12 | 2013-04-09 13:41:51 +0000 | [diff] [blame] | 164 | const uint32_t device_unique_idUTF8Length, |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 165 | int& capture_id) { |
mflodman@webrtc.org | d32c447 | 2011-12-22 14:17:53 +0000 | [diff] [blame] | 166 | CriticalSectionScoped cs(map_cs_.get()); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 167 | |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 168 | // Make sure the device is not already allocated. |
pbos@webrtc.org | 4ca7d3f | 2013-08-12 19:51:57 +0000 | [diff] [blame] | 169 | for (FrameProviderMap::iterator it = vie_frame_provider_map_.begin(); |
| 170 | it != vie_frame_provider_map_.end(); |
| 171 | ++it) { |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 172 | // Make sure this is a capture device. |
pbos@webrtc.org | 4ca7d3f | 2013-08-12 19:51:57 +0000 | [diff] [blame] | 173 | if (it->first >= kViECaptureIdBase && it->first <= kViECaptureIdMax) { |
| 174 | ViECapturer* vie_capture = static_cast<ViECapturer*>(it->second); |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 175 | assert(vie_capture); |
| 176 | // TODO(mflodman) Can we change input to avoid this cast? |
| 177 | const char* device_name = |
| 178 | reinterpret_cast<const char*>(vie_capture->CurrentDeviceName()); |
pbos@webrtc.org | 4ca7d3f | 2013-08-12 19:51:57 +0000 | [diff] [blame] | 179 | if (strncmp(device_name, device_unique_idUTF8, |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 180 | strlen(device_name)) == 0) { |
| 181 | return kViECaptureDeviceAlreadyAllocated; |
| 182 | } |
| 183 | } |
| 184 | } |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 185 | |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 186 | // Make sure the device name is valid. |
| 187 | bool found_device = false; |
pbos@webrtc.org | 927296f | 2013-03-08 13:12:29 +0000 | [diff] [blame] | 188 | CriticalSectionScoped cs_devinfo(device_info_cs_.get()); |
| 189 | if (capture_device_info_ == NULL) |
| 190 | capture_device_info_ = VideoCaptureFactory::CreateDeviceInfo( |
| 191 | ViEModuleId(engine_id_)); |
| 192 | assert(capture_device_info_); |
pbos@webrtc.org | b238d12 | 2013-04-09 13:41:51 +0000 | [diff] [blame] | 193 | for (uint32_t device_index = 0; |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 194 | device_index < capture_device_info_->NumberOfDevices(); ++device_index) { |
| 195 | if (device_unique_idUTF8Length > kVideoCaptureUniqueNameLength) { |
| 196 | // User's string length is longer than the max. |
| 197 | return -1; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 198 | } |
| 199 | |
leozwang@webrtc.org | 1745e93 | 2012-03-01 16:30:40 +0000 | [diff] [blame] | 200 | char found_name[kVideoCaptureDeviceNameLength] = ""; |
| 201 | char found_unique_name[kVideoCaptureUniqueNameLength] = ""; |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 202 | capture_device_info_->GetDeviceName(device_index, found_name, |
| 203 | kVideoCaptureDeviceNameLength, |
| 204 | found_unique_name, |
| 205 | kVideoCaptureUniqueNameLength); |
| 206 | |
| 207 | // TODO(mflodman) Can we change input to avoid this cast? |
| 208 | const char* cast_id = reinterpret_cast<const char*>(device_unique_idUTF8); |
| 209 | if (strncmp(cast_id, reinterpret_cast<const char*>(found_unique_name), |
| 210 | strlen(cast_id)) == 0) { |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 211 | found_device = true; |
| 212 | break; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 213 | } |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 214 | } |
| 215 | if (!found_device) { |
pbos@webrtc.org | 4e2806d | 2014-05-14 08:02:22 +0000 | [diff] [blame] | 216 | LOG(LS_ERROR) << "Capture device not found: " << device_unique_idUTF8; |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 217 | return kViECaptureDeviceDoesNotExist; |
| 218 | } |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 219 | |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 220 | int newcapture_id = 0; |
pbos@webrtc.org | 4e2806d | 2014-05-14 08:02:22 +0000 | [diff] [blame] | 221 | if (!GetFreeCaptureId(&newcapture_id)) { |
| 222 | LOG(LS_ERROR) << "All capture devices already allocated."; |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 223 | return kViECaptureDeviceMaxNoDevicesAllocated; |
| 224 | } |
| 225 | ViECapturer* vie_capture = ViECapturer::CreateViECapture( |
andresp@webrtc.org | 7707d06 | 2013-05-13 10:50:50 +0000 | [diff] [blame] | 226 | newcapture_id, engine_id_, config_, device_unique_idUTF8, |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 227 | device_unique_idUTF8Length, *module_process_thread_); |
| 228 | if (!vie_capture) { |
pbos@webrtc.org | 4e2806d | 2014-05-14 08:02:22 +0000 | [diff] [blame] | 229 | ReturnCaptureId(newcapture_id); |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 230 | return kViECaptureDeviceUnknownError; |
| 231 | } |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 232 | |
pbos@webrtc.org | 4ca7d3f | 2013-08-12 19:51:57 +0000 | [diff] [blame] | 233 | vie_frame_provider_map_[newcapture_id] = vie_capture; |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 234 | capture_id = newcapture_id; |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 235 | return 0; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 236 | } |
| 237 | |
mflodman@webrtc.org | 8baed51 | 2012-06-21 12:11:50 +0000 | [diff] [blame] | 238 | int ViEInputManager::CreateCaptureDevice(VideoCaptureModule* capture_module, |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 239 | int& capture_id) { |
mflodman@webrtc.org | d32c447 | 2011-12-22 14:17:53 +0000 | [diff] [blame] | 240 | CriticalSectionScoped cs(map_cs_.get()); |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 241 | int newcapture_id = 0; |
mflodman@webrtc.org | 8baed51 | 2012-06-21 12:11:50 +0000 | [diff] [blame] | 242 | if (!GetFreeCaptureId(&newcapture_id)) { |
pbos@webrtc.org | 4e2806d | 2014-05-14 08:02:22 +0000 | [diff] [blame] | 243 | LOG(LS_ERROR) << "All capture devices already allocated."; |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 244 | return kViECaptureDeviceMaxNoDevicesAllocated; |
| 245 | } |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 246 | |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 247 | ViECapturer* vie_capture = ViECapturer::CreateViECapture( |
andresp@webrtc.org | 7707d06 | 2013-05-13 10:50:50 +0000 | [diff] [blame] | 248 | newcapture_id, engine_id_, config_, |
| 249 | capture_module, *module_process_thread_); |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 250 | if (!vie_capture) { |
pbos@webrtc.org | 4e2806d | 2014-05-14 08:02:22 +0000 | [diff] [blame] | 251 | ReturnCaptureId(newcapture_id); |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 252 | return kViECaptureDeviceUnknownError; |
| 253 | } |
pbos@webrtc.org | 4ca7d3f | 2013-08-12 19:51:57 +0000 | [diff] [blame] | 254 | vie_frame_provider_map_[newcapture_id] = vie_capture; |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 255 | capture_id = newcapture_id; |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 256 | return 0; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 257 | } |
| 258 | |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 259 | int ViEInputManager::DestroyCaptureDevice(const int capture_id) { |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 260 | ViECapturer* vie_capture = NULL; |
| 261 | { |
| 262 | // We need exclusive access to the object to delete it. |
| 263 | // Take this write lock first since the read lock is taken before map_cs_. |
mflodman@webrtc.org | cee447a | 2012-06-28 07:29:46 +0000 | [diff] [blame] | 264 | ViEManagerWriteScoped wl(this); |
mflodman@webrtc.org | d32c447 | 2011-12-22 14:17:53 +0000 | [diff] [blame] | 265 | CriticalSectionScoped cs(map_cs_.get()); |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 266 | |
| 267 | vie_capture = ViECapturePtr(capture_id); |
| 268 | if (!vie_capture) { |
pbos@webrtc.org | 4e2806d | 2014-05-14 08:02:22 +0000 | [diff] [blame] | 269 | LOG(LS_ERROR) << "No such capture device id: " << capture_id; |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 270 | return -1; |
| 271 | } |
pbos@webrtc.org | b238d12 | 2013-04-09 13:41:51 +0000 | [diff] [blame] | 272 | uint32_t num_callbacks = |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 273 | vie_capture->NumberOfRegisteredFrameCallbacks(); |
| 274 | if (num_callbacks > 0) { |
pbos@webrtc.org | 4e2806d | 2014-05-14 08:02:22 +0000 | [diff] [blame] | 275 | LOG(LS_WARNING) << num_callbacks << " still registered to capture id " |
| 276 | << capture_id << " when destroying capture device."; |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 277 | } |
pbos@webrtc.org | 4ca7d3f | 2013-08-12 19:51:57 +0000 | [diff] [blame] | 278 | vie_frame_provider_map_.erase(capture_id); |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 279 | ReturnCaptureId(capture_id); |
| 280 | // Leave cs before deleting the capture object. This is because deleting the |
| 281 | // object might cause deletions of renderers so we prefer to not have a lock |
| 282 | // at that time. |
| 283 | } |
| 284 | delete vie_capture; |
| 285 | return 0; |
| 286 | } |
| 287 | |
| 288 | int ViEInputManager::CreateExternalCaptureDevice( |
| 289 | ViEExternalCapture*& external_capture, |
| 290 | int& capture_id) { |
mflodman@webrtc.org | d32c447 | 2011-12-22 14:17:53 +0000 | [diff] [blame] | 291 | CriticalSectionScoped cs(map_cs_.get()); |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 292 | |
| 293 | int newcapture_id = 0; |
mflodman@webrtc.org | 8baed51 | 2012-06-21 12:11:50 +0000 | [diff] [blame] | 294 | if (GetFreeCaptureId(&newcapture_id) == false) { |
pbos@webrtc.org | 4e2806d | 2014-05-14 08:02:22 +0000 | [diff] [blame] | 295 | LOG(LS_ERROR) << "All capture devices already allocated."; |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 296 | return kViECaptureDeviceMaxNoDevicesAllocated; |
| 297 | } |
| 298 | |
| 299 | ViECapturer* vie_capture = ViECapturer::CreateViECapture( |
andresp@webrtc.org | 7707d06 | 2013-05-13 10:50:50 +0000 | [diff] [blame] | 300 | newcapture_id, engine_id_, config_, NULL, 0, *module_process_thread_); |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 301 | if (!vie_capture) { |
| 302 | ReturnCaptureId(newcapture_id); |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 303 | return kViECaptureDeviceUnknownError; |
| 304 | } |
| 305 | |
pbos@webrtc.org | 4ca7d3f | 2013-08-12 19:51:57 +0000 | [diff] [blame] | 306 | vie_frame_provider_map_[newcapture_id] = vie_capture; |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 307 | capture_id = newcapture_id; |
| 308 | external_capture = vie_capture; |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 309 | return 0; |
| 310 | } |
| 311 | |
mflodman@webrtc.org | 8baed51 | 2012-06-21 12:11:50 +0000 | [diff] [blame] | 312 | bool ViEInputManager::GetFreeCaptureId(int* freecapture_id) { |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 313 | for (int id = 0; id < kViEMaxCaptureDevices; id++) { |
| 314 | if (free_capture_device_id_[id]) { |
| 315 | // We found a free capture device id. |
| 316 | free_capture_device_id_[id] = false; |
mflodman@webrtc.org | 8baed51 | 2012-06-21 12:11:50 +0000 | [diff] [blame] | 317 | *freecapture_id = id + kViECaptureIdBase; |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 318 | return true; |
| 319 | } |
| 320 | } |
| 321 | return false; |
| 322 | } |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 323 | |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 324 | void ViEInputManager::ReturnCaptureId(int capture_id) { |
mflodman@webrtc.org | d32c447 | 2011-12-22 14:17:53 +0000 | [diff] [blame] | 325 | CriticalSectionScoped cs(map_cs_.get()); |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 326 | if (capture_id >= kViECaptureIdBase && |
| 327 | capture_id < kViEMaxCaptureDevices + kViECaptureIdBase) { |
| 328 | free_capture_device_id_[capture_id - kViECaptureIdBase] = true; |
| 329 | } |
| 330 | return; |
| 331 | } |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 332 | |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 333 | ViEFrameProviderBase* ViEInputManager::ViEFrameProvider( |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 334 | const ViEFrameCallback* capture_observer) const { |
| 335 | assert(capture_observer); |
mflodman@webrtc.org | d32c447 | 2011-12-22 14:17:53 +0000 | [diff] [blame] | 336 | CriticalSectionScoped cs(map_cs_.get()); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 337 | |
pbos@webrtc.org | 4ca7d3f | 2013-08-12 19:51:57 +0000 | [diff] [blame] | 338 | for (FrameProviderMap::const_iterator it = vie_frame_provider_map_.begin(); |
| 339 | it != vie_frame_provider_map_.end(); |
| 340 | ++it) { |
| 341 | if (it->second->IsFrameCallbackRegistered(capture_observer)) |
| 342 | return it->second; |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 343 | } |
pbos@webrtc.org | 4ca7d3f | 2013-08-12 19:51:57 +0000 | [diff] [blame] | 344 | |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 345 | // No capture device set for this channel. |
| 346 | return NULL; |
| 347 | } |
| 348 | |
| 349 | ViEFrameProviderBase* ViEInputManager::ViEFrameProvider(int provider_id) const { |
mflodman@webrtc.org | d32c447 | 2011-12-22 14:17:53 +0000 | [diff] [blame] | 350 | CriticalSectionScoped cs(map_cs_.get()); |
pbos@webrtc.org | 4ca7d3f | 2013-08-12 19:51:57 +0000 | [diff] [blame] | 351 | |
| 352 | FrameProviderMap::const_iterator it = |
| 353 | vie_frame_provider_map_.find(provider_id); |
| 354 | if (it == vie_frame_provider_map_.end()) |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 355 | return NULL; |
pbos@webrtc.org | 4ca7d3f | 2013-08-12 19:51:57 +0000 | [diff] [blame] | 356 | return it->second; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 357 | } |
| 358 | |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 359 | ViECapturer* ViEInputManager::ViECapturePtr(int capture_id) const { |
| 360 | if (!(capture_id >= kViECaptureIdBase && |
mflodman@webrtc.org | 5574dac | 2014-04-07 10:56:31 +0000 | [diff] [blame] | 361 | capture_id <= kViECaptureIdBase + kViEMaxCaptureDevices)) { |
| 362 | LOG(LS_ERROR) << "Capture device doesn't exist " << capture_id << "."; |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 363 | return NULL; |
mflodman@webrtc.org | 5574dac | 2014-04-07 10:56:31 +0000 | [diff] [blame] | 364 | } |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 365 | |
pbos@webrtc.org | 4ca7d3f | 2013-08-12 19:51:57 +0000 | [diff] [blame] | 366 | return static_cast<ViECapturer*>(ViEFrameProvider(capture_id)); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 367 | } |
| 368 | |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 369 | ViEInputManagerScoped::ViEInputManagerScoped( |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 370 | const ViEInputManager& vie_input_manager) |
| 371 | : ViEManagerScopedBase(vie_input_manager) { |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 372 | } |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 373 | |
| 374 | ViECapturer* ViEInputManagerScoped::Capture(int capture_id) const { |
| 375 | return static_cast<const ViEInputManager*>(vie_manager_)->ViECapturePtr( |
| 376 | capture_id); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 377 | } |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 378 | |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 379 | ViEFrameProviderBase* ViEInputManagerScoped::FrameProvider( |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 380 | const ViEFrameCallback* capture_observer) const { |
| 381 | return static_cast<const ViEInputManager*>(vie_manager_)->ViEFrameProvider( |
| 382 | capture_observer); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 383 | } |
| 384 | |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 385 | ViEFrameProviderBase* ViEInputManagerScoped::FrameProvider( |
| 386 | int provider_id) const { |
| 387 | return static_cast<const ViEInputManager*>(vie_manager_)->ViEFrameProvider( |
| 388 | provider_id); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 389 | } |
| 390 | |
mflodman@webrtc.org | e8be22c | 2011-12-15 10:19:29 +0000 | [diff] [blame] | 391 | } // namespace webrtc |