OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/renderer/media/video_capture_module_impl.h" | 5 #include "content/renderer/media/video_capture_module_impl.h" |
6 | 6 |
7 #include "base/atomicops.h" | 7 #include "base/atomicops.h" |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "content/renderer/media/video_capture_impl_manager.h" | 9 #include "content/renderer/media/video_capture_impl_manager.h" |
10 | 10 |
11 namespace { | |
12 | |
13 static void CopyOnePlane(uint8* src, int src_stride, int src_rows, | |
14 uint8* dest, int dest_stride, int dest_rows) { | |
15 // Clamp in case source frame has smaller stride. | |
16 int bytes_to_copy_per_row = std::min(src_stride, dest_stride); | |
17 // Clamp in case source frame has smaller height. | |
18 int rows_to_copy = std::min(src_rows, dest_rows); | |
19 // Copy Y plane. | |
20 for (int row = 0; row < rows_to_copy; ++row) { | |
21 memcpy(dest, src, bytes_to_copy_per_row); | |
22 src += src_stride; | |
23 dest += dest_stride; | |
24 } | |
25 } | |
26 | |
27 static void CopyI420(uint8* src, int src_stride, int src_rows, | |
28 uint8* dest, int dest_stride, int dest_rows) { | |
29 int src_plane_size = src_stride * src_rows; | |
30 int dest_plane_size = dest_stride * dest_rows; | |
31 CopyOnePlane(src, src_stride, src_rows, dest, dest_stride, dest_rows); | |
32 | |
33 src += src_plane_size; | |
34 dest += dest_plane_size; | |
35 src_stride /= 2; | |
36 src_rows /= 2; | |
37 dest_stride /= 2; | |
38 dest_rows /= 2; | |
39 CopyOnePlane(src, src_stride, src_rows, dest, dest_stride, dest_rows); | |
40 src += src_plane_size / 4; | |
41 dest += dest_plane_size / 4; | |
42 CopyOnePlane(src, src_stride, src_rows, dest, dest_stride, dest_rows); | |
43 } | |
44 | |
45 } // namespace | |
46 | |
11 VideoCaptureModuleImpl::VideoCaptureModuleImpl( | 47 VideoCaptureModuleImpl::VideoCaptureModuleImpl( |
12 const media::VideoCaptureSessionId id, | 48 const media::VideoCaptureSessionId id, |
13 VideoCaptureImplManager* vc_manager) | 49 VideoCaptureImplManager* vc_manager) |
14 : webrtc::videocapturemodule::VideoCaptureImpl(id), | 50 : webrtc::videocapturemodule::VideoCaptureImpl(id), |
15 session_id_(id), | 51 session_id_(id), |
16 thread_("VideoCaptureModuleImpl"), | 52 thread_("VideoCaptureModuleImpl"), |
17 vc_manager_(vc_manager), | 53 vc_manager_(vc_manager), |
18 state_(media::VideoCapture::kStopped), | 54 state_(media::VideoCapture::kStopped), |
19 got_first_frame_(false), | 55 got_first_frame_(false), |
20 width_(-1), | 56 width_(-1), |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
153 width_ = capability.width; | 189 width_ = capability.width; |
154 height_ = capability.height; | 190 height_ = capability.height; |
155 frame_rate_ = capability.maxFPS; | 191 frame_rate_ = capability.maxFPS; |
156 state_ = media::VideoCapture::kStarted; | 192 state_ = media::VideoCapture::kStarted; |
157 | 193 |
158 media::VideoCapture::VideoCaptureCapability cap; | 194 media::VideoCapture::VideoCaptureCapability cap; |
159 cap.width = capability.width; | 195 cap.width = capability.width; |
160 cap.height = capability.height; | 196 cap.height = capability.height; |
161 cap.max_fps = capability.maxFPS; | 197 cap.max_fps = capability.maxFPS; |
162 cap.raw_type = media::VideoFrame::I420; | 198 cap.raw_type = media::VideoFrame::I420; |
163 cap.resolution_fixed = true; | |
164 capture_engine_->StartCapture(this, cap); | 199 capture_engine_->StartCapture(this, cap); |
165 } | 200 } |
166 | 201 |
167 void VideoCaptureModuleImpl::StopCaptureOnCaptureThread() { | 202 void VideoCaptureModuleImpl::StopCaptureOnCaptureThread() { |
168 DCHECK(message_loop_proxy_->BelongsToCurrentThread()); | 203 DCHECK(message_loop_proxy_->BelongsToCurrentThread()); |
169 | 204 |
170 if (pending_start_) { | 205 if (pending_start_) { |
171 VLOG(1) << "Got a StopCapture with one pending start!!! "; | 206 VLOG(1) << "Got a StopCapture with one pending start!!! "; |
172 pending_start_ = false; | 207 pending_start_ = false; |
173 return; | 208 return; |
(...skipping 26 matching lines...) Expand all Loading... | |
200 VLOG(1) << "restart pending start "; | 235 VLOG(1) << "restart pending start "; |
201 pending_start_ = false; | 236 pending_start_ = false; |
202 StartCaptureInternal(pending_cap_); | 237 StartCaptureInternal(pending_cap_); |
203 } | 238 } |
204 } | 239 } |
205 | 240 |
206 void VideoCaptureModuleImpl::OnBufferReadyOnCaptureThread( | 241 void VideoCaptureModuleImpl::OnBufferReadyOnCaptureThread( |
207 media::VideoCapture* capture, | 242 media::VideoCapture* capture, |
208 scoped_refptr<media::VideoCapture::VideoFrameBuffer> buf) { | 243 scoped_refptr<media::VideoCapture::VideoFrameBuffer> buf) { |
209 DCHECK(message_loop_proxy_->BelongsToCurrentThread()); | 244 DCHECK(message_loop_proxy_->BelongsToCurrentThread()); |
245 DCHECK_GE(buf->width, static_cast<int>(width_)); | |
246 DCHECK_GE(buf->height, static_cast<int>(height_)); | |
210 | 247 |
211 if (state_ != media::VideoCapture::kStarted) | 248 if (state_ != media::VideoCapture::kStarted) |
212 return; | 249 return; |
213 | 250 |
214 if (!got_first_frame_) { | 251 if (!got_first_frame_) { |
perkj_chrome
2011/10/28 08:37:19
Why is this necessary? Why compensate the time? Vi
wjia(left Chromium)
2011/10/29 02:34:40
removed.
| |
215 got_first_frame_ = true; | 252 got_first_frame_ = true; |
216 start_time_ = buf->timestamp; | 253 start_time_ = buf->timestamp; |
217 } | 254 } |
218 | 255 |
219 frameInfo_.width = buf->width; | 256 frameInfo_.width = buf->width; |
220 frameInfo_.height = buf->height; | 257 frameInfo_.height = buf->height; |
221 frameInfo_.rawType = video_type_; | 258 frameInfo_.rawType = video_type_; |
222 | 259 |
223 IncomingFrame( | 260 if (buf->width == static_cast<int>(width_) && |
perkj_chrome
2011/10/28 08:37:19
You should never have to care about the frame size
wjia(left Chromium)
2011/10/29 02:34:40
reverted the change.
| |
224 static_cast<WebRtc_UWord8*>(buf->memory_pointer), | 261 buf->height == static_cast<int>(height_)) { |
225 static_cast<WebRtc_Word32>(buf->buffer_size), | 262 IncomingFrame( |
226 frameInfo_, | 263 static_cast<WebRtc_UWord8*>(buf->memory_pointer), |
227 static_cast<WebRtc_Word64>( | 264 static_cast<WebRtc_Word32>(buf->buffer_size), |
228 (buf->timestamp - start_time_).InMicroseconds())); | 265 frameInfo_, |
266 static_cast<WebRtc_Word64>( | |
267 (buf->timestamp - start_time_).InMicroseconds())); | |
268 | |
269 } else { | |
270 webrtc::VideoFrame out_frame; | |
271 out_frame.VerifyAndAllocate(CalcBufferSize(webrtc::kI420, width_, height_)); | |
272 if (out_frame.Buffer()) { | |
273 // TODO(wjia): Use resampling to get larger view field. | |
274 CopyI420(buf->memory_pointer, buf->stride, buf->height, | |
275 out_frame.Buffer(), width_, height_); | |
276 out_frame.SetLength(width_ * height_ * 3 / 2); | |
277 | |
278 DeliverCapturedFrame(out_frame, width_, height_, | |
279 static_cast<WebRtc_Word64>( | |
280 (buf->timestamp - start_time_).InMicroseconds()), | |
281 frameInfo_.codecType); | |
282 } | |
283 } | |
229 | 284 |
230 capture->FeedBuffer(buf); | 285 capture->FeedBuffer(buf); |
231 } | 286 } |
OLD | NEW |