Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1308)

Unified Diff: content/browser/renderer_host/video_capture_host.cc

Issue 7002027: VideoCaptureHost (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/renderer_host/video_capture_host.cc
===================================================================
--- content/browser/renderer_host/video_capture_host.cc (revision 0)
+++ content/browser/renderer_host/video_capture_host.cc (revision 0)
@@ -0,0 +1,249 @@
+// Copyright (c) 2011 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/browser/renderer_host/video_capture_host.h"
+
+#include "base/memory/scoped_ptr.h"
+#include "base/stl_util-inl.h"
+#include "content/browser/media_stream/video_capture_manager.h"
+#include "content/common/video_capture_messages.h"
+
+VideoCaptureHost::VideoCaptureHost() {}
+
+VideoCaptureHost::~VideoCaptureHost() {
+ DCHECK(vc_entries_.empty());
+ // Delete all Memory handlers that have been stopped but not returned all
+ // TransportDIBs.
+ STLDeleteContainerPairSecondPointers(vc_stoped_entries_.begin(),
+ vc_stoped_entries_.end());
+ vc_stoped_entries_.clear();
+}
+
+void VideoCaptureHost::OnChannelClosing() {
+ BrowserMessageFilter::OnChannelClosing();
+
+ // Since the IPC channel is gone, close all requested VideCaptureDevices.
+ for (VCEntryMap::iterator it = vc_entries_.begin();
+ it != vc_entries_.end(); it++) {
+ StopVideoCapture(it->second->entry_id());
+ }
+}
+
+void VideoCaptureHost::OnDestruct() const {
+ BrowserThread::DeleteOnIOThread::Destruct(this);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+// Implements VideoCaptureMemory::EventHandler.
+void VideoCaptureHost::OnError(VideoCaptureMemory::VCEntryId entry) {
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ NewRunnableMethod(this, &VideoCaptureHost::DoHandleError, entry));
+}
+
+void VideoCaptureHost::OnBufferReady(VideoCaptureMemory::VCEntryId entry,
+ TransportDIB::Handle handle,
+ base::Time timestamp) {
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ NewRunnableMethod(this, &VideoCaptureHost::DoSendFilledBuffer, entry,
+ handle, timestamp));
+}
+
+void VideoCaptureHost::OnFrameInfo(VideoCaptureMemory::VCEntryId entry,
+ int width,
+ int height,
+ int frame_per_second) {
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ NewRunnableMethod(this, &VideoCaptureHost::DoSendFrameInfo, entry, width,
+ height, frame_per_second));
+}
+
+void VideoCaptureHost::DoSendFilledBuffer(VideoCaptureMemory::VCEntryId entry,
+ TransportDIB::Handle handle,
+ base::Time timestamp) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ Send(new VideoCaptureMsg_BufferReady(entry.render_id, entry.device_id, handle,
+ timestamp));
+}
+
+void VideoCaptureHost::DoHandleError(VideoCaptureMemory::VCEntryId entry) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ SendErrorMessage(entry.render_id, entry.device_id);
+ StopVideoCapture(entry);
+}
+
+void VideoCaptureHost::DoSendFrameInfo(VideoCaptureMemory::VCEntryId entry,
+ int width,
+ int height,
+ int frame_per_second) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ media::VideoCaptureParams params;
+ params.width = width;
+ params.height = height;
+ params.frame_per_second = frame_per_second;
+ Send(new VideoCaptureMsg_DeviceInfo(entry.render_id,
+ entry.device_id,
+ params));
+ Send(new VideoCaptureMsg_StateChanged(entry.render_id, entry.device_id,
+ media::VideoCapture::kStarted));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// IPC Messages handler.
+bool VideoCaptureHost::OnMessageReceived(const IPC::Message& message,
+ bool* message_was_ok) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP_EX(VideoCaptureHost, message, *message_was_ok)
+ IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Start, OnStartCapture)
+ IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Pause, OnPauseCapture)
+ IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Stop, OnStopCapture)
+ IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_BufferReady, OnReceiveEmptyBuffer)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP_EX()
+
+ return handled;
+}
+
+void VideoCaptureHost::OnStartCapture(
+ const IPC::Message& msg, int device_id,
wjia(left Chromium) 2011/05/11 23:23:31 indent
Per K 2011/05/16 11:49:39 Done.
+ const media::VideoCaptureParams& params) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ VideoCaptureMemory::VCEntryId entry(msg.routing_id(),
+ device_id,
+ params.session_id);
+ // Check that it is not already started.
+ DCHECK(LookupStartedDevicesById(device_id) == NULL);
+ VideoCaptureMemory* memory_handler = new VideoCaptureMemory(this, entry);
+ if (!memory_handler) {
+ SendErrorMessage(msg.routing_id(), device_id);
+ return;
+ }
+
+ media_stream::VideoCaptureManager* manager =
+ media_stream::VideoCaptureManager::Get();
+ // Order the manager to start the actual capture.
+ manager->Start(params, memory_handler);
+
+ vc_entries_.insert(std::make_pair(device_id, memory_handler));
wjia(left Chromium) 2011/05/11 23:23:31 Some thoughts about the modules: 1. Host only nee
Per K 2011/05/16 11:49:39 VCEntryId moved to VideoCaptureHost and called Vid
+}
+
+void VideoCaptureHost::OnStopCapture(const IPC::Message& msg, int device_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ VideoCaptureMemory* memory_handler = LookupStartedDevicesById(device_id);
wjia(left Chromium) 2011/05/11 23:23:31 would it be good to pass Stop command to memory_ha
Per K 2011/05/16 11:49:39 Done.
+ if (!memory_handler) {
+ // Check if the device is being stopped
+ if (!LookupStopedDevicesById(device_id)) {
+ // It does not exist so it must have been stopped already.
+ Send(new VideoCaptureMsg_StateChanged(msg.routing_id(), device_id,
+ media::VideoCapture::kStopped));
+ }
+ return;
+ }
+ StopVideoCapture(memory_handler->entry_id());
+}
+
+void VideoCaptureHost::OnPauseCapture(const IPC::Message& msg, int device_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ // Not used.
+ SendErrorMessage(msg.routing_id(), device_id);
+}
+
+void VideoCaptureHost::OnReceiveEmptyBuffer(const IPC::Message& msg,
+ int device_id,
+ TransportDIB::Handle handle) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ VideoCaptureMemory* memory_handler = LookupStartedDevicesById(device_id);
+ if (!memory_handler || memory_handler->AddTransportDIB(handle) != 0) {
+ // This buffer do not belong to an active VideoCaptureMemory instance
+ // Check the Stopped Devices.
+ memory_handler = LookupStopedDevicesById(device_id);
+ if (memory_handler) {
+ memory_handler->AddTransportDIB(handle);
+ if (memory_handler->ReadyToDelete()) {
+ SendDeviceStopped(msg.routing_id(), device_id);
+ scoped_ptr<VideoCaptureMemory> item_to_delete(memory_handler);
+ vc_stoped_entries_.erase(device_id);
+ }
+ }
+ }
+}
+
+void VideoCaptureHost::StopVideoCapture(VideoCaptureMemory::VCEntryId entry) {
+ media_stream::VideoCaptureManager* manager =
+ media_stream::VideoCaptureManager::Get();
+ manager->Stop(entry.session_id,
+ NewRunnableMethod(this, &VideoCaptureHost::OnDeviceStoped,
+ entry.device_id));
+}
+
+void VideoCaptureHost::OnDeviceStoped(int device_id) {
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ NewRunnableMethod(this, &VideoCaptureHost::DoDeviceStoped, device_id));
+}
+
+void VideoCaptureHost::DoDeviceStoped(int device_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ scoped_ptr<VideoCaptureMemory> memory_handler(
+ LookupStartedDevicesById(device_id));
+ if (!memory_handler.get()) {
+ return;
+ }
+
+ vc_entries_.erase(device_id);
+
+ // If we can not delete the memory_handler now because all
+ // DIBS have not been returned we add the vc_entry to the list of stopped
+ // devices and do it later and hopefully get the missing DIB back soon.
+ if (!memory_handler->ReadyToDelete()) {
+ vc_stoped_entries_.insert(
+ std::make_pair(device_id, memory_handler.release()));
+ } else {
+ // We have received all buffers and is ready to delete the memory pool.
+ const VideoCaptureMemory::VCEntryId entry_id = memory_handler->entry_id();
+ SendDeviceStopped(entry_id.render_id, entry_id.device_id);
+ }
+}
+
+void VideoCaptureHost::SendDeviceStopped(int32 render_view_id, int device_id) {
+ // Report that the device have successfully been stopped.
+ Send(new VideoCaptureMsg_StateChanged(render_view_id, device_id,
+ media::VideoCapture::kStopped));
+}
+
+void VideoCaptureHost::SendErrorMessage(int32 render_view_id, int32 device_id) {
+ Send(new VideoCaptureMsg_StateChanged(render_view_id, device_id,
+ media::VideoCapture::kError));
wjia(left Chromium) 2011/05/11 23:23:31 Is it needed for renderer process to distinguish d
Per K 2011/05/16 11:49:39 I am not really sure we will be able to distinguis
+}
+
+VideoCaptureMemory* VideoCaptureHost::LookupStartedDevicesById(int device_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ VCEntryMap::iterator it = vc_entries_.find(device_id);
+ if (it != vc_entries_.end()) {
+ return it->second;
+ }
+
+ return NULL;
+}
+
+VideoCaptureMemory* VideoCaptureHost::LookupStopedDevicesById(int device_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ VCEntryMap::iterator it = vc_stoped_entries_.find(device_id);
+ if (it != vc_stoped_entries_.end()) {
+ return it->second;
+ }
+
+ return NULL;
+}

Powered by Google App Engine
This is Rietveld 408576698