Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(128)

Side by Side Diff: talk/media/devices/devicemanager.cc

Issue 1587193006: Move talk/media to webrtc/media (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Rebased to b647aca12a884a13c1728118586245399b55fa3d (#11493) Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « talk/media/devices/devicemanager.h ('k') | talk/media/devices/devicemanager_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * libjingle
3 * Copyright 2004 Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #include "talk/media/devices/devicemanager.h"
29
30 #include "talk/media/base/mediacommon.h"
31 #include "talk/media/base/videocapturerfactory.h"
32 #include "talk/media/devices/deviceinfo.h"
33 #include "talk/media/devices/filevideocapturer.h"
34 #include "talk/media/devices/yuvframescapturer.h"
35 #include "webrtc/base/fileutils.h"
36 #include "webrtc/base/logging.h"
37 #include "webrtc/base/pathutils.h"
38 #include "webrtc/base/stringutils.h"
39 #include "webrtc/base/thread.h"
40 #include "webrtc/base/windowpicker.h"
41 #include "webrtc/base/windowpickerfactory.h"
42
43 #ifdef HAVE_WEBRTC_VIDEO
44 #include "talk/media/webrtc/webrtcvideocapturerfactory.h"
45 #endif // HAVE_WEBRTC_VIDEO
46
47 namespace {
48
49 bool StringMatchWithWildcard(
50 const std::pair<const std::basic_string<char>, cricket::VideoFormat> key,
51 const std::string& val) {
52 return rtc::string_match(val.c_str(), key.first.c_str());
53 }
54
55 } // namespace
56
57 namespace cricket {
58
59 // Initialize to empty string.
60 const char DeviceManagerInterface::kDefaultDeviceName[] = "";
61
62 DeviceManager::DeviceManager()
63 : initialized_(false),
64 window_picker_(rtc::WindowPickerFactory::CreateWindowPicker()) {
65 #ifdef HAVE_WEBRTC_VIDEO
66 SetVideoDeviceCapturerFactory(new WebRtcVideoDeviceCapturerFactory());
67 #endif // HAVE_WEBRTC_VIDEO
68 }
69
70 DeviceManager::~DeviceManager() {
71 if (initialized()) {
72 Terminate();
73 }
74 }
75
76 bool DeviceManager::Init() {
77 if (!initialized()) {
78 if (!watcher()->Start()) {
79 return false;
80 }
81 set_initialized(true);
82 }
83 return true;
84 }
85
86 void DeviceManager::Terminate() {
87 if (initialized()) {
88 watcher()->Stop();
89 set_initialized(false);
90 }
91 }
92
93 int DeviceManager::GetCapabilities() {
94 std::vector<Device> devices;
95 int caps = VIDEO_RECV;
96 if (GetAudioInputDevices(&devices) && !devices.empty()) {
97 caps |= AUDIO_SEND;
98 }
99 if (GetAudioOutputDevices(&devices) && !devices.empty()) {
100 caps |= AUDIO_RECV;
101 }
102 if (GetVideoCaptureDevices(&devices) && !devices.empty()) {
103 caps |= VIDEO_SEND;
104 }
105 return caps;
106 }
107
108 bool DeviceManager::GetAudioInputDevices(std::vector<Device>* devices) {
109 return GetAudioDevices(true, devices);
110 }
111
112 bool DeviceManager::GetAudioOutputDevices(std::vector<Device>* devices) {
113 return GetAudioDevices(false, devices);
114 }
115
116 bool DeviceManager::GetAudioInputDevice(const std::string& name, Device* out) {
117 return GetAudioDevice(true, name, out);
118 }
119
120 bool DeviceManager::GetAudioOutputDevice(const std::string& name, Device* out) {
121 return GetAudioDevice(false, name, out);
122 }
123
124 bool DeviceManager::GetVideoCaptureDevices(std::vector<Device>* devices) {
125 devices->clear();
126 #if defined(ANDROID) || defined(WEBRTC_IOS)
127 // On Android and iOS, we treat the camera(s) as a single device. Even if
128 // there are multiple cameras, that's abstracted away at a higher level.
129 Device dev("camera", "1"); // name and ID
130 devices->push_back(dev);
131 return true;
132 #else
133 return false;
134 #endif
135 }
136
137 bool DeviceManager::GetVideoCaptureDevice(const std::string& name,
138 Device* out) {
139 // If the name is empty, return the default device.
140 if (name.empty() || name == kDefaultDeviceName) {
141 return GetDefaultVideoCaptureDevice(out);
142 }
143
144 std::vector<Device> devices;
145 if (!GetVideoCaptureDevices(&devices)) {
146 return false;
147 }
148
149 for (std::vector<Device>::const_iterator it = devices.begin();
150 it != devices.end(); ++it) {
151 if (name == it->name) {
152 *out = *it;
153 return true;
154 }
155 }
156
157 // If |name| is a valid name for a file or yuvframedevice,
158 // return a fake video capturer device.
159 if (GetFakeVideoCaptureDevice(name, out)) {
160 return true;
161 }
162
163 return false;
164 }
165
166 bool DeviceManager::GetFakeVideoCaptureDevice(const std::string& name,
167 Device* out) const {
168 if (rtc::Filesystem::IsFile(name)) {
169 *out = FileVideoCapturer::CreateFileVideoCapturerDevice(name);
170 return true;
171 }
172
173 if (name == YuvFramesCapturer::kYuvFrameDeviceName) {
174 *out = YuvFramesCapturer::CreateYuvFramesCapturerDevice();
175 return true;
176 }
177
178 return false;
179 }
180
181 void DeviceManager::SetVideoCaptureDeviceMaxFormat(
182 const std::string& usb_id,
183 const VideoFormat& max_format) {
184 max_formats_[usb_id] = max_format;
185 }
186
187 void DeviceManager::ClearVideoCaptureDeviceMaxFormat(
188 const std::string& usb_id) {
189 max_formats_.erase(usb_id);
190 }
191
192 VideoCapturer* DeviceManager::CreateVideoCapturer(const Device& device) const {
193 VideoCapturer* capturer = MaybeConstructFakeVideoCapturer(device);
194 if (capturer) {
195 return capturer;
196 }
197
198 if (!video_device_capturer_factory_) {
199 LOG(LS_ERROR) << "No video capturer factory for devices.";
200 return NULL;
201 }
202 capturer = video_device_capturer_factory_->Create(device);
203 if (!capturer) {
204 return NULL;
205 }
206 LOG(LS_INFO) << "Created VideoCapturer for " << device.name;
207 VideoFormat video_format;
208 bool has_max = GetMaxFormat(device, &video_format);
209 capturer->set_enable_camera_list(has_max);
210 if (has_max) {
211 capturer->ConstrainSupportedFormats(video_format);
212 }
213 return capturer;
214 }
215
216 VideoCapturer* DeviceManager::MaybeConstructFakeVideoCapturer(
217 const Device& device) const {
218 // TODO(hellner): Throw out the creation of a file video capturer once the
219 // refactoring is completed.
220 if (FileVideoCapturer::IsFileVideoCapturerDevice(device)) {
221 FileVideoCapturer* capturer = new FileVideoCapturer;
222 if (!capturer->Init(device)) {
223 delete capturer;
224 return NULL;
225 }
226 LOG(LS_INFO) << "Created file video capturer " << device.name;
227 capturer->set_repeat(FileVideoCapturer::kForever);
228 return capturer;
229 }
230
231 if (YuvFramesCapturer::IsYuvFramesCapturerDevice(device)) {
232 YuvFramesCapturer* capturer = new YuvFramesCapturer();
233 capturer->Init();
234 return capturer;
235 }
236 return NULL;
237 }
238
239 bool DeviceManager::GetWindows(
240 std::vector<rtc::WindowDescription>* descriptions) {
241 if (!window_picker_) {
242 return false;
243 }
244 return window_picker_->GetWindowList(descriptions);
245 }
246
247 bool DeviceManager::GetDesktops(
248 std::vector<rtc::DesktopDescription>* descriptions) {
249 if (!window_picker_) {
250 return false;
251 }
252 return window_picker_->GetDesktopList(descriptions);
253 }
254
255 VideoCapturer* DeviceManager::CreateScreenCapturer(
256 const ScreencastId& screenid) const {
257 if (!screen_capturer_factory_) {
258 LOG(LS_ERROR) << "No video capturer factory for screens.";
259 return NULL;
260 }
261 return screen_capturer_factory_->Create(screenid);
262 }
263
264 bool DeviceManager::GetAudioDevices(bool input,
265 std::vector<Device>* devs) {
266 devs->clear();
267 #if defined(ANDROID)
268 // Under Android, 0 is always required for the playout device and 0 is the
269 // default for the recording device.
270 devs->push_back(Device("default-device", 0));
271 return true;
272 #else
273 // Other platforms either have their own derived class implementation
274 // (desktop) or don't use device manager for audio devices (iOS).
275 return false;
276 #endif
277 }
278
279 bool DeviceManager::GetAudioDevice(bool is_input, const std::string& name,
280 Device* out) {
281 // If the name is empty, return the default device id.
282 if (name.empty() || name == kDefaultDeviceName) {
283 *out = Device(name, -1);
284 return true;
285 }
286
287 std::vector<Device> devices;
288 bool ret = is_input ? GetAudioInputDevices(&devices) :
289 GetAudioOutputDevices(&devices);
290 if (ret) {
291 ret = false;
292 for (size_t i = 0; i < devices.size(); ++i) {
293 if (devices[i].name == name) {
294 *out = devices[i];
295 ret = true;
296 break;
297 }
298 }
299 }
300 return ret;
301 }
302
303 bool DeviceManager::GetDefaultVideoCaptureDevice(Device* device) {
304 bool ret = false;
305 // We just return the first device.
306 std::vector<Device> devices;
307 ret = (GetVideoCaptureDevices(&devices) && !devices.empty());
308 if (ret) {
309 *device = devices[0];
310 }
311 return ret;
312 }
313
314 bool DeviceManager::IsInWhitelist(const std::string& key,
315 VideoFormat* video_format) const {
316 std::map<std::string, VideoFormat>::const_iterator found =
317 std::search_n(max_formats_.begin(), max_formats_.end(), 1, key,
318 StringMatchWithWildcard);
319 if (found == max_formats_.end()) {
320 return false;
321 }
322 *video_format = found->second;
323 return true;
324 }
325
326 bool DeviceManager::GetMaxFormat(const Device& device,
327 VideoFormat* video_format) const {
328 // Match USB ID if available. Failing that, match device name.
329 std::string usb_id;
330 if (GetUsbId(device, &usb_id) && IsInWhitelist(usb_id, video_format)) {
331 return true;
332 }
333 return IsInWhitelist(device.name, video_format);
334 }
335
336 bool DeviceManager::ShouldDeviceBeIgnored(const std::string& device_name,
337 const char* const exclusion_list[]) {
338 // If exclusion_list is empty return directly.
339 if (!exclusion_list)
340 return false;
341
342 int i = 0;
343 while (exclusion_list[i]) {
344 if (strnicmp(device_name.c_str(), exclusion_list[i],
345 strlen(exclusion_list[i])) == 0) {
346 LOG(LS_INFO) << "Ignoring device " << device_name;
347 return true;
348 }
349 ++i;
350 }
351 return false;
352 }
353
354 bool DeviceManager::FilterDevices(std::vector<Device>* devices,
355 const char* const exclusion_list[]) {
356 if (!devices) {
357 return false;
358 }
359
360 for (std::vector<Device>::iterator it = devices->begin();
361 it != devices->end(); ) {
362 if (ShouldDeviceBeIgnored(it->name, exclusion_list)) {
363 it = devices->erase(it);
364 } else {
365 ++it;
366 }
367 }
368 return true;
369 }
370
371 } // namespace cricket
OLDNEW
« no previous file with comments | « talk/media/devices/devicemanager.h ('k') | talk/media/devices/devicemanager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698