Chromium Code Reviews| Index: content/renderer/media/video_capture_module_impl.cc |
| =================================================================== |
| --- content/renderer/media/video_capture_module_impl.cc (revision 107671) |
| +++ content/renderer/media/video_capture_module_impl.cc (working copy) |
| @@ -8,6 +8,42 @@ |
| #include "base/bind.h" |
| #include "content/renderer/media/video_capture_impl_manager.h" |
| +namespace { |
| + |
| +static void CopyOnePlane(uint8* src, int src_stride, int src_rows, |
| + uint8* dest, int dest_stride, int dest_rows) { |
| + // Clamp in case source frame has smaller stride. |
| + int bytes_to_copy_per_row = std::min(src_stride, dest_stride); |
| + // Clamp in case source frame has smaller height. |
| + int rows_to_copy = std::min(src_rows, dest_rows); |
| + // Copy Y plane. |
| + for (int row = 0; row < rows_to_copy; ++row) { |
| + memcpy(dest, src, bytes_to_copy_per_row); |
| + src += src_stride; |
| + dest += dest_stride; |
| + } |
| +} |
| + |
| +static void CopyI420(uint8* src, int src_stride, int src_rows, |
| + uint8* dest, int dest_stride, int dest_rows) { |
| + int src_plane_size = src_stride * src_rows; |
| + int dest_plane_size = dest_stride * dest_rows; |
| + CopyOnePlane(src, src_stride, src_rows, dest, dest_stride, dest_rows); |
| + |
| + src += src_plane_size; |
| + dest += dest_plane_size; |
| + src_stride /= 2; |
| + src_rows /= 2; |
| + dest_stride /= 2; |
| + dest_rows /= 2; |
| + CopyOnePlane(src, src_stride, src_rows, dest, dest_stride, dest_rows); |
| + src += src_plane_size / 4; |
| + dest += dest_plane_size / 4; |
| + CopyOnePlane(src, src_stride, src_rows, dest, dest_stride, dest_rows); |
| +} |
| + |
| +} // namespace |
| + |
| VideoCaptureModuleImpl::VideoCaptureModuleImpl( |
| const media::VideoCaptureSessionId id, |
| VideoCaptureImplManager* vc_manager) |
| @@ -160,7 +196,6 @@ |
| cap.height = capability.height; |
| cap.max_fps = capability.maxFPS; |
| cap.raw_type = media::VideoFrame::I420; |
| - cap.resolution_fixed = true; |
| capture_engine_->StartCapture(this, cap); |
| } |
| @@ -207,6 +242,8 @@ |
| media::VideoCapture* capture, |
| scoped_refptr<media::VideoCapture::VideoFrameBuffer> buf) { |
| DCHECK(message_loop_proxy_->BelongsToCurrentThread()); |
| + DCHECK_GE(buf->width, static_cast<int>(width_)); |
| + DCHECK_GE(buf->height, static_cast<int>(height_)); |
| if (state_ != media::VideoCapture::kStarted) |
| return; |
| @@ -220,12 +257,30 @@ |
| frameInfo_.height = buf->height; |
| frameInfo_.rawType = video_type_; |
| - IncomingFrame( |
| - static_cast<WebRtc_UWord8*>(buf->memory_pointer), |
| - static_cast<WebRtc_Word32>(buf->buffer_size), |
| - frameInfo_, |
| - static_cast<WebRtc_Word64>( |
| - (buf->timestamp - start_time_).InMicroseconds())); |
| + 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.
|
| + buf->height == static_cast<int>(height_)) { |
| + IncomingFrame( |
| + static_cast<WebRtc_UWord8*>(buf->memory_pointer), |
| + static_cast<WebRtc_Word32>(buf->buffer_size), |
| + frameInfo_, |
| + static_cast<WebRtc_Word64>( |
| + (buf->timestamp - start_time_).InMicroseconds())); |
| + } else { |
| + webrtc::VideoFrame out_frame; |
| + out_frame.VerifyAndAllocate(CalcBufferSize(webrtc::kI420, width_, height_)); |
| + if (out_frame.Buffer()) { |
| + // TODO(wjia): Use resampling to get larger view field. |
| + CopyI420(buf->memory_pointer, buf->stride, buf->height, |
| + out_frame.Buffer(), width_, height_); |
| + out_frame.SetLength(width_ * height_ * 3 / 2); |
| + |
| + DeliverCapturedFrame(out_frame, width_, height_, |
| + static_cast<WebRtc_Word64>( |
| + (buf->timestamp - start_time_).InMicroseconds()), |
| + frameInfo_.codecType); |
| + } |
| + } |
| + |
| capture->FeedBuffer(buf); |
| } |