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