1470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/*
212984f0d0236af77e6e56491298b3bf2cbd74ea9mallinath@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
4470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  Use of this source code is governed by a BSD-style license
5470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  that can be found in the LICENSE file in the root of the source
6470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  tree. An additional intellectual property rights grant can be found
7470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  in the file PATENTS.  All contributing project authors may
8470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  be found in the AUTHORS file in the root of the source tree.
9470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
10470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
113d5cb33da4df7eae70c21ba7fd0604fb93c6cedbpbos@webrtc.org#include <assert.h>
12470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include <stdlib.h>
13470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
14a9b74ad716031e7ce63ae0b792b1ba4d2b223d13pbos@webrtc.org#include "webrtc/modules/video_capture/device_info_impl.h"
15a9b74ad716031e7ce63ae0b792b1ba4d2b223d13pbos@webrtc.org#include "webrtc/modules/video_capture/video_capture_config.h"
1698f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/logging.h"
17a9b74ad716031e7ce63ae0b792b1ba4d2b223d13pbos@webrtc.org
18470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifndef abs
19470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#define abs(a) (a>=0?a:-a)
20470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif
21470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
22470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comnamespace webrtc
23470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
24470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comnamespace videocapturemodule
25470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
26dfc5bb9c97fdd8df3cd86afe2b378ebf89cea628pbos@webrtc.orgDeviceInfoImpl::DeviceInfoImpl(const int32_t id)
27470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    : _id(id), _apiLock(*RWLockWrapper::CreateRWLock()), _lastUsedDeviceName(NULL),
28470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      _lastUsedDeviceNameLength(0)
29470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
30470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
31470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
32470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comDeviceInfoImpl::~DeviceInfoImpl(void)
33470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
34470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    _apiLock.AcquireLockExclusive();
35470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    free(_lastUsedDeviceName);
36470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    _apiLock.ReleaseLockExclusive();
37470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
38470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    delete &_apiLock;
39470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
40dfc5bb9c97fdd8df3cd86afe2b378ebf89cea628pbos@webrtc.orgint32_t DeviceInfoImpl::NumberOfCapabilities(
411745e932cc560e50d764f6f0fbdc4d5b8bf20e4aleozwang@webrtc.org                                        const char* deviceUniqueIdUTF8)
42470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
43470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
44470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    if (!deviceUniqueIdUTF8)
45470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        return -1;
46470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
47470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    _apiLock.AcquireLockShared();
48470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
49470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    if (_lastUsedDeviceNameLength == strlen((char*) deviceUniqueIdUTF8))
50470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    {
51470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        // Is it the same device that is asked for again.
52f3b65dbfe8a8d88f623d962f8ced78ce764d518eandrew@webrtc.org#if defined(WEBRTC_MAC) || defined(WEBRTC_LINUX)
53470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        if(strncasecmp((char*)_lastUsedDeviceName,
54470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                       (char*) deviceUniqueIdUTF8,
55470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                       _lastUsedDeviceNameLength)==0)
56470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#else
57470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        if (_strnicmp((char*) _lastUsedDeviceName,
58470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                      (char*) deviceUniqueIdUTF8,
59470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                      _lastUsedDeviceNameLength) == 0)
60470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif
61470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        {
62470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            //yes
63470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            _apiLock.ReleaseLockShared();
644ca7d3f9fe809e76ee4f827a8a7f6bd31802b92cpbos@webrtc.org            return static_cast<int32_t>(_captureCapabilities.size());
65470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        }
66470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
67470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    // Need to get exclusive rights to create the new capability map.
68470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    _apiLock.ReleaseLockShared();
69470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    WriteLockScoped cs2(_apiLock);
70470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
71dfc5bb9c97fdd8df3cd86afe2b378ebf89cea628pbos@webrtc.org    int32_t ret = CreateCapabilityMap(deviceUniqueIdUTF8);
72470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return ret;
73470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
74470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
75dfc5bb9c97fdd8df3cd86afe2b378ebf89cea628pbos@webrtc.orgint32_t DeviceInfoImpl::GetCapability(const char* deviceUniqueIdUTF8,
76dfc5bb9c97fdd8df3cd86afe2b378ebf89cea628pbos@webrtc.org                                      const uint32_t deviceCapabilityNumber,
77dfc5bb9c97fdd8df3cd86afe2b378ebf89cea628pbos@webrtc.org                                      VideoCaptureCapability& capability)
78470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
793d5cb33da4df7eae70c21ba7fd0604fb93c6cedbpbos@webrtc.org    assert(deviceUniqueIdUTF8 != NULL);
80470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
81470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ReadLockScoped cs(_apiLock);
82470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
83470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    if ((_lastUsedDeviceNameLength != strlen((char*) deviceUniqueIdUTF8))
84f3b65dbfe8a8d88f623d962f8ced78ce764d518eandrew@webrtc.org#if defined(WEBRTC_MAC) || defined(WEBRTC_LINUX)
85470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        || (strncasecmp((char*)_lastUsedDeviceName,
86470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                        (char*) deviceUniqueIdUTF8,
87470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                        _lastUsedDeviceNameLength)!=0))
88470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#else
89470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        || (_strnicmp((char*) _lastUsedDeviceName,
90470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                      (char*) deviceUniqueIdUTF8,
91470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                      _lastUsedDeviceNameLength) != 0))
92470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif
93470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
94470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    {
95470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        _apiLock.ReleaseLockShared();
96470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        _apiLock.AcquireLockExclusive();
97470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        if (-1 == CreateCapabilityMap(deviceUniqueIdUTF8))
98470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        {
99470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            _apiLock.ReleaseLockExclusive();
100470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            _apiLock.AcquireLockShared();
101470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            return -1;
102470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        }
103470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        _apiLock.ReleaseLockExclusive();
104470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        _apiLock.AcquireLockShared();
105470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
106470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
107470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    // Make sure the number is valid
1084ca7d3f9fe809e76ee4f827a8a7f6bd31802b92cpbos@webrtc.org    if (deviceCapabilityNumber >= (unsigned int) _captureCapabilities.size())
109470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    {
1103d5cb33da4df7eae70c21ba7fd0604fb93c6cedbpbos@webrtc.org        LOG(LS_ERROR) << "Invalid deviceCapabilityNumber "
1113d5cb33da4df7eae70c21ba7fd0604fb93c6cedbpbos@webrtc.org                      << deviceCapabilityNumber << ">= number of capabilities ("
1123d5cb33da4df7eae70c21ba7fd0604fb93c6cedbpbos@webrtc.org                      << _captureCapabilities.size() << ").";
113470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        return -1;
114470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
115470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
11669fc315fd94ad338885cdcd28d5e85880cb4444bfischman@webrtc.org    capability = _captureCapabilities[deviceCapabilityNumber];
117470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return 0;
118470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
119470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
120dfc5bb9c97fdd8df3cd86afe2b378ebf89cea628pbos@webrtc.orgint32_t DeviceInfoImpl::GetBestMatchedCapability(
1211745e932cc560e50d764f6f0fbdc4d5b8bf20e4aleozwang@webrtc.org                                        const char*deviceUniqueIdUTF8,
12212984f0d0236af77e6e56491298b3bf2cbd74ea9mallinath@webrtc.org                                        const VideoCaptureCapability& requested,
123470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                        VideoCaptureCapability& resulting)
124470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
125470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
126470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
127470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    if (!deviceUniqueIdUTF8)
128470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        return -1;
129470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
130470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ReadLockScoped cs(_apiLock);
131470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    if ((_lastUsedDeviceNameLength != strlen((char*) deviceUniqueIdUTF8))
132f3b65dbfe8a8d88f623d962f8ced78ce764d518eandrew@webrtc.org#if defined(WEBRTC_MAC) || defined(WEBRTC_LINUX)
133470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        || (strncasecmp((char*)_lastUsedDeviceName,
134470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                        (char*) deviceUniqueIdUTF8,
135470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                        _lastUsedDeviceNameLength)!=0))
136470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#else
137470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        || (_strnicmp((char*) _lastUsedDeviceName,
138470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                      (char*) deviceUniqueIdUTF8,
139470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                      _lastUsedDeviceNameLength) != 0))
140470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif
141470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    {
142470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        _apiLock.ReleaseLockShared();
143470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        _apiLock.AcquireLockExclusive();
144470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        if (-1 == CreateCapabilityMap(deviceUniqueIdUTF8))
145470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        {
146470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            return -1;
147470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        }
148470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        _apiLock.ReleaseLockExclusive();
149470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        _apiLock.AcquireLockShared();
150470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
151470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
152dfc5bb9c97fdd8df3cd86afe2b378ebf89cea628pbos@webrtc.org    int32_t bestformatIndex = -1;
153dfc5bb9c97fdd8df3cd86afe2b378ebf89cea628pbos@webrtc.org    int32_t bestWidth = 0;
154dfc5bb9c97fdd8df3cd86afe2b378ebf89cea628pbos@webrtc.org    int32_t bestHeight = 0;
155dfc5bb9c97fdd8df3cd86afe2b378ebf89cea628pbos@webrtc.org    int32_t bestFrameRate = 0;
156470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    RawVideoType bestRawType = kVideoUnknown;
157470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    webrtc::VideoCodecType bestCodecType = webrtc::kVideoCodecUnknown;
158470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1594ca7d3f9fe809e76ee4f827a8a7f6bd31802b92cpbos@webrtc.org    const int32_t numberOfCapabilies =
1604ca7d3f9fe809e76ee4f827a8a7f6bd31802b92cpbos@webrtc.org        static_cast<int32_t>(_captureCapabilities.size());
161470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
162dfc5bb9c97fdd8df3cd86afe2b378ebf89cea628pbos@webrtc.org    for (int32_t tmp = 0; tmp < numberOfCapabilies; ++tmp) // Loop through all capabilities
163470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    {
16469fc315fd94ad338885cdcd28d5e85880cb4444bfischman@webrtc.org        VideoCaptureCapability& capability = _captureCapabilities[tmp];
165470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
166dfc5bb9c97fdd8df3cd86afe2b378ebf89cea628pbos@webrtc.org        const int32_t diffWidth = capability.width - requested.width;
167dfc5bb9c97fdd8df3cd86afe2b378ebf89cea628pbos@webrtc.org        const int32_t diffHeight = capability.height - requested.height;
168dfc5bb9c97fdd8df3cd86afe2b378ebf89cea628pbos@webrtc.org        const int32_t diffFrameRate = capability.maxFPS - requested.maxFPS;
169470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
170dfc5bb9c97fdd8df3cd86afe2b378ebf89cea628pbos@webrtc.org        const int32_t currentbestDiffWith = bestWidth - requested.width;
171dfc5bb9c97fdd8df3cd86afe2b378ebf89cea628pbos@webrtc.org        const int32_t currentbestDiffHeight = bestHeight - requested.height;
172dfc5bb9c97fdd8df3cd86afe2b378ebf89cea628pbos@webrtc.org        const int32_t currentbestDiffFrameRate = bestFrameRate - requested.maxFPS;
173470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
174470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        if ((diffHeight >= 0 && diffHeight <= abs(currentbestDiffHeight)) // Height better or equalt that previouse.
175470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            || (currentbestDiffHeight < 0 && diffHeight >= currentbestDiffHeight))
176470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        {
177470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
178470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            if (diffHeight == currentbestDiffHeight) // Found best height. Care about the width)
179470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            {
180470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                if ((diffWidth >= 0 && diffWidth <= abs(currentbestDiffWith)) // Width better or equal
181470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                    || (currentbestDiffWith < 0 && diffWidth >= currentbestDiffWith))
182470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                {
183470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                    if (diffWidth == currentbestDiffWith && diffHeight
184470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                        == currentbestDiffHeight) // Same size as previously
185470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                    {
186470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                        //Also check the best frame rate if the diff is the same as previouse
187470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                        if (((diffFrameRate >= 0 &&
188470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                              diffFrameRate <= currentbestDiffFrameRate) // Frame rate to high but better match than previouse and we have not selected IUV
189470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                            ||
190470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                            (currentbestDiffFrameRate < 0 &&
191470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                             diffFrameRate >= currentbestDiffFrameRate)) // Current frame rate is lower than requested. This is better.
192470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                        )
193470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                        {
194470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                            if ((currentbestDiffFrameRate == diffFrameRate) // Same frame rate as previous  or frame rate allready good enough
195470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                || (currentbestDiffFrameRate >= 0))
196470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                            {
197470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                if (bestRawType != requested.rawType
198470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                    && requested.rawType != kVideoUnknown
199470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                    && (capability.rawType == requested.rawType
200470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                        || capability.rawType == kVideoI420
201470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                        || capability.rawType == kVideoYUY2
202470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                        || capability.rawType == kVideoYV12))
203470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                {
204470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                    bestCodecType = capability.codecType;
205470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                    bestRawType = capability.rawType;
206470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                    bestformatIndex = tmp;
207470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                }
208470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                // If width height and frame rate is full filled we can use the camera for encoding if it is supported.
209470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                if (capability.height == requested.height
210470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                    && capability.width == requested.width
211470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                    && capability.maxFPS >= requested.maxFPS)
212470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                {
213470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                    if (capability.codecType == requested.codecType
214470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                        && bestCodecType != requested.codecType)
215470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                    {
216470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                        bestCodecType = capability.codecType;
217470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                        bestformatIndex = tmp;
218470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                    }
219470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                }
220470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                            }
221470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                            else // Better frame rate
222470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                            {
223470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                if (requested.codecType == capability.codecType)
224470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                {
225470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
226470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                    bestWidth = capability.width;
227470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                    bestHeight = capability.height;
228470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                    bestFrameRate = capability.maxFPS;
229470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                    bestCodecType = capability.codecType;
230470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                    bestRawType = capability.rawType;
231470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                    bestformatIndex = tmp;
232470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                }
233470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                            }
234470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                        }
235470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                    }
236470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                    else // Better width than previously
237470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                    {
238470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                        if (requested.codecType == capability.codecType)
239470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                        {
240470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                            bestWidth = capability.width;
241470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                            bestHeight = capability.height;
242470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                            bestFrameRate = capability.maxFPS;
243470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                            bestCodecType = capability.codecType;
244470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                            bestRawType = capability.rawType;
245470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                            bestformatIndex = tmp;
246470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                        }
247470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                    }
248470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                }// else width no good
249470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            }
250470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            else // Better height
251470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            {
252470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                if (requested.codecType == capability.codecType)
253470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                {
254470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                    bestWidth = capability.width;
255470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                    bestHeight = capability.height;
256470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                    bestFrameRate = capability.maxFPS;
257470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                    bestCodecType = capability.codecType;
258470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                    bestRawType = capability.rawType;
259470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                    bestformatIndex = tmp;
260470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                }
261470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            }
262470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        }// else height not good
263470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }//end for
264470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
2653d5cb33da4df7eae70c21ba7fd0604fb93c6cedbpbos@webrtc.org    LOG(LS_VERBOSE) << "Best camera format: " << bestWidth << "x" << bestHeight
2663d5cb33da4df7eae70c21ba7fd0604fb93c6cedbpbos@webrtc.org                    << "@" << bestFrameRate
2673d5cb33da4df7eae70c21ba7fd0604fb93c6cedbpbos@webrtc.org                    << "fps, color format: " << bestRawType;
268470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
269470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    // Copy the capability
27069fc315fd94ad338885cdcd28d5e85880cb4444bfischman@webrtc.org    if (bestformatIndex < 0)
271470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        return -1;
27269fc315fd94ad338885cdcd28d5e85880cb4444bfischman@webrtc.org    resulting = _captureCapabilities[bestformatIndex];
273470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return bestformatIndex;
274470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
275470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
276470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* Returns the expected Capture delay*/
277dfc5bb9c97fdd8df3cd86afe2b378ebf89cea628pbos@webrtc.orgint32_t DeviceInfoImpl::GetExpectedCaptureDelay(
278470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                          const DelayValues delayValues[],
279dfc5bb9c97fdd8df3cd86afe2b378ebf89cea628pbos@webrtc.org                                          const uint32_t sizeOfDelayValues,
2801745e932cc560e50d764f6f0fbdc4d5b8bf20e4aleozwang@webrtc.org                                          const char* productId,
281dfc5bb9c97fdd8df3cd86afe2b378ebf89cea628pbos@webrtc.org                                          const uint32_t width,
282dfc5bb9c97fdd8df3cd86afe2b378ebf89cea628pbos@webrtc.org                                          const uint32_t height)
283470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
284dfc5bb9c97fdd8df3cd86afe2b378ebf89cea628pbos@webrtc.org    int32_t bestDelay = kDefaultCaptureDelay;
285470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
286dfc5bb9c97fdd8df3cd86afe2b378ebf89cea628pbos@webrtc.org    for (uint32_t device = 0; device < sizeOfDelayValues; ++device)
287470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    {
288470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        if (delayValues[device].productId && strncmp((char*) productId,
289470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                                     (char*) delayValues[device].productId,
290470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                                     kVideoCaptureProductIdLength) == 0)
291470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        {
292470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            // We have found the camera
293470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
294dfc5bb9c97fdd8df3cd86afe2b378ebf89cea628pbos@webrtc.org            int32_t bestWidth = 0;
295dfc5bb9c97fdd8df3cd86afe2b378ebf89cea628pbos@webrtc.org            int32_t bestHeight = 0;
296470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
297470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            //Loop through all tested sizes and find one that seems fitting
298dfc5bb9c97fdd8df3cd86afe2b378ebf89cea628pbos@webrtc.org            for (uint32_t delayIndex = 0; delayIndex < NoOfDelayValues; ++delayIndex)
299470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            {
300470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                const DelayValue& currentValue = delayValues[device].delayValues[delayIndex];
301470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
302dfc5bb9c97fdd8df3cd86afe2b378ebf89cea628pbos@webrtc.org                const int32_t diffWidth = currentValue.width - width;
303dfc5bb9c97fdd8df3cd86afe2b378ebf89cea628pbos@webrtc.org                const int32_t diffHeight = currentValue.height - height;
304470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
305dfc5bb9c97fdd8df3cd86afe2b378ebf89cea628pbos@webrtc.org                const int32_t currentbestDiffWith = bestWidth - width;
306dfc5bb9c97fdd8df3cd86afe2b378ebf89cea628pbos@webrtc.org                const int32_t currentbestDiffHeight = bestHeight - height;
307470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
308470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                if ((diffHeight >= 0 && diffHeight <= abs(currentbestDiffHeight)) // Height better or equal than previous.
309470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                    || (currentbestDiffHeight < 0 && diffHeight >= currentbestDiffHeight))
310470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                {
311470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
312470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                    if (diffHeight == currentbestDiffHeight) // Found best height. Care about the width)
313470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                    {
314470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                        if ((diffWidth >= 0 && diffWidth <= abs(currentbestDiffWith)) // Width better or equal
315470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                            || (currentbestDiffWith < 0 && diffWidth >= currentbestDiffWith))
316470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                        {
317470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                            if (diffWidth == currentbestDiffWith && diffHeight
318470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                == currentbestDiffHeight) // Same size as previous
319470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                            {
320470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                            }
321470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                            else // Better width than previously
322470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                            {
323470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                bestWidth = currentValue.width;
324470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                bestHeight = currentValue.height;
325470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                bestDelay = currentValue.delay;
326470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                            }
327470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                        }// else width no good
328470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                    }
329470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                    else // Better height
330470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                    {
331470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                        bestWidth = currentValue.width;
332470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                        bestHeight = currentValue.height;
333470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                        bestDelay = currentValue.delay;
334470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                    }
335470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                }// else height not good
336470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            }//end for
337470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            break;
338470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        }
339470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
340470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    if (bestDelay > kMaxCaptureDelay)
341470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    {
3423d5cb33da4df7eae70c21ba7fd0604fb93c6cedbpbos@webrtc.org        LOG(LS_WARNING) << "Expected capture delay (" << bestDelay
3433d5cb33da4df7eae70c21ba7fd0604fb93c6cedbpbos@webrtc.org                        << " ms) too high, using " << kMaxCaptureDelay
3443d5cb33da4df7eae70c21ba7fd0604fb93c6cedbpbos@webrtc.org                        << " ms.";
345470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        bestDelay = kMaxCaptureDelay;
346470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
347470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
348470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return bestDelay;
349470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
350470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
351470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
352470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com//Default implementation. This should be overridden by Mobile implementations.
353dfc5bb9c97fdd8df3cd86afe2b378ebf89cea628pbos@webrtc.orgint32_t DeviceInfoImpl::GetOrientation(const char* deviceUniqueIdUTF8,
3545a7dc39277999cbfa0da053da5eacc7fee5cd307guoweis@webrtc.org                                       VideoRotation& orientation) {
3555a7dc39277999cbfa0da053da5eacc7fee5cd307guoweis@webrtc.org  orientation = kVideoRotation_0;
356470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
357470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
358d900e8bea84c474696bf0219aed1353ce65ffd8epbos@webrtc.org}  // namespace videocapturemodule
359d900e8bea84c474696bf0219aed1353ce65ffd8epbos@webrtc.org}  // namespace webrtc
360