Note: We no longer publish the latest version of our code here. We primarily use a kumc-bmi github organization. The heron ETL repository, in particular, is not public. Peers in the informatics community should see MultiSiteDev for details on requesting access.

source: webrtc/webrtc/modules/video_capture/device_info_impl.cc @ 0:4bda6873e34c

pub_scrub_3792 tip
Last change on this file since 0:4bda6873e34c was 0:4bda6873e34c, checked in by Michael Prittie <mprittie@…>, 6 years ago

Scrubbed password for publication.

File size: 14.6 KB
Line 
1/*
2 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
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
11#include <stdlib.h>
12
13#include "webrtc/modules/video_capture/device_info_impl.h"
14#include "webrtc/modules/video_capture/video_capture_config.h"
15#include "webrtc/system_wrappers/interface/trace.h"
16
17#ifndef abs
18#define abs(a) (a>=0?a:-a)
19#endif
20
21namespace webrtc
22{
23namespace videocapturemodule
24{
25DeviceInfoImpl::DeviceInfoImpl(const int32_t id)
26    : _id(id), _apiLock(*RWLockWrapper::CreateRWLock()), _lastUsedDeviceName(NULL),
27      _lastUsedDeviceNameLength(0)
28{
29}
30
31DeviceInfoImpl::~DeviceInfoImpl(void)
32{
33    _apiLock.AcquireLockExclusive();
34    free(_lastUsedDeviceName);
35    _apiLock.ReleaseLockExclusive();
36
37    delete &_apiLock;
38}
39int32_t DeviceInfoImpl::NumberOfCapabilities(
40                                        const char* deviceUniqueIdUTF8)
41{
42
43    if (!deviceUniqueIdUTF8)
44        return -1;
45
46    _apiLock.AcquireLockShared();
47
48    if (_lastUsedDeviceNameLength == strlen((char*) deviceUniqueIdUTF8))
49    {
50        // Is it the same device that is asked for again.
51#if defined(WEBRTC_MAC) || defined(WEBRTC_LINUX)
52        if(strncasecmp((char*)_lastUsedDeviceName,
53                       (char*) deviceUniqueIdUTF8,
54                       _lastUsedDeviceNameLength)==0)
55#else
56        if (_strnicmp((char*) _lastUsedDeviceName,
57                      (char*) deviceUniqueIdUTF8,
58                      _lastUsedDeviceNameLength) == 0)
59#endif
60        {
61            //yes
62            _apiLock.ReleaseLockShared();
63            return static_cast<int32_t>(_captureCapabilities.size());
64        }
65    }
66    // Need to get exclusive rights to create the new capability map.
67    _apiLock.ReleaseLockShared();
68    WriteLockScoped cs2(_apiLock);
69
70    int32_t ret = CreateCapabilityMap(deviceUniqueIdUTF8);
71    return ret;
72}
73
74int32_t DeviceInfoImpl::GetCapability(const char* deviceUniqueIdUTF8,
75                                      const uint32_t deviceCapabilityNumber,
76                                      VideoCaptureCapability& capability)
77{
78
79    if (!deviceUniqueIdUTF8)
80    {
81        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
82                   "deviceUniqueIdUTF8 parameter not set in call to GetCapability");
83        return -1;
84    }
85    ReadLockScoped cs(_apiLock);
86
87    if ((_lastUsedDeviceNameLength != strlen((char*) deviceUniqueIdUTF8))
88#if defined(WEBRTC_MAC) || defined(WEBRTC_LINUX)
89        || (strncasecmp((char*)_lastUsedDeviceName,
90                        (char*) deviceUniqueIdUTF8,
91                        _lastUsedDeviceNameLength)!=0))
92#else
93        || (_strnicmp((char*) _lastUsedDeviceName,
94                      (char*) deviceUniqueIdUTF8,
95                      _lastUsedDeviceNameLength) != 0))
96#endif
97
98    {
99        _apiLock.ReleaseLockShared();
100        _apiLock.AcquireLockExclusive();
101        if (-1 == CreateCapabilityMap(deviceUniqueIdUTF8))
102        {
103            _apiLock.ReleaseLockExclusive();
104            _apiLock.AcquireLockShared();
105            return -1;
106        }
107        _apiLock.ReleaseLockExclusive();
108        _apiLock.AcquireLockShared();
109    }
110
111    // Make sure the number is valid
112    if (deviceCapabilityNumber >= (unsigned int) _captureCapabilities.size())
113    {
114        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
115                   "deviceCapabilityNumber %d is invalid in call to GetCapability",
116                   deviceCapabilityNumber);
117        return -1;
118    }
119
120    capability = _captureCapabilities[deviceCapabilityNumber];
121    return 0;
122}
123
124int32_t DeviceInfoImpl::GetBestMatchedCapability(
125                                        const char*deviceUniqueIdUTF8,
126                                        const VideoCaptureCapability& requested,
127                                        VideoCaptureCapability& resulting)
128{
129
130
131    if (!deviceUniqueIdUTF8)
132        return -1;
133
134    ReadLockScoped cs(_apiLock);
135    if ((_lastUsedDeviceNameLength != strlen((char*) deviceUniqueIdUTF8))
136#if defined(WEBRTC_MAC) || defined(WEBRTC_LINUX)
137        || (strncasecmp((char*)_lastUsedDeviceName,
138                        (char*) deviceUniqueIdUTF8,
139                        _lastUsedDeviceNameLength)!=0))
140#else
141        || (_strnicmp((char*) _lastUsedDeviceName,
142                      (char*) deviceUniqueIdUTF8,
143                      _lastUsedDeviceNameLength) != 0))
144#endif
145    {
146        _apiLock.ReleaseLockShared();
147        _apiLock.AcquireLockExclusive();
148        if (-1 == CreateCapabilityMap(deviceUniqueIdUTF8))
149        {
150            return -1;
151        }
152        _apiLock.ReleaseLockExclusive();
153        _apiLock.AcquireLockShared();
154    }
155
156    int32_t bestformatIndex = -1;
157    int32_t bestWidth = 0;
158    int32_t bestHeight = 0;
159    int32_t bestFrameRate = 0;
160    RawVideoType bestRawType = kVideoUnknown;
161    webrtc::VideoCodecType bestCodecType = webrtc::kVideoCodecUnknown;
162
163    const int32_t numberOfCapabilies =
164        static_cast<int32_t>(_captureCapabilities.size());
165
166    for (int32_t tmp = 0; tmp < numberOfCapabilies; ++tmp) // Loop through all capabilities
167    {
168        VideoCaptureCapability& capability = _captureCapabilities[tmp];
169
170        const int32_t diffWidth = capability.width - requested.width;
171        const int32_t diffHeight = capability.height - requested.height;
172        const int32_t diffFrameRate = capability.maxFPS - requested.maxFPS;
173
174        const int32_t currentbestDiffWith = bestWidth - requested.width;
175        const int32_t currentbestDiffHeight = bestHeight - requested.height;
176        const int32_t currentbestDiffFrameRate = bestFrameRate - requested.maxFPS;
177
178        if ((diffHeight >= 0 && diffHeight <= abs(currentbestDiffHeight)) // Height better or equalt that previouse.
179            || (currentbestDiffHeight < 0 && diffHeight >= currentbestDiffHeight))
180        {
181
182            if (diffHeight == currentbestDiffHeight) // Found best height. Care about the width)
183            {
184                if ((diffWidth >= 0 && diffWidth <= abs(currentbestDiffWith)) // Width better or equal
185                    || (currentbestDiffWith < 0 && diffWidth >= currentbestDiffWith))
186                {
187                    if (diffWidth == currentbestDiffWith && diffHeight
188                        == currentbestDiffHeight) // Same size as previously
189                    {
190                        //Also check the best frame rate if the diff is the same as previouse
191                        if (((diffFrameRate >= 0 &&
192                              diffFrameRate <= currentbestDiffFrameRate) // Frame rate to high but better match than previouse and we have not selected IUV
193                            ||
194                            (currentbestDiffFrameRate < 0 &&
195                             diffFrameRate >= currentbestDiffFrameRate)) // Current frame rate is lower than requested. This is better.
196                        )
197                        {
198                            if ((currentbestDiffFrameRate == diffFrameRate) // Same frame rate as previous  or frame rate allready good enough
199                                || (currentbestDiffFrameRate >= 0))
200                            {
201                                if (bestRawType != requested.rawType
202                                    && requested.rawType != kVideoUnknown
203                                    && (capability.rawType == requested.rawType
204                                        || capability.rawType == kVideoI420
205                                        || capability.rawType == kVideoYUY2
206                                        || capability.rawType == kVideoYV12))
207                                {
208                                    bestCodecType = capability.codecType;
209                                    bestRawType = capability.rawType;
210                                    bestformatIndex = tmp;
211                                }
212                                // If width height and frame rate is full filled we can use the camera for encoding if it is supported.
213                                if (capability.height == requested.height
214                                    && capability.width == requested.width
215                                    && capability.maxFPS >= requested.maxFPS)
216                                {
217                                    if (capability.codecType == requested.codecType
218                                        && bestCodecType != requested.codecType)
219                                    {
220                                        bestCodecType = capability.codecType;
221                                        bestformatIndex = tmp;
222                                    }
223                                }
224                            }
225                            else // Better frame rate
226                            {
227                                if (requested.codecType == capability.codecType)
228                                {
229
230                                    bestWidth = capability.width;
231                                    bestHeight = capability.height;
232                                    bestFrameRate = capability.maxFPS;
233                                    bestCodecType = capability.codecType;
234                                    bestRawType = capability.rawType;
235                                    bestformatIndex = tmp;
236                                }
237                            }
238                        }
239                    }
240                    else // Better width than previously
241                    {
242                        if (requested.codecType == capability.codecType)
243                        {
244                            bestWidth = capability.width;
245                            bestHeight = capability.height;
246                            bestFrameRate = capability.maxFPS;
247                            bestCodecType = capability.codecType;
248                            bestRawType = capability.rawType;
249                            bestformatIndex = tmp;
250                        }
251                    }
252                }// else width no good
253            }
254            else // Better height
255            {
256                if (requested.codecType == capability.codecType)
257                {
258                    bestWidth = capability.width;
259                    bestHeight = capability.height;
260                    bestFrameRate = capability.maxFPS;
261                    bestCodecType = capability.codecType;
262                    bestRawType = capability.rawType;
263                    bestformatIndex = tmp;
264                }
265            }
266        }// else height not good
267    }//end for
268
269    WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id,
270               "Best camera format: Width %d, Height %d, Frame rate %d, Color format %d",
271               bestWidth, bestHeight, bestFrameRate, bestRawType);
272
273    // Copy the capability
274    if (bestformatIndex < 0)
275        return -1;
276    resulting = _captureCapabilities[bestformatIndex];
277    return bestformatIndex;
278}
279
280/* Returns the expected Capture delay*/
281int32_t DeviceInfoImpl::GetExpectedCaptureDelay(
282                                          const DelayValues delayValues[],
283                                          const uint32_t sizeOfDelayValues,
284                                          const char* productId,
285                                          const uint32_t width,
286                                          const uint32_t height)
287{
288    int32_t bestDelay = kDefaultCaptureDelay;
289
290    for (uint32_t device = 0; device < sizeOfDelayValues; ++device)
291    {
292        if (delayValues[device].productId && strncmp((char*) productId,
293                                                     (char*) delayValues[device].productId,
294                                                     kVideoCaptureProductIdLength) == 0)
295        {
296            // We have found the camera
297
298            int32_t bestWidth = 0;
299            int32_t bestHeight = 0;
300
301            //Loop through all tested sizes and find one that seems fitting
302            for (uint32_t delayIndex = 0; delayIndex < NoOfDelayValues; ++delayIndex)
303            {
304                const DelayValue& currentValue = delayValues[device].delayValues[delayIndex];
305
306                const int32_t diffWidth = currentValue.width - width;
307                const int32_t diffHeight = currentValue.height - height;
308
309                const int32_t currentbestDiffWith = bestWidth - width;
310                const int32_t currentbestDiffHeight = bestHeight - height;
311
312                if ((diffHeight >= 0 && diffHeight <= abs(currentbestDiffHeight)) // Height better or equal than previous.
313                    || (currentbestDiffHeight < 0 && diffHeight >= currentbestDiffHeight))
314                {
315
316                    if (diffHeight == currentbestDiffHeight) // Found best height. Care about the width)
317                    {
318                        if ((diffWidth >= 0 && diffWidth <= abs(currentbestDiffWith)) // Width better or equal
319                            || (currentbestDiffWith < 0 && diffWidth >= currentbestDiffWith))
320                        {
321                            if (diffWidth == currentbestDiffWith && diffHeight
322                                == currentbestDiffHeight) // Same size as previous
323                            {
324                            }
325                            else // Better width than previously
326                            {
327                                bestWidth = currentValue.width;
328                                bestHeight = currentValue.height;
329                                bestDelay = currentValue.delay;
330                            }
331                        }// else width no good
332                    }
333                    else // Better height
334                    {
335                        bestWidth = currentValue.width;
336                        bestHeight = currentValue.height;
337                        bestDelay = currentValue.delay;
338                    }
339                }// else height not good
340            }//end for
341            break;
342        }
343    }
344    if (bestDelay > kMaxCaptureDelay)
345    {
346        WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCapture, _id,
347                   "Expected capture delay too high. %dms, will use %d", bestDelay,
348                   kMaxCaptureDelay);
349        bestDelay = kMaxCaptureDelay;
350
351    }
352
353    return bestDelay;
354
355}
356
357//Default implementation. This should be overridden by Mobile implementations.
358int32_t DeviceInfoImpl::GetOrientation(const char* deviceUniqueIdUTF8,
359                                       VideoCaptureRotation& orientation)
360{
361    orientation = kCameraRotate0;
362    return -1;
363}
364}  // namespace videocapturemodule
365}  // namespace webrtc
Note: See TracBrowser for help on using the repository browser.