video_capture_message_filter.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "content/renderer/media/video_capture_message_filter.h"
6
7#include "content/common/media/video_capture_messages.h"
8#include "content/common/view_messages.h"
9
10namespace content {
11
12VideoCaptureMessageFilter::VideoCaptureMessageFilter()
13    : last_device_id_(0),
14      channel_(NULL) {
15}
16
17void VideoCaptureMessageFilter::AddDelegate(Delegate* delegate) {
18  if (++last_device_id_ <= 0)
19    last_device_id_ = 1;
20  while (delegates_.find(last_device_id_) != delegates_.end())
21    last_device_id_++;
22
23  if (channel_) {
24    delegates_[last_device_id_] = delegate;
25    delegate->OnDelegateAdded(last_device_id_);
26  } else {
27    pending_delegates_[last_device_id_] = delegate;
28  }
29}
30
31void VideoCaptureMessageFilter::RemoveDelegate(Delegate* delegate) {
32  for (Delegates::iterator it = delegates_.begin();
33       it != delegates_.end(); it++) {
34    if (it->second == delegate) {
35      delegates_.erase(it);
36      break;
37    }
38  }
39  for (Delegates::iterator it = pending_delegates_.begin();
40       it != pending_delegates_.end(); it++) {
41    if (it->second == delegate) {
42      pending_delegates_.erase(it);
43      break;
44    }
45  }
46}
47
48bool VideoCaptureMessageFilter::Send(IPC::Message* message) {
49  if (!channel_) {
50    delete message;
51    return false;
52  }
53
54  return channel_->Send(message);
55}
56
57bool VideoCaptureMessageFilter::OnMessageReceived(const IPC::Message& message) {
58  bool handled = true;
59  IPC_BEGIN_MESSAGE_MAP(VideoCaptureMessageFilter, message)
60    IPC_MESSAGE_HANDLER(VideoCaptureMsg_BufferReady, OnBufferReceived)
61    IPC_MESSAGE_HANDLER(VideoCaptureMsg_MailboxBufferReady,
62                        OnMailboxBufferReceived)
63    IPC_MESSAGE_HANDLER(VideoCaptureMsg_StateChanged, OnDeviceStateChanged)
64    IPC_MESSAGE_HANDLER(VideoCaptureMsg_NewBuffer, OnBufferCreated)
65    IPC_MESSAGE_HANDLER(VideoCaptureMsg_FreeBuffer, OnBufferDestroyed)
66    IPC_MESSAGE_HANDLER(VideoCaptureMsg_DeviceSupportedFormatsEnumerated,
67                        OnDeviceSupportedFormatsEnumerated)
68    IPC_MESSAGE_HANDLER(VideoCaptureMsg_DeviceFormatsInUseReceived,
69                        OnDeviceFormatsInUseReceived)
70    IPC_MESSAGE_UNHANDLED(handled = false)
71  IPC_END_MESSAGE_MAP()
72  return handled;
73}
74
75void VideoCaptureMessageFilter::OnFilterAdded(IPC::Channel* channel) {
76  DVLOG(1) << "VideoCaptureMessageFilter::OnFilterAdded()";
77  channel_ = channel;
78
79  for (Delegates::iterator it = pending_delegates_.begin();
80       it != pending_delegates_.end(); it++) {
81    it->second->OnDelegateAdded(it->first);
82    delegates_[it->first] = it->second;
83  }
84  pending_delegates_.clear();
85}
86
87void VideoCaptureMessageFilter::OnFilterRemoved() {
88  channel_ = NULL;
89}
90
91void VideoCaptureMessageFilter::OnChannelClosing() {
92  channel_ = NULL;
93}
94
95VideoCaptureMessageFilter::~VideoCaptureMessageFilter() {}
96
97VideoCaptureMessageFilter::Delegate* VideoCaptureMessageFilter::find_delegate(
98    int device_id) const {
99  Delegates::const_iterator i = delegates_.find(device_id);
100  return i != delegates_.end() ? i->second : NULL;
101}
102
103void VideoCaptureMessageFilter::OnBufferCreated(
104    int device_id,
105    base::SharedMemoryHandle handle,
106    int length,
107    int buffer_id) {
108  Delegate* delegate = find_delegate(device_id);
109  if (!delegate) {
110    DLOG(WARNING) << "OnBufferCreated: Got video SHM buffer for a "
111                     "non-existent or removed video capture.";
112
113    // Send the buffer back to Host in case it's waiting for all buffers
114    // to be returned.
115    base::SharedMemory::CloseHandle(handle);
116    Send(new VideoCaptureHostMsg_BufferReady(device_id, buffer_id, 0));
117    return;
118  }
119
120  delegate->OnBufferCreated(handle, length, buffer_id);
121}
122
123void VideoCaptureMessageFilter::OnBufferReceived(
124    int device_id,
125    int buffer_id,
126    const media::VideoCaptureFormat& format,
127    base::TimeTicks timestamp) {
128  Delegate* delegate = find_delegate(device_id);
129  if (!delegate) {
130    DLOG(WARNING) << "OnBufferReceived: Got video SHM buffer for a "
131                     "non-existent or removed video capture.";
132
133    // Send the buffer back to Host in case it's waiting for all buffers
134    // to be returned.
135    Send(new VideoCaptureHostMsg_BufferReady(device_id, buffer_id, 0));
136    return;
137  }
138
139  delegate->OnBufferReceived(buffer_id, format, timestamp);
140}
141
142void VideoCaptureMessageFilter::OnMailboxBufferReceived(
143    int device_id,
144    int buffer_id,
145    const gpu::MailboxHolder& mailbox_holder,
146    const media::VideoCaptureFormat& format,
147    base::TimeTicks timestamp) {
148  Delegate* delegate = find_delegate(device_id);
149
150  if (!delegate) {
151    DLOG(WARNING) << "OnMailboxBufferReceived: Got video mailbox buffer for a "
152                     "non-existent or removed video capture.";
153
154    // Send the buffer back to Host in case it's waiting for all buffers
155    // to be returned.
156    Send(new VideoCaptureHostMsg_BufferReady(device_id, buffer_id, 0));
157    return;
158  }
159
160  delegate->OnMailboxBufferReceived(
161      buffer_id, mailbox_holder, format, timestamp);
162}
163
164void VideoCaptureMessageFilter::OnBufferDestroyed(
165    int device_id,
166    int buffer_id) {
167  Delegate* delegate = find_delegate(device_id);
168  if (!delegate) {
169    DLOG(WARNING) << "OnBufferDestroyed: Instructed to free buffer for a "
170        "non-existent or removed video capture.";
171    return;
172  }
173
174  delegate->OnBufferDestroyed(buffer_id);
175}
176
177void VideoCaptureMessageFilter::OnDeviceStateChanged(
178    int device_id,
179    VideoCaptureState state) {
180  Delegate* delegate = find_delegate(device_id);
181  if (!delegate) {
182    DLOG(WARNING) << "OnDeviceStateChanged: Got video capture event for a "
183        "non-existent or removed video capture.";
184    return;
185  }
186  delegate->OnStateChanged(state);
187}
188
189void VideoCaptureMessageFilter::OnDeviceSupportedFormatsEnumerated(
190    int device_id,
191    const media::VideoCaptureFormats& supported_formats) {
192  Delegate* delegate = find_delegate(device_id);
193  if (!delegate) {
194    DLOG(WARNING) << "OnDeviceFormatsEnumerated: unknown device";
195    return;
196  }
197  delegate->OnDeviceSupportedFormatsEnumerated(supported_formats);
198}
199
200void VideoCaptureMessageFilter::OnDeviceFormatsInUseReceived(
201    int device_id,
202    const media::VideoCaptureFormats& formats_in_use) {
203  Delegate* delegate = find_delegate(device_id);
204  if (!delegate) {
205    DLOG(WARNING) << "OnDeviceFormatInUse: unknown device";
206    return;
207  }
208  delegate->OnDeviceFormatsInUseReceived(formats_in_use);
209}
210
211}  // namespace content
212