blob: 0ef77fa1888a641140720f3ff9c531c48dc7cec6 [file] [log] [blame]
// 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_message_filter.h"
#include "content/common/media/video_capture_messages.h"
#include "content/common/view_messages.h"
namespace content {
VideoCaptureMessageFilter::VideoCaptureMessageFilter()
: last_device_id_(0),
channel_(NULL) {
}
void VideoCaptureMessageFilter::AddDelegate(Delegate* delegate) {
if (++last_device_id_ <= 0)
last_device_id_ = 1;
while (delegates_.find(last_device_id_) != delegates_.end())
last_device_id_++;
if (channel_) {
delegates_[last_device_id_] = delegate;
delegate->OnDelegateAdded(last_device_id_);
} else {
pending_delegates_[last_device_id_] = delegate;
}
}
void VideoCaptureMessageFilter::RemoveDelegate(Delegate* delegate) {
for (Delegates::iterator it = delegates_.begin();
it != delegates_.end(); it++) {
if (it->second == delegate) {
delegates_.erase(it);
break;
}
}
for (Delegates::iterator it = pending_delegates_.begin();
it != pending_delegates_.end(); it++) {
if (it->second == delegate) {
pending_delegates_.erase(it);
break;
}
}
}
bool VideoCaptureMessageFilter::Send(IPC::Message* message) {
if (!channel_) {
delete message;
return false;
}
return channel_->Send(message);
}
bool VideoCaptureMessageFilter::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(VideoCaptureMessageFilter, message)
IPC_MESSAGE_HANDLER(VideoCaptureMsg_BufferReady, OnBufferReceived)
IPC_MESSAGE_HANDLER(VideoCaptureMsg_StateChanged, OnDeviceStateChanged)
IPC_MESSAGE_HANDLER(VideoCaptureMsg_NewBuffer, OnBufferCreated)
IPC_MESSAGE_HANDLER(VideoCaptureMsg_DeviceInfo, OnDeviceInfoReceived)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void VideoCaptureMessageFilter::OnFilterAdded(IPC::Channel* channel) {
DVLOG(1) << "VideoCaptureMessageFilter::OnFilterAdded()";
// Captures the message loop proxy for IPC.
message_loop_proxy_ = base::MessageLoopProxy::current();
channel_ = channel;
for (Delegates::iterator it = pending_delegates_.begin();
it != pending_delegates_.end(); it++) {
it->second->OnDelegateAdded(it->first);
delegates_[it->first] = it->second;
}
pending_delegates_.clear();
}
void VideoCaptureMessageFilter::OnFilterRemoved() {
channel_ = NULL;
}
void VideoCaptureMessageFilter::OnChannelClosing() {
channel_ = NULL;
}
VideoCaptureMessageFilter::~VideoCaptureMessageFilter() {}
VideoCaptureMessageFilter::Delegate* VideoCaptureMessageFilter::find_delegate(
int device_id) const {
Delegates::const_iterator i = delegates_.find(device_id);
return i != delegates_.end() ? i->second : NULL;
}
void VideoCaptureMessageFilter::OnBufferCreated(
int device_id,
base::SharedMemoryHandle handle,
int length,
int buffer_id) {
Delegate* delegate = find_delegate(device_id);
if (!delegate) {
DLOG(WARNING) << "OnBufferCreated: Got video frame buffer for a "
"non-existent or removed video capture.";
// Send the buffer back to Host in case it's waiting for all buffers
// to be returned.
base::SharedMemory::CloseHandle(handle);
Send(new VideoCaptureHostMsg_BufferReady(device_id, buffer_id));
return;
}
delegate->OnBufferCreated(handle, length, buffer_id);
}
void VideoCaptureMessageFilter::OnBufferReceived(
int device_id,
int buffer_id,
base::Time timestamp) {
Delegate* delegate = find_delegate(device_id);
if (!delegate) {
DLOG(WARNING) << "OnBufferReceived: Got video frame buffer for a "
"non-existent or removed video capture.";
// Send the buffer back to Host in case it's waiting for all buffers
// to be returned.
Send(new VideoCaptureHostMsg_BufferReady(device_id, buffer_id));
return;
}
delegate->OnBufferReceived(buffer_id, timestamp);
}
void VideoCaptureMessageFilter::OnDeviceStateChanged(
int device_id,
VideoCaptureState state) {
Delegate* delegate = find_delegate(device_id);
if (!delegate) {
DLOG(WARNING) << "OnDeviceStateChanged: Got video capture event for a "
"non-existent or removed video capture.";
return;
}
delegate->OnStateChanged(state);
}
void VideoCaptureMessageFilter::OnDeviceInfoReceived(
int device_id,
const media::VideoCaptureParams& params) {
Delegate* delegate = find_delegate(device_id);
if (!delegate) {
DLOG(WARNING) << "OnDeviceInfoReceived: Got video capture event for a "
"non-existent or removed video capture.";
return;
}
delegate->OnDeviceInfoReceived(params);
}
} // namespace content