| Index: content/renderer/media/video_capture_module_impl.cc
|
| ===================================================================
|
| --- content/renderer/media/video_capture_module_impl.cc (revision 106642)
|
| +++ 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)
|
| @@ -158,7 +194,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);
|
| }
|
|
|
| @@ -205,6 +240,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;
|
| @@ -218,12 +255,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_) &&
|
| + 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);
|
| }
|
|
|