Index: content/renderer/media/video_capture_relay.cc |
=================================================================== |
--- content/renderer/media/video_capture_relay.cc (revision 0) |
+++ content/renderer/media/video_capture_relay.cc (revision 0) |
@@ -0,0 +1,198 @@ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "content/renderer/media/video_capture_relay.h" |
+ |
+#include "base/bind.h" |
+#include "base/callback_helpers.h" |
+#include "content/renderer/media/video_capture_impl_manager.h" |
+//#include "media/base/filters.h" |
+#include "media/base/limits.h" |
+#include "media/base/video_util.h" |
+ |
+using media::CopyYPlane; |
+using media::CopyUPlane; |
+using media::CopyVPlane; |
+ |
+VideoCaptureRelay::VideoCaptureRelay( |
+ media::VideoCaptureSessionId video_stream_id, |
+ VideoCaptureImplManager* vc_manager, |
+ const media::VideoCaptureCapability& capability, |
+ const base::Closure& paint_cb) |
+ : thread_("VideoCaptureRelay"), |
+ vc_manager_(vc_manager), |
+ capability_(capability), |
+ is_active_(false), |
+ pending_paint_(false), |
+ paint_cb_(paint_cb), |
+ video_stream_id_(video_stream_id), |
+ capture_engine_(NULL) { |
+VLOG(1) << "VideoCaptureRelay::VideoCaptureRelay"; |
+ DCHECK(vc_manager); |
+ thread_.Start(); |
+ message_loop_proxy_ = thread_.message_loop_proxy(); |
+} |
+ |
+VideoCaptureRelay::~VideoCaptureRelay() { |
+VLOG(1) << "VideoCaptureRelay::~VideoCaptureRelay"; |
+ thread_.Stop(); |
+} |
+ |
+void VideoCaptureRelay::Start() { |
+ message_loop_proxy_->PostTask( |
+ FROM_HERE, |
+ base::Bind(&VideoCaptureRelay::StartOnRelayThread, this)); |
+} |
+ |
+void VideoCaptureRelay::Stop(const base::Closure& callback) { |
+ message_loop_proxy_->PostTask( |
+ FROM_HERE, |
+ base::Bind(&VideoCaptureRelay::StopOnRelayThread, |
+ this, callback)); |
+} |
+ |
+void VideoCaptureRelay::OnStarted(media::VideoCapture* capture) { |
+ NOTIMPLEMENTED(); |
+} |
+ |
+void VideoCaptureRelay::OnStopped(media::VideoCapture* capture) { |
+ message_loop_proxy_->PostTask( |
+ FROM_HERE, |
+ base::Bind(&VideoCaptureRelay::OnStoppedOnRelayThread, |
+ this, capture)); |
+} |
+ |
+void VideoCaptureRelay::OnPaused(media::VideoCapture* capture) { |
+ NOTIMPLEMENTED(); |
+} |
+ |
+void VideoCaptureRelay::OnError(media::VideoCapture* capture, |
+ int error_code) { |
+ NOTIMPLEMENTED(); |
+} |
+ |
+void VideoCaptureRelay::OnRemoved(media::VideoCapture* capture) { |
+ NOTIMPLEMENTED(); |
+} |
+ |
+void VideoCaptureRelay::OnBufferReady( |
+ media::VideoCapture* capture, |
+ scoped_refptr<media::VideoCapture::VideoFrameBuffer> buf) { |
+ DCHECK(buf); |
+ message_loop_proxy_->PostTask( |
+ FROM_HERE, |
+ base::Bind(&VideoCaptureRelay::OnBufferReadyOnRelayThread, |
+ this, capture, buf)); |
+} |
+ |
+void VideoCaptureRelay::OnDeviceInfoReceived( |
+ media::VideoCapture* capture, |
+ const media::VideoCaptureParams& device_info) { |
+ message_loop_proxy_->PostTask( |
+ FROM_HERE, |
+ base::Bind(&VideoCaptureRelay::OnDeviceInfoReceivedOnRelayThread, |
+ this, capture, device_info)); |
+} |
+ |
+void VideoCaptureRelay::StartOnRelayThread() { |
+ DVLOG(1) << "StartOnRelayThread"; |
+VLOG(1) << "VideoCaptureRelay::StartOnRelayThread"; |
+ DCHECK(message_loop_proxy_->BelongsToCurrentThread()); |
+ |
+ capture_engine_ = vc_manager_->AddDevice(video_stream_id_, this); |
+ is_active_ = true; |
+ capture_engine_->StartCapture(this, capability_); |
+} |
+ |
+void VideoCaptureRelay::StopOnRelayThread(const base::Closure& callback) { |
+ DVLOG(1) << "StopOnRelayThread"; |
+VLOG(1) << "VideoCaptureRelay::StopOnRelayThread"; |
+ DCHECK(message_loop_proxy_->BelongsToCurrentThread()); |
+ pending_stop_cb_ = callback; |
+ is_active_ = false; |
+ capture_engine_->StopCapture(this); |
+} |
+ |
+void VideoCaptureRelay::OnStoppedOnRelayThread( |
+ media::VideoCapture* capture) { |
+ DVLOG(1) << "OnStoppedOnRelayThread"; |
+VLOG(1) << "VideoCaptureRelay::OnStoppedOnRelayThread"; |
+ DCHECK(message_loop_proxy_->BelongsToCurrentThread()); |
+ if (!pending_stop_cb_.is_null()) |
+ base::ResetAndReturn(&pending_stop_cb_).Run(); |
+ vc_manager_->RemoveDevice(video_stream_id_, this); |
+} |
+ |
+void VideoCaptureRelay::OnDeviceInfoReceivedOnRelayThread( |
+ media::VideoCapture* capture, |
+ const media::VideoCaptureParams& device_info) { |
+VLOG(1) << "VideoCaptureRelay::OnDeviceInfoReceivedOnRelayThread"; |
+} |
+ |
+void VideoCaptureRelay::OnBufferReadyOnRelayThread( |
+ media::VideoCapture* capture, |
+ scoped_refptr<media::VideoCapture::VideoFrameBuffer> buf) { |
+ DCHECK(message_loop_proxy_->BelongsToCurrentThread()); |
+//VLOG(1) << "VideoCaptureRelay::OnBufferReadyOnRelayThread"; |
+ |
+ base::AutoLock auto_lock(lock_); |
+ if (pending_paint_ || !is_active_) { |
+VLOG(1) << "VideoCaptureRelay::OnBufferReadyOnRelayThread, drop a frame"; |
+ capture->FeedBuffer(buf); |
+ return; |
+ } |
+ |
+ if (!current_frame_ || |
+ static_cast<int>(current_frame_->width()) != buf->width || |
+ static_cast<int>(current_frame_->height()) != buf->height) { |
+ const base::TimeDelta kZero; |
+ current_frame_ = |
+ media::VideoFrame::CreateFrame(media::VideoFrame::YV12, |
+ buf->width, buf->height, |
+ kZero, kZero); |
+ } |
+ |
+ uint8* buffer = buf->memory_pointer; |
+ |
+ // Assume YV12 format. Note that camera gives YUV and media pipeline video |
+ // renderer asks for YVU. The following code did the conversion. |
+ DCHECK_EQ(capability_.color, media::VideoCaptureCapability::kI420); |
+ int y_width = buf->width; |
+ int y_height = buf->height; |
+ int uv_width = buf->width / 2; |
+ int uv_height = buf->height / 2; // YV12 format. |
+ CopyYPlane(buffer, y_width, y_height, current_frame_); |
+ buffer += y_width * y_height; |
+ CopyUPlane(buffer, uv_width, uv_height, current_frame_); |
+ buffer += uv_width * uv_height; |
+ CopyVPlane(buffer, uv_width, uv_height, current_frame_); |
+ |
+ base::AutoUnlock auto_unlock(lock_); |
+ capture->FeedBuffer(buf); |
+ paint_cb_.Run(); |
+} |
+ |
+void VideoCaptureRelay::GetCurrentFrame( |
+ scoped_refptr<media::VideoFrame>* frame_out) { |
+ base::AutoLock auto_lock(lock_); |
+ DCHECK(!pending_paint_); |
+ |
+ *frame_out = current_frame_; |
+ if (current_frame_) { |
+ pending_paint_ = true; |
+ } |
+} |
+ |
+void VideoCaptureRelay::PutCurrentFrame( |
+ scoped_refptr<media::VideoFrame> frame) { |
+ base::AutoLock auto_lock(lock_); |
+ |
+ if (pending_paint_) { |
+ DCHECK_EQ(current_frame_, frame); |
+ pending_paint_ = false; |
+ } else { |
+ DCHECK(!frame); |
+ } |
+} |
+ |
Property changes on: content/renderer/media/video_capture_relay.cc |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |