OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 14 matching lines...) Expand all Loading... |
25 namespace webrtc { | 25 namespace webrtc { |
26 namespace videocapturemodule { | 26 namespace videocapturemodule { |
27 rtc::scoped_refptr<VideoCaptureModule> VideoCaptureImpl::Create( | 27 rtc::scoped_refptr<VideoCaptureModule> VideoCaptureImpl::Create( |
28 VideoCaptureExternal*& externalCapture) { | 28 VideoCaptureExternal*& externalCapture) { |
29 rtc::scoped_refptr<VideoCaptureImpl> implementation( | 29 rtc::scoped_refptr<VideoCaptureImpl> implementation( |
30 new rtc::RefCountedObject<VideoCaptureImpl>()); | 30 new rtc::RefCountedObject<VideoCaptureImpl>()); |
31 externalCapture = implementation.get(); | 31 externalCapture = implementation.get(); |
32 return implementation; | 32 return implementation; |
33 } | 33 } |
34 | 34 |
35 const char* VideoCaptureImpl::CurrentDeviceName() const { | 35 const char* VideoCaptureImpl::CurrentDeviceName() const |
36 return _deviceUniqueId; | 36 { |
| 37 return _deviceUniqueId; |
37 } | 38 } |
38 | 39 |
39 // static | 40 // static |
40 int32_t VideoCaptureImpl::RotationFromDegrees(int degrees, | 41 int32_t VideoCaptureImpl::RotationFromDegrees(int degrees, |
41 VideoRotation* rotation) { | 42 VideoRotation* rotation) { |
42 switch (degrees) { | 43 switch (degrees) { |
43 case 0: | 44 case 0: |
44 *rotation = kVideoRotation_0; | 45 *rotation = kVideoRotation_0; |
45 return 0; | 46 return 0; |
46 case 90: | 47 case 90: |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 { | 129 { |
129 rtc::CritScope cs(&_apiCs); | 130 rtc::CritScope cs(&_apiCs); |
130 | 131 |
131 const int32_t width = frameInfo.width; | 132 const int32_t width = frameInfo.width; |
132 const int32_t height = frameInfo.height; | 133 const int32_t height = frameInfo.height; |
133 | 134 |
134 TRACE_EVENT1("webrtc", "VC::IncomingFrame", "capture_time", captureTime); | 135 TRACE_EVENT1("webrtc", "VC::IncomingFrame", "capture_time", captureTime); |
135 | 136 |
136 // Not encoded, convert to I420. | 137 // Not encoded, convert to I420. |
137 const VideoType commonVideoType = | 138 const VideoType commonVideoType = |
138 RawVideoTypeToCommonVideoVideoType(frameInfo.rawType); | 139 RawVideoTypeToCommonVideoVideoType(frameInfo.rawType); |
139 | 140 |
140 if (frameInfo.rawType != kVideoMJPEG && | 141 if (frameInfo.rawType != kVideoMJPEG && |
141 CalcBufferSize(commonVideoType, width, abs(height)) != | 142 CalcBufferSize(commonVideoType, width, |
142 videoFrameLength) { | 143 abs(height)) != videoFrameLength) |
143 LOG(LS_ERROR) << "Wrong incoming frame length."; | 144 { |
144 return -1; | 145 LOG(LS_ERROR) << "Wrong incoming frame length."; |
| 146 return -1; |
145 } | 147 } |
146 | 148 |
147 int stride_y = width; | 149 int stride_y = width; |
148 int stride_uv = (width + 1) / 2; | 150 int stride_uv = (width + 1) / 2; |
149 int target_width = width; | 151 int target_width = width; |
150 int target_height = height; | 152 int target_height = height; |
151 | 153 |
152 // SetApplyRotation doesn't take any lock. Make a local copy here. | 154 // SetApplyRotation doesn't take any lock. Make a local copy here. |
153 bool apply_rotation = apply_rotation_; | 155 bool apply_rotation = apply_rotation_; |
154 | 156 |
(...skipping 10 matching lines...) Expand all Loading... |
165 // In Windows, the image starts bottom left, instead of top left. | 167 // In Windows, the image starts bottom left, instead of top left. |
166 // Setting a negative source height, inverts the image (within LibYuv). | 168 // Setting a negative source height, inverts the image (within LibYuv). |
167 | 169 |
168 // TODO(nisse): Use a pool? | 170 // TODO(nisse): Use a pool? |
169 rtc::scoped_refptr<I420Buffer> buffer = I420Buffer::Create( | 171 rtc::scoped_refptr<I420Buffer> buffer = I420Buffer::Create( |
170 target_width, abs(target_height), stride_y, stride_uv, stride_uv); | 172 target_width, abs(target_height), stride_y, stride_uv, stride_uv); |
171 const int conversionResult = ConvertToI420( | 173 const int conversionResult = ConvertToI420( |
172 commonVideoType, videoFrame, 0, 0, // No cropping | 174 commonVideoType, videoFrame, 0, 0, // No cropping |
173 width, height, videoFrameLength, | 175 width, height, videoFrameLength, |
174 apply_rotation ? _rotateFrame : kVideoRotation_0, buffer.get()); | 176 apply_rotation ? _rotateFrame : kVideoRotation_0, buffer.get()); |
175 if (conversionResult < 0) { | 177 if (conversionResult < 0) |
| 178 { |
176 LOG(LS_ERROR) << "Failed to convert capture frame from type " | 179 LOG(LS_ERROR) << "Failed to convert capture frame from type " |
177 << frameInfo.rawType << "to I420."; | 180 << frameInfo.rawType << "to I420."; |
178 return -1; | 181 return -1; |
179 } | 182 } |
180 | 183 |
181 VideoFrame captureFrame(buffer, 0, rtc::TimeMillis(), | 184 VideoFrame captureFrame( |
182 !apply_rotation ? _rotateFrame : kVideoRotation_0); | 185 buffer, 0, rtc::TimeMillis(), |
| 186 !apply_rotation ? _rotateFrame : kVideoRotation_0); |
183 captureFrame.set_ntp_time_ms(captureTime); | 187 captureFrame.set_ntp_time_ms(captureTime); |
184 | 188 |
185 DeliverCapturedFrame(captureFrame); | 189 DeliverCapturedFrame(captureFrame); |
186 | 190 |
187 return 0; | 191 return 0; |
188 } | 192 } |
189 | 193 |
190 int32_t VideoCaptureImpl::SetCaptureRotation(VideoRotation rotation) { | 194 int32_t VideoCaptureImpl::SetCaptureRotation(VideoRotation rotation) { |
191 rtc::CritScope cs(&_apiCs); | 195 rtc::CritScope cs(&_apiCs); |
192 _rotateFrame = rotation; | 196 _rotateFrame = rotation; |
193 return 0; | 197 return 0; |
194 } | 198 } |
195 | 199 |
196 bool VideoCaptureImpl::SetApplyRotation(bool enable) { | 200 bool VideoCaptureImpl::SetApplyRotation(bool enable) { |
197 // We can't take any lock here as it'll cause deadlock with IncomingFrame. | 201 // We can't take any lock here as it'll cause deadlock with IncomingFrame. |
198 | 202 |
199 // The effect of this is the last caller wins. | 203 // The effect of this is the last caller wins. |
200 apply_rotation_ = enable; | 204 apply_rotation_ = enable; |
201 return true; | 205 return true; |
202 } | 206 } |
203 | 207 |
204 void VideoCaptureImpl::UpdateFrameCount() { | 208 void VideoCaptureImpl::UpdateFrameCount() |
205 if (_incomingFrameTimesNanos[0] / rtc::kNumNanosecsPerMicrosec == 0) { | 209 { |
206 // first no shift | 210 if (_incomingFrameTimesNanos[0] / rtc::kNumNanosecsPerMicrosec == 0) |
207 } else { | 211 { |
208 // shift | 212 // first no shift |
209 for (int i = (kFrameRateCountHistorySize - 2); i >= 0; --i) { | |
210 _incomingFrameTimesNanos[i + 1] = _incomingFrameTimesNanos[i]; | |
211 } | 213 } |
212 } | 214 else |
213 _incomingFrameTimesNanos[0] = rtc::TimeNanos(); | 215 { |
| 216 // shift |
| 217 for (int i = (kFrameRateCountHistorySize - 2); i >= 0; i--) |
| 218 { |
| 219 _incomingFrameTimesNanos[i + 1] = _incomingFrameTimesNanos[i]; |
| 220 } |
| 221 } |
| 222 _incomingFrameTimesNanos[0] = rtc::TimeNanos(); |
214 } | 223 } |
215 | 224 |
216 uint32_t VideoCaptureImpl::CalculateFrameRate(int64_t now_ns) { | 225 uint32_t VideoCaptureImpl::CalculateFrameRate(int64_t now_ns) |
217 int32_t num = 0; | 226 { |
218 int32_t nrOfFrames = 0; | 227 int32_t num = 0; |
219 for (num = 1; num < (kFrameRateCountHistorySize - 1); ++num) { | 228 int32_t nrOfFrames = 0; |
220 if (_incomingFrameTimesNanos[num] <= 0 || | 229 for (num = 1; num < (kFrameRateCountHistorySize - 1); num++) |
221 (now_ns - _incomingFrameTimesNanos[num]) / | 230 { |
222 rtc::kNumNanosecsPerMillisec > | 231 if (_incomingFrameTimesNanos[num] <= 0 || |
223 kFrameRateHistoryWindowMs) { // don't use data older than 2sec | 232 (now_ns - _incomingFrameTimesNanos[num]) / |
224 break; | 233 rtc::kNumNanosecsPerMillisec > |
225 } else { | 234 kFrameRateHistoryWindowMs) // don't use data older than 2sec |
226 nrOfFrames++; | 235 { |
| 236 break; |
| 237 } |
| 238 else |
| 239 { |
| 240 nrOfFrames++; |
| 241 } |
227 } | 242 } |
228 } | 243 if (num > 1) |
229 if (num > 1) { | 244 { |
230 int64_t diff = (now_ns - _incomingFrameTimesNanos[num - 1]) / | 245 int64_t diff = (now_ns - _incomingFrameTimesNanos[num - 1]) / |
231 rtc::kNumNanosecsPerMillisec; | 246 rtc::kNumNanosecsPerMillisec; |
232 if (diff > 0) { | 247 if (diff > 0) |
233 return uint32_t((nrOfFrames * 1000.0f / diff) + 0.5f); | 248 { |
| 249 return uint32_t((nrOfFrames * 1000.0f / diff) + 0.5f); |
| 250 } |
234 } | 251 } |
235 } | |
236 | 252 |
237 return nrOfFrames; | 253 return nrOfFrames; |
238 } | 254 } |
239 } // namespace videocapturemodule | 255 } // namespace videocapturemodule |
240 } // namespace webrtc | 256 } // namespace webrtc |
OLD | NEW |