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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 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/browser/renderer_host/video_capture_host.h"
6
7 #include "base/memory/scoped_ptr.h"
8 #include "base/stl_util-inl.h"
9 #include "content/browser/media_stream/video_capture_manager.h"
10 #include "content/common/video_capture_messages.h"
11
12 VideoCaptureHost::VideoCaptureHost() {}
13
14 VideoCaptureHost::~VideoCaptureHost() {
15 DCHECK(vc_entries_.empty());
16 // Delete all Memory handlers that have been stopped but not returned all
17 // TransportDIBs.
18 STLDeleteContainerPairSecondPointers(vc_stoped_entries_.begin(),
19 vc_stoped_entries_.end());
20 vc_stoped_entries_.clear();
21 }
22
23 void VideoCaptureHost::OnChannelClosing() {
24 BrowserMessageFilter::OnChannelClosing();
25
26 // Since the IPC channel is gone, close all requested VideCaptureDevices.
27 for (VCEntryMap::iterator it = vc_entries_.begin();
28 it != vc_entries_.end(); it++) {
29 StopVideoCapture(it->second->entry_id());
30 }
31 }
32
33 void VideoCaptureHost::OnDestruct() const {
34 BrowserThread::DeleteOnIOThread::Destruct(this);
35 }
36
37 ///////////////////////////////////////////////////////////////////////////////
38
39 // Implements VideoCaptureMemory::EventHandler.
40 void VideoCaptureHost::OnError(VideoCaptureMemory::VCEntryId entry) {
41 BrowserThread::PostTask(
42 BrowserThread::IO, FROM_HERE,
43 NewRunnableMethod(this, &VideoCaptureHost::DoHandleError, entry));
44 }
45
46 void VideoCaptureHost::OnBufferReady(VideoCaptureMemory::VCEntryId entry,
47 TransportDIB::Handle handle,
48 base::Time timestamp) {
49 BrowserThread::PostTask(
50 BrowserThread::IO, FROM_HERE,
51 NewRunnableMethod(this, &VideoCaptureHost::DoSendFilledBuffer, entry,
52 handle, timestamp));
53 }
54
55 void VideoCaptureHost::OnFrameInfo(VideoCaptureMemory::VCEntryId entry,
56 int width,
57 int height,
58 int frame_per_second) {
59 BrowserThread::PostTask(
60 BrowserThread::IO, FROM_HERE,
61 NewRunnableMethod(this, &VideoCaptureHost::DoSendFrameInfo, entry, width,
62 height, frame_per_second));
63 }
64
65 void VideoCaptureHost::DoSendFilledBuffer(VideoCaptureMemory::VCEntryId entry,
66 TransportDIB::Handle handle,
67 base::Time timestamp) {
68 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
69
70 Send(new VideoCaptureMsg_BufferReady(entry.render_id, entry.device_id, handle,
71 timestamp));
72 }
73
74 void VideoCaptureHost::DoHandleError(VideoCaptureMemory::VCEntryId entry) {
75 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
76
77 SendErrorMessage(entry.render_id, entry.device_id);
78 StopVideoCapture(entry);
79 }
80
81 void VideoCaptureHost::DoSendFrameInfo(VideoCaptureMemory::VCEntryId entry,
82 int width,
83 int height,
84 int frame_per_second) {
85 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
86 media::VideoCaptureParams params;
87 params.width = width;
88 params.height = height;
89 params.frame_per_second = frame_per_second;
90 Send(new VideoCaptureMsg_DeviceInfo(entry.render_id,
91 entry.device_id,
92 params));
93 Send(new VideoCaptureMsg_StateChanged(entry.render_id, entry.device_id,
94 media::VideoCapture::kStarted));
95 }
96
97 ///////////////////////////////////////////////////////////////////////////////
98 // IPC Messages handler.
99 bool VideoCaptureHost::OnMessageReceived(const IPC::Message& message,
100 bool* message_was_ok) {
101 bool handled = true;
102 IPC_BEGIN_MESSAGE_MAP_EX(VideoCaptureHost, message, *message_was_ok)
103 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Start, OnStartCapture)
104 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Pause, OnPauseCapture)
105 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Stop, OnStopCapture)
106 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_BufferReady, OnReceiveEmptyBuffer)
107 IPC_MESSAGE_UNHANDLED(handled = false)
108 IPC_END_MESSAGE_MAP_EX()
109
110 return handled;
111 }
112
113 void VideoCaptureHost::OnStartCapture(
114 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.
115 const media::VideoCaptureParams& params) {
116 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
117
118 VideoCaptureMemory::VCEntryId entry(msg.routing_id(),
119 device_id,
120 params.session_id);
121 // Check that it is not already started.
122 DCHECK(LookupStartedDevicesById(device_id) == NULL);
123 VideoCaptureMemory* memory_handler = new VideoCaptureMemory(this, entry);
124 if (!memory_handler) {
125 SendErrorMessage(msg.routing_id(), device_id);
126 return;
127 }
128
129 media_stream::VideoCaptureManager* manager =
130 media_stream::VideoCaptureManager::Get();
131 // Order the manager to start the actual capture.
132 manager->Start(params, memory_handler);
133
134 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
135 }
136
137 void VideoCaptureHost::OnStopCapture(const IPC::Message& msg, int device_id) {
138 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
139
140 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.
141 if (!memory_handler) {
142 // Check if the device is being stopped
143 if (!LookupStopedDevicesById(device_id)) {
144 // It does not exist so it must have been stopped already.
145 Send(new VideoCaptureMsg_StateChanged(msg.routing_id(), device_id,
146 media::VideoCapture::kStopped));
147 }
148 return;
149 }
150 StopVideoCapture(memory_handler->entry_id());
151 }
152
153 void VideoCaptureHost::OnPauseCapture(const IPC::Message& msg, int device_id) {
154 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
155 // Not used.
156 SendErrorMessage(msg.routing_id(), device_id);
157 }
158
159 void VideoCaptureHost::OnReceiveEmptyBuffer(const IPC::Message& msg,
160 int device_id,
161 TransportDIB::Handle handle) {
162 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
163
164 VideoCaptureMemory* memory_handler = LookupStartedDevicesById(device_id);
165 if (!memory_handler || memory_handler->AddTransportDIB(handle) != 0) {
166 // This buffer do not belong to an active VideoCaptureMemory instance
167 // Check the Stopped Devices.
168 memory_handler = LookupStopedDevicesById(device_id);
169 if (memory_handler) {
170 memory_handler->AddTransportDIB(handle);
171 if (memory_handler->ReadyToDelete()) {
172 SendDeviceStopped(msg.routing_id(), device_id);
173 scoped_ptr<VideoCaptureMemory> item_to_delete(memory_handler);
174 vc_stoped_entries_.erase(device_id);
175 }
176 }
177 }
178 }
179
180 void VideoCaptureHost::StopVideoCapture(VideoCaptureMemory::VCEntryId entry) {
181 media_stream::VideoCaptureManager* manager =
182 media_stream::VideoCaptureManager::Get();
183 manager->Stop(entry.session_id,
184 NewRunnableMethod(this, &VideoCaptureHost::OnDeviceStoped,
185 entry.device_id));
186 }
187
188 void VideoCaptureHost::OnDeviceStoped(int device_id) {
189 BrowserThread::PostTask(
190 BrowserThread::IO, FROM_HERE,
191 NewRunnableMethod(this, &VideoCaptureHost::DoDeviceStoped, device_id));
192 }
193
194 void VideoCaptureHost::DoDeviceStoped(int device_id) {
195 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
196
197 scoped_ptr<VideoCaptureMemory> memory_handler(
198 LookupStartedDevicesById(device_id));
199 if (!memory_handler.get()) {
200 return;
201 }
202
203 vc_entries_.erase(device_id);
204
205 // If we can not delete the memory_handler now because all
206 // DIBS have not been returned we add the vc_entry to the list of stopped
207 // devices and do it later and hopefully get the missing DIB back soon.
208 if (!memory_handler->ReadyToDelete()) {
209 vc_stoped_entries_.insert(
210 std::make_pair(device_id, memory_handler.release()));
211 } else {
212 // We have received all buffers and is ready to delete the memory pool.
213 const VideoCaptureMemory::VCEntryId entry_id = memory_handler->entry_id();
214 SendDeviceStopped(entry_id.render_id, entry_id.device_id);
215 }
216 }
217
218 void VideoCaptureHost::SendDeviceStopped(int32 render_view_id, int device_id) {
219 // Report that the device have successfully been stopped.
220 Send(new VideoCaptureMsg_StateChanged(render_view_id, device_id,
221 media::VideoCapture::kStopped));
222 }
223
224 void VideoCaptureHost::SendErrorMessage(int32 render_view_id, int32 device_id) {
225 Send(new VideoCaptureMsg_StateChanged(render_view_id, device_id,
226 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
227 }
228
229 VideoCaptureMemory* VideoCaptureHost::LookupStartedDevicesById(int device_id) {
230 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
231
232 VCEntryMap::iterator it = vc_entries_.find(device_id);
233 if (it != vc_entries_.end()) {
234 return it->second;
235 }
236
237 return NULL;
238 }
239
240 VideoCaptureMemory* VideoCaptureHost::LookupStopedDevicesById(int device_id) {
241 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
242
243 VCEntryMap::iterator it = vc_stoped_entries_.find(device_id);
244 if (it != vc_stoped_entries_.end()) {
245 return it->second;
246 }
247
248 return NULL;
249 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698