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 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
151 width_ = capability.width; | 187 width_ = capability.width; |
152 height_ = capability.height; | 188 height_ = capability.height; |
153 frame_rate_ = capability.maxFPS; | 189 frame_rate_ = capability.maxFPS; |
154 state_ = media::VideoCapture::kStarted; | 190 state_ = media::VideoCapture::kStarted; |
155 | 191 |
156 media::VideoCapture::VideoCaptureCapability cap; | 192 media::VideoCapture::VideoCaptureCapability cap; |
157 cap.width = capability.width; | 193 cap.width = capability.width; |
158 cap.height = capability.height; | 194 cap.height = capability.height; |
159 cap.max_fps = capability.maxFPS; | 195 cap.max_fps = capability.maxFPS; |
160 cap.raw_type = media::VideoFrame::I420; | 196 cap.raw_type = media::VideoFrame::I420; |
161 cap.resolution_fixed = true; | |
162 capture_engine_->StartCapture(this, cap); | 197 capture_engine_->StartCapture(this, cap); |
163 } | 198 } |
164 | 199 |
165 void VideoCaptureModuleImpl::StopCaptureOnCaptureThread() { | 200 void VideoCaptureModuleImpl::StopCaptureOnCaptureThread() { |
166 DCHECK(message_loop_proxy_->BelongsToCurrentThread()); | 201 DCHECK(message_loop_proxy_->BelongsToCurrentThread()); |
167 | 202 |
168 if (pending_start_) { | 203 if (pending_start_) { |
169 VLOG(1) << "Got a StopCapture with one pending start!!! "; | 204 VLOG(1) << "Got a StopCapture with one pending start!!! "; |
170 pending_start_ = false; | 205 pending_start_ = false; |
171 return; | 206 return; |
(...skipping 26 matching lines...) Expand all Loading... |
198 VLOG(1) << "restart pending start "; | 233 VLOG(1) << "restart pending start "; |
199 pending_start_ = false; | 234 pending_start_ = false; |
200 StartCaptureInternal(pending_cap_); | 235 StartCaptureInternal(pending_cap_); |
201 } | 236 } |
202 } | 237 } |
203 | 238 |
204 void VideoCaptureModuleImpl::OnBufferReadyOnCaptureThread( | 239 void VideoCaptureModuleImpl::OnBufferReadyOnCaptureThread( |
205 media::VideoCapture* capture, | 240 media::VideoCapture* capture, |
206 scoped_refptr<media::VideoCapture::VideoFrameBuffer> buf) { | 241 scoped_refptr<media::VideoCapture::VideoFrameBuffer> buf) { |
207 DCHECK(message_loop_proxy_->BelongsToCurrentThread()); | 242 DCHECK(message_loop_proxy_->BelongsToCurrentThread()); |
| 243 DCHECK_GE(buf->width, static_cast<int>(width_)); |
| 244 DCHECK_GE(buf->height, static_cast<int>(height_)); |
208 | 245 |
209 if (state_ != media::VideoCapture::kStarted) | 246 if (state_ != media::VideoCapture::kStarted) |
210 return; | 247 return; |
211 | 248 |
212 if (!got_first_frame_) { | 249 if (!got_first_frame_) { |
213 got_first_frame_ = true; | 250 got_first_frame_ = true; |
214 start_time_ = buf->timestamp; | 251 start_time_ = buf->timestamp; |
215 } | 252 } |
216 | 253 |
217 frameInfo_.width = buf->width; | 254 frameInfo_.width = buf->width; |
218 frameInfo_.height = buf->height; | 255 frameInfo_.height = buf->height; |
219 frameInfo_.rawType = video_type_; | 256 frameInfo_.rawType = video_type_; |
220 | 257 |
221 IncomingFrame( | 258 if (buf->width == static_cast<int>(width_) && |
222 static_cast<WebRtc_UWord8*>(buf->memory_pointer), | 259 buf->height == static_cast<int>(height_)) { |
223 static_cast<WebRtc_Word32>(buf->buffer_size), | 260 IncomingFrame( |
224 frameInfo_, | 261 static_cast<WebRtc_UWord8*>(buf->memory_pointer), |
225 static_cast<WebRtc_Word64>( | 262 static_cast<WebRtc_Word32>(buf->buffer_size), |
226 (buf->timestamp - start_time_).InMicroseconds())); | 263 frameInfo_, |
| 264 static_cast<WebRtc_Word64>( |
| 265 (buf->timestamp - start_time_).InMicroseconds())); |
| 266 |
| 267 } else { |
| 268 webrtc::VideoFrame out_frame; |
| 269 out_frame.VerifyAndAllocate(CalcBufferSize(webrtc::kI420, width_, height_)); |
| 270 if (out_frame.Buffer()) { |
| 271 // TODO(wjia): Use resampling to get larger view field. |
| 272 CopyI420(buf->memory_pointer, buf->stride, buf->height, |
| 273 out_frame.Buffer(), width_, height_); |
| 274 out_frame.SetLength(width_ * height_ * 3 / 2); |
| 275 |
| 276 DeliverCapturedFrame(out_frame, width_, height_, |
| 277 static_cast<WebRtc_Word64>( |
| 278 (buf->timestamp - start_time_).InMicroseconds()), |
| 279 frameInfo_.codecType); |
| 280 } |
| 281 } |
227 | 282 |
228 capture->FeedBuffer(buf); | 283 capture->FeedBuffer(buf); |
229 } | 284 } |
OLD | NEW |