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); |
} |