| 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
|
|
|
|
|