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 "webrtc/modules/video_capture/mac/qtkit/video_capture_qtkit.h"
12#import "webrtc/modules/video_capture/mac/qtkit/video_capture_qtkit_info_objc.h"
13#import "webrtc/modules/video_capture/mac/qtkit/video_capture_qtkit_objc.h"
14#include "webrtc/modules/video_capture/video_capture_config.h"
15#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
16#include "webrtc/system_wrappers/include/trace.h"
17
18namespace webrtc
19{
20
21namespace videocapturemodule
22{
23
24VideoCaptureMacQTKit::VideoCaptureMacQTKit(const int32_t id) :
25    VideoCaptureImpl(id),
26    _captureDevice(NULL),
27    _captureInfo(NULL),
28    _isCapturing(false),
29    _id(id),
30    _captureWidth(QTKIT_DEFAULT_WIDTH),
31    _captureHeight(QTKIT_DEFAULT_HEIGHT),
32    _captureFrameRate(QTKIT_DEFAULT_FRAME_RATE),
33    _frameCount(0)
34{
35
36    memset(_currentDeviceNameUTF8, 0, MAX_NAME_LENGTH);
37    memset(_currentDeviceUniqueIdUTF8, 0, MAX_NAME_LENGTH);
38    memset(_currentDeviceProductUniqueIDUTF8, 0, MAX_NAME_LENGTH);
39}
40
41VideoCaptureMacQTKit::~VideoCaptureMacQTKit()
42{
43
44    WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, _id,
45                 "~VideoCaptureMacQTKit() called");
46    if(_captureDevice)
47    {
48        [_captureDevice registerOwner:nil];
49        [_captureDevice stopCapture];
50        [_captureDevice release];
51    }
52
53    if(_captureInfo)
54    {
55        [_captureInfo release];
56    }
57}
58
59int32_t VideoCaptureMacQTKit::Init(
60    const int32_t id, const char* iDeviceUniqueIdUTF8)
61{
62    CriticalSectionScoped cs(&_apiCs);
63
64
65    const int32_t nameLength =
66        (int32_t) strlen((char*)iDeviceUniqueIdUTF8);
67    if(nameLength>kVideoCaptureUniqueNameLength)
68        return -1;
69
70    // Store the device name
71    _deviceUniqueId = new char[nameLength+1];
72    memcpy(_deviceUniqueId, iDeviceUniqueIdUTF8,nameLength+1);
73
74    _captureDevice = [[VideoCaptureMacQTKitObjC alloc] init];
75    if(NULL == _captureDevice)
76    {
77        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, id,
78                     "Failed to create an instance of "
79                     "VideoCaptureMacQTKitObjC");
80        return -1;
81    }
82
83    [_captureDevice registerOwner:this];
84
85    if(0 == strcmp((char*)iDeviceUniqueIdUTF8, ""))
86    {
87        // the user doesn't want to set a capture device at this time
88        return 0;
89    }
90
91    _captureInfo = [[VideoCaptureMacQTKitInfoObjC alloc]init];
92    if(nil == _captureInfo)
93    {
94        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, id,
95        "Failed to create an instance of VideoCaptureMacQTKitInfoObjC");
96        return -1;
97    }
98
99    int captureDeviceCount = [[_captureInfo getCaptureDeviceCount]intValue];
100    if(captureDeviceCount < 0)
101    {
102        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, id,
103                     "No Capture Devices Present");
104        return -1;
105    }
106
107    const int NAME_LENGTH = 1024;
108    char deviceNameUTF8[1024] = "";
109    char deviceUniqueIdUTF8[1024] = "";
110    char deviceProductUniqueIDUTF8[1024] = "";
111
112    bool captureDeviceFound = false;
113    for(int index = 0; index < captureDeviceCount; index++){
114
115        memset(deviceNameUTF8, 0, NAME_LENGTH);
116        memset(deviceUniqueIdUTF8, 0, NAME_LENGTH);
117        memset(deviceProductUniqueIDUTF8, 0, NAME_LENGTH);
118        if(-1 == [[_captureInfo getDeviceNamesFromIndex:index
119                   DefaultName:deviceNameUTF8 WithLength:NAME_LENGTH
120                   AndUniqueID:deviceUniqueIdUTF8 WithLength:NAME_LENGTH
121                   AndProductID:deviceProductUniqueIDUTF8
122                   WithLength:NAME_LENGTH]intValue])
123        {
124            WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
125                         "GetDeviceName returned -1 for index %d", index);
126            return -1;
127        }
128        if(0 == strcmp((const char*)iDeviceUniqueIdUTF8,
129                       (char*)deviceUniqueIdUTF8))
130        {
131            // we have a match
132            captureDeviceFound = true;
133            break;
134        }
135    }
136
137    if(false == captureDeviceFound)
138    {
139        WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id,
140                     "Failed to find capture device unique ID %s",
141                     iDeviceUniqueIdUTF8);
142        return -1;
143    }
144
145    // at this point we know that the user has passed in a valid camera. Let's
146    // set it as the current.
147    if(![_captureDevice setCaptureDeviceById:(char*)deviceUniqueIdUTF8])
148    {
149        strcpy((char*)_deviceUniqueId, (char*)deviceUniqueIdUTF8);
150        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
151                     "Failed to set capture device %s (unique ID %s) even "
152                     "though it was a valid return from "
153                     "VideoCaptureMacQTKitInfo", deviceNameUTF8,
154                     iDeviceUniqueIdUTF8);
155        return -1;
156    }
157
158    WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id,
159                 "successfully Init VideoCaptureMacQTKit" );
160    return 0;
161}
162
163int32_t VideoCaptureMacQTKit::StartCapture(
164    const VideoCaptureCapability& capability)
165{
166
167    _captureWidth = capability.width;
168    _captureHeight = capability.height;
169    _captureFrameRate = capability.maxFPS;
170    _captureDelay = 120;
171
172    [_captureDevice setCaptureHeight:_captureHeight
173                               width:_captureWidth
174                           frameRate:_captureFrameRate];
175
176    [_captureDevice startCapture];
177    _isCapturing = true;
178    return 0;
179}
180
181int32_t VideoCaptureMacQTKit::StopCapture()
182{
183    [_captureDevice stopCapture];
184    _isCapturing = false;
185    return 0;
186}
187
188bool VideoCaptureMacQTKit::CaptureStarted()
189{
190    return _isCapturing;
191}
192
193int32_t VideoCaptureMacQTKit::CaptureSettings(VideoCaptureCapability& settings)
194{
195    settings.width = _captureWidth;
196    settings.height = _captureHeight;
197    settings.maxFPS = _captureFrameRate;
198    return 0;
199}
200
201
202// ********** begin functions inherited from DeviceInfoImpl **********
203
204struct VideoCaptureCapabilityMacQTKit:public VideoCaptureCapability
205{
206    VideoCaptureCapabilityMacQTKit()
207    {
208    }
209};
210}  // namespace videocapturemodule
211}  // namespace webrtc
212