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

Side by Side Diff: trunk/src/content/browser/renderer_host/media/video_capture_controller.cc

Issue 84393002: Revert 236927 "Reorganize media::VideoCapture* types" (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: Created 7 years, 1 month 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/renderer_host/media/video_capture_controller.h" 5 #include "content/browser/renderer_host/media/video_capture_controller.h"
6 6
7 #include <set> 7 #include <set>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
11 #include "base/stl_util.h" 11 #include "base/stl_util.h"
12 #include "content/browser/renderer_host/media/media_stream_manager.h" 12 #include "content/browser/renderer_host/media/media_stream_manager.h"
13 #include "content/browser/renderer_host/media/video_capture_manager.h" 13 #include "content/browser/renderer_host/media/video_capture_manager.h"
14 #include "content/public/browser/browser_thread.h" 14 #include "content/public/browser/browser_thread.h"
15 #include "media/base/video_frame.h" 15 #include "media/base/video_frame.h"
16 #include "media/base/video_util.h" 16 #include "media/base/video_util.h"
17 #include "media/base/yuv_convert.h" 17 #include "media/base/yuv_convert.h"
18 18
19 #if !defined(AVOID_LIBYUV_FOR_ANDROID_WEBVIEW) 19 #if !defined(AVOID_LIBYUV_FOR_ANDROID_WEBVIEW)
20 #include "third_party/libyuv/include/libyuv.h" 20 #include "third_party/libyuv/include/libyuv.h"
21 #endif 21 #endif
22 22
23 using media::VideoCaptureFormat; 23 using media::VideoCaptureCapability;
24 24
25 namespace content { 25 namespace content {
26 26
27 namespace { 27 namespace {
28 28
29 // The number of buffers that VideoCaptureBufferPool should allocate. 29 // The number of buffers that VideoCaptureBufferPool should allocate.
30 const int kNoOfBuffers = 3; 30 const int kNoOfBuffers = 3;
31 31
32 class PoolBuffer : public media::VideoCaptureDevice::Client::Buffer { 32 class PoolBuffer : public media::VideoCaptureDevice::Client::Buffer {
33 public: 33 public:
34 PoolBuffer(const scoped_refptr<VideoCaptureBufferPool>& pool, 34 PoolBuffer(const scoped_refptr<VideoCaptureBufferPool>& pool,
35 int buffer_id, 35 int buffer_id,
36 void* data, 36 void* data,
37 size_t size) 37 size_t size)
38 : Buffer(buffer_id, data, size), pool_(pool) { 38 : Buffer(buffer_id, data, size), pool_(pool) {
39 DCHECK(pool_); 39 DCHECK(pool_);
40 } 40 }
41 41
42 private: 42 private:
43 virtual ~PoolBuffer() { pool_->RelinquishProducerReservation(id()); } 43 virtual ~PoolBuffer() { pool_->RelinquishProducerReservation(id()); }
44 44
45 const scoped_refptr<VideoCaptureBufferPool> pool_; 45 const scoped_refptr<VideoCaptureBufferPool> pool_;
46 }; 46 };
47 47
48 } // anonymous namespace 48 } // anonymous namespace
49 49
50 struct VideoCaptureController::ControllerClient { 50 struct VideoCaptureController::ControllerClient {
51 ControllerClient(const VideoCaptureControllerID& id, 51 ControllerClient(
52 VideoCaptureControllerEventHandler* handler, 52 const VideoCaptureControllerID& id,
53 base::ProcessHandle render_process, 53 VideoCaptureControllerEventHandler* handler,
54 media::VideoCaptureSessionId session_id, 54 base::ProcessHandle render_process,
55 const media::VideoCaptureParams& params) 55 const media::VideoCaptureParams& params)
56 : controller_id(id), 56 : controller_id(id),
57 event_handler(handler), 57 event_handler(handler),
58 render_process_handle(render_process), 58 render_process_handle(render_process),
59 session_id(session_id),
60 parameters(params), 59 parameters(params),
61 session_closed(false) {} 60 session_closed(false) {
61 }
62 62
63 ~ControllerClient() {} 63 ~ControllerClient() {}
64 64
65 // ID used for identifying this object. 65 // ID used for identifying this object.
66 const VideoCaptureControllerID controller_id; 66 VideoCaptureControllerID controller_id;
67 VideoCaptureControllerEventHandler* const event_handler; 67 VideoCaptureControllerEventHandler* event_handler;
68 68
69 // Handle to the render process that will receive the capture buffers. 69 // Handle to the render process that will receive the capture buffers.
70 const base::ProcessHandle render_process_handle; 70 base::ProcessHandle render_process_handle;
71 const media::VideoCaptureSessionId session_id; 71 media::VideoCaptureParams parameters;
72 const media::VideoCaptureParams parameters;
73 72
74 // Buffers that are currently known to this client. 73 // Buffers that are currently known to this client.
75 std::set<int> known_buffers; 74 std::set<int> known_buffers;
76 75
77 // Buffers currently held by this client. 76 // Buffers currently held by this client.
78 std::set<int> active_buffers; 77 std::set<int> active_buffers;
79 78
80 // State of capture session, controlled by VideoCaptureManager directly. This 79 // State of capture session, controlled by VideoCaptureManager directly. This
81 // transitions to true as soon as StopSession() occurs, at which point the 80 // transitions to true as soon as StopSession() occurs, at which point the
82 // client is sent an OnEnded() event. However, because the client retains a 81 // client is sent an OnEnded() event. However, because the client retains a
(...skipping 26 matching lines...) Expand all
109 // VideoCaptureDevice::Client implementation. 108 // VideoCaptureDevice::Client implementation.
110 virtual scoped_refptr<Buffer> ReserveOutputBuffer( 109 virtual scoped_refptr<Buffer> ReserveOutputBuffer(
111 media::VideoFrame::Format format, 110 media::VideoFrame::Format format,
112 const gfx::Size& size) OVERRIDE; 111 const gfx::Size& size) OVERRIDE;
113 virtual void OnIncomingCapturedFrame(const uint8* data, 112 virtual void OnIncomingCapturedFrame(const uint8* data,
114 int length, 113 int length,
115 base::Time timestamp, 114 base::Time timestamp,
116 int rotation, 115 int rotation,
117 bool flip_vert, 116 bool flip_vert,
118 bool flip_horiz, 117 bool flip_horiz,
119 const VideoCaptureFormat& frame_format) 118 const VideoCaptureCapability& frame_info)
120 OVERRIDE; 119 OVERRIDE;
121 virtual void OnIncomingCapturedBuffer(const scoped_refptr<Buffer>& buffer, 120 virtual void OnIncomingCapturedBuffer(const scoped_refptr<Buffer>& buffer,
122 media::VideoFrame::Format format, 121 media::VideoFrame::Format format,
123 const gfx::Size& dimensions, 122 const gfx::Size& dimensions,
124 base::Time timestamp, 123 base::Time timestamp,
125 int frame_rate) OVERRIDE; 124 int frame_rate) OVERRIDE;
126 virtual void OnError() OVERRIDE; 125 virtual void OnError() OVERRIDE;
127 126
128 private: 127 private:
129 scoped_refptr<Buffer> DoReserveOutputBuffer(media::VideoFrame::Format format, 128 scoped_refptr<Buffer> DoReserveOutputBuffer(media::VideoFrame::Format format,
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 VideoCaptureController::NewDeviceClient() { 160 VideoCaptureController::NewDeviceClient() {
162 scoped_ptr<media::VideoCaptureDevice::Client> result( 161 scoped_ptr<media::VideoCaptureDevice::Client> result(
163 new VideoCaptureDeviceClient(this->GetWeakPtr(), buffer_pool_)); 162 new VideoCaptureDeviceClient(this->GetWeakPtr(), buffer_pool_));
164 return result.Pass(); 163 return result.Pass();
165 } 164 }
166 165
167 void VideoCaptureController::AddClient( 166 void VideoCaptureController::AddClient(
168 const VideoCaptureControllerID& id, 167 const VideoCaptureControllerID& id,
169 VideoCaptureControllerEventHandler* event_handler, 168 VideoCaptureControllerEventHandler* event_handler,
170 base::ProcessHandle render_process, 169 base::ProcessHandle render_process,
171 media::VideoCaptureSessionId session_id,
172 const media::VideoCaptureParams& params) { 170 const media::VideoCaptureParams& params) {
173 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 171 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
174 DVLOG(1) << "VideoCaptureController::AddClient, id " << id.device_id 172 DVLOG(1) << "VideoCaptureController::AddClient, id " << id.device_id
175 << ", " << params.requested_format.frame_size.ToString() 173 << ", (" << params.requested_format.width
174 << ", " << params.requested_format.height
176 << ", " << params.requested_format.frame_rate 175 << ", " << params.requested_format.frame_rate
177 << ", " << session_id 176 << ", " << params.session_id
178 << ")"; 177 << ")";
179 178
180 // Signal error in case device is already in error state. 179 // Signal error in case device is already in error state.
181 if (state_ == VIDEO_CAPTURE_STATE_ERROR) { 180 if (state_ == VIDEO_CAPTURE_STATE_ERROR) {
182 event_handler->OnError(id); 181 event_handler->OnError(id);
183 return; 182 return;
184 } 183 }
185 184
186 // Do nothing if this client has called AddClient before. 185 // Do nothing if this client has called AddClient before.
187 if (FindClient(id, event_handler, controller_clients_)) 186 if (FindClient(id, event_handler, controller_clients_))
188 return; 187 return;
189 188
190 ControllerClient* client = new ControllerClient( 189 ControllerClient* client = new ControllerClient(id, event_handler,
191 id, event_handler, render_process, session_id, params); 190 render_process, params);
192 // If we already have gotten frame_info from the device, repeat it to the new 191 // If we already have gotten frame_info from the device, repeat it to the new
193 // client. 192 // client.
194 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { 193 if (state_ == VIDEO_CAPTURE_STATE_STARTED) {
195 controller_clients_.push_back(client); 194 controller_clients_.push_back(client);
196 return; 195 return;
197 } 196 }
198 } 197 }
199 198
200 int VideoCaptureController::RemoveClient( 199 int VideoCaptureController::RemoveClient(
201 const VideoCaptureControllerID& id, 200 const VideoCaptureControllerID& id,
202 VideoCaptureControllerEventHandler* event_handler) { 201 VideoCaptureControllerEventHandler* event_handler) {
203 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 202 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
204 DVLOG(1) << "VideoCaptureController::RemoveClient, id " << id.device_id; 203 DVLOG(1) << "VideoCaptureController::RemoveClient, id " << id.device_id;
205 204
206 ControllerClient* client = FindClient(id, event_handler, controller_clients_); 205 ControllerClient* client = FindClient(id, event_handler, controller_clients_);
207 if (!client) 206 if (!client)
208 return kInvalidMediaCaptureSessionId; 207 return kInvalidMediaCaptureSessionId;
209 208
210 // Take back all buffers held by the |client|. 209 // Take back all buffers held by the |client|.
211 for (std::set<int>::iterator buffer_it = client->active_buffers.begin(); 210 for (std::set<int>::iterator buffer_it = client->active_buffers.begin();
212 buffer_it != client->active_buffers.end(); 211 buffer_it != client->active_buffers.end();
213 ++buffer_it) { 212 ++buffer_it) {
214 int buffer_id = *buffer_it; 213 int buffer_id = *buffer_it;
215 buffer_pool_->RelinquishConsumerHold(buffer_id, 1); 214 buffer_pool_->RelinquishConsumerHold(buffer_id, 1);
216 } 215 }
217 client->active_buffers.clear(); 216 client->active_buffers.clear();
218 217
219 int session_id = client->session_id; 218 int session_id = client->parameters.session_id;
220 controller_clients_.remove(client); 219 controller_clients_.remove(client);
221 delete client; 220 delete client;
222 221
223 return session_id; 222 return session_id;
224 } 223 }
225 224
226 void VideoCaptureController::StopSession(int session_id) { 225 void VideoCaptureController::StopSession(int session_id) {
227 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 226 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
228 DVLOG(1) << "VideoCaptureController::StopSession, id " << session_id; 227 DVLOG(1) << "VideoCaptureController::StopSession, id " << session_id;
229 228
(...skipping 30 matching lines...) Expand all
260 return DoReserveOutputBuffer(format, size, 0); 259 return DoReserveOutputBuffer(format, size, 0);
261 } 260 }
262 261
263 void VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedFrame( 262 void VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedFrame(
264 const uint8* data, 263 const uint8* data,
265 int length, 264 int length,
266 base::Time timestamp, 265 base::Time timestamp,
267 int rotation, 266 int rotation,
268 bool flip_vert, 267 bool flip_vert,
269 bool flip_horiz, 268 bool flip_horiz,
270 const VideoCaptureFormat& frame_format) { 269 const VideoCaptureCapability& frame_info) {
271 TRACE_EVENT0("video", "VideoCaptureController::OnIncomingCapturedFrame"); 270 TRACE_EVENT0("video", "VideoCaptureController::OnIncomingCapturedFrame");
272 271
273 if (!frame_format.IsValid()) 272 if (!frame_info.IsValid())
274 return; 273 return;
275 274
276 // Chopped pixels in width/height in case video capture device has odd 275 // Chopped pixels in width/height in case video capture device has odd
277 // numbers for width/height. 276 // numbers for width/height.
278 int chopped_width = 0; 277 int chopped_width = 0;
279 int chopped_height = 0; 278 int chopped_height = 0;
280 int new_width = frame_format.frame_size.width(); 279 int new_width = frame_info.width;
281 int new_height = frame_format.frame_size.height(); 280 int new_height = frame_info.height;
282 281
283 if (new_width & 1) { 282 if (frame_info.width & 1) {
284 --new_width; 283 --new_width;
285 chopped_width = 1; 284 chopped_width = 1;
286 } 285 }
287 if (new_height & 1) { 286 if (frame_info.height & 1) {
288 --new_height; 287 --new_height;
289 chopped_height = 1; 288 chopped_height = 1;
290 } 289 }
291 290
292 const gfx::Size dimensions(new_width, new_height); 291 const gfx::Size dimensions(new_width, new_height);
293 scoped_refptr<Buffer> buffer = 292 scoped_refptr<Buffer> buffer =
294 DoReserveOutputBuffer(media::VideoFrame::I420, dimensions, rotation); 293 DoReserveOutputBuffer(media::VideoFrame::I420, dimensions, rotation);
295 294
296 if (!buffer) 295 if (!buffer)
297 return; 296 return;
(...skipping 20 matching lines...) Expand all
318 // new_vertical_flip = horizontal_flip XOR vertical_flip 317 // new_vertical_flip = horizontal_flip XOR vertical_flip
319 int new_rotation_angle = (rotation + 180 * flip_vert) % 360; 318 int new_rotation_angle = (rotation + 180 * flip_vert) % 360;
320 libyuv::RotationMode rotation_mode = libyuv::kRotate0; 319 libyuv::RotationMode rotation_mode = libyuv::kRotate0;
321 if (new_rotation_angle == 90) 320 if (new_rotation_angle == 90)
322 rotation_mode = libyuv::kRotate90; 321 rotation_mode = libyuv::kRotate90;
323 else if (new_rotation_angle == 180) 322 else if (new_rotation_angle == 180)
324 rotation_mode = libyuv::kRotate180; 323 rotation_mode = libyuv::kRotate180;
325 else if (new_rotation_angle == 270) 324 else if (new_rotation_angle == 270)
326 rotation_mode = libyuv::kRotate270; 325 rotation_mode = libyuv::kRotate270;
327 326
328 switch (frame_format.pixel_format) { 327 switch (frame_info.color) {
329 case media::PIXEL_FORMAT_UNKNOWN: // Color format not set. 328 case media::PIXEL_FORMAT_UNKNOWN: // Color format not set.
330 break; 329 break;
331 case media::PIXEL_FORMAT_I420: 330 case media::PIXEL_FORMAT_I420:
332 DCHECK(!chopped_width && !chopped_height); 331 DCHECK(!chopped_width && !chopped_height);
333 origin_colorspace = libyuv::FOURCC_I420; 332 origin_colorspace = libyuv::FOURCC_I420;
334 break; 333 break;
335 case media::PIXEL_FORMAT_YV12: 334 case media::PIXEL_FORMAT_YV12:
336 DCHECK(!chopped_width && !chopped_height); 335 DCHECK(!chopped_width && !chopped_height);
337 origin_colorspace = libyuv::FOURCC_YV12; 336 origin_colorspace = libyuv::FOURCC_YV12;
338 break; 337 break;
(...skipping 19 matching lines...) Expand all
358 origin_colorspace = libyuv::FOURCC_MJPG; 357 origin_colorspace = libyuv::FOURCC_MJPG;
359 break; 358 break;
360 default: 359 default:
361 NOTREACHED(); 360 NOTREACHED();
362 } 361 }
363 362
364 int need_convert_rgb24_on_win = false; 363 int need_convert_rgb24_on_win = false;
365 #if defined(OS_WIN) 364 #if defined(OS_WIN)
366 // kRGB24 on Windows start at the bottom line and has a negative stride. This 365 // kRGB24 on Windows start at the bottom line and has a negative stride. This
367 // is not supported by libyuv, so the media API is used instead. 366 // is not supported by libyuv, so the media API is used instead.
368 if (frame_format.pixel_format == media::PIXEL_FORMAT_RGB24) { 367 if (frame_info.color == media::PIXEL_FORMAT_RGB24) {
369 // Rotation and flipping is not supported in kRGB24 and OS_WIN case. 368 // Rotation and flipping is not supported in kRGB24 and OS_WIN case.
370 DCHECK(!rotation && !flip_vert && !flip_horiz); 369 DCHECK(!rotation && !flip_vert && !flip_horiz);
371 need_convert_rgb24_on_win = true; 370 need_convert_rgb24_on_win = true;
372 } 371 }
373 #endif 372 #endif
374 if (need_convert_rgb24_on_win) { 373 if (need_convert_rgb24_on_win) {
375 int rgb_stride = -3 * (new_width + chopped_width); 374 int rgb_stride = -3 * (new_width + chopped_width);
376 const uint8* rgb_src = data + 3 * (new_width + chopped_width) * 375 const uint8* rgb_src = data + 3 * (new_width + chopped_width) *
377 (new_height - 1 + chopped_height); 376 (new_height - 1 + chopped_height);
378 media::ConvertRGB24ToYUV(rgb_src, 377 media::ConvertRGB24ToYUV(rgb_src,
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
428 NOTREACHED(); 427 NOTREACHED();
429 #endif // if !defined(AVOID_LIBYUV_FOR_ANDROID_WEBVIEW) 428 #endif // if !defined(AVOID_LIBYUV_FOR_ANDROID_WEBVIEW)
430 BrowserThread::PostTask( 429 BrowserThread::PostTask(
431 BrowserThread::IO, 430 BrowserThread::IO,
432 FROM_HERE, 431 FROM_HERE,
433 base::Bind( 432 base::Bind(
434 &VideoCaptureController::DoIncomingCapturedI420BufferOnIOThread, 433 &VideoCaptureController::DoIncomingCapturedI420BufferOnIOThread,
435 controller_, 434 controller_,
436 buffer, 435 buffer,
437 dimensions, 436 dimensions,
438 frame_format.frame_rate, 437 frame_info.frame_rate,
439 timestamp)); 438 timestamp));
440 } 439 }
441 440
442 void VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedBuffer( 441 void VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedBuffer(
443 const scoped_refptr<Buffer>& buffer, 442 const scoped_refptr<Buffer>& buffer,
444 media::VideoFrame::Format format, 443 media::VideoFrame::Format format,
445 const gfx::Size& dimensions, 444 const gfx::Size& dimensions,
446 base::Time timestamp, 445 base::Time timestamp,
447 int frame_rate) { 446 int frame_rate) {
448 // The capture pipeline expects I420 for now. 447 // The capture pipeline expects I420 for now.
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 } 517 }
519 518
520 void VideoCaptureController::DoIncomingCapturedI420BufferOnIOThread( 519 void VideoCaptureController::DoIncomingCapturedI420BufferOnIOThread(
521 scoped_refptr<media::VideoCaptureDevice::Client::Buffer> buffer, 520 scoped_refptr<media::VideoCaptureDevice::Client::Buffer> buffer,
522 const gfx::Size& dimensions, 521 const gfx::Size& dimensions,
523 int frame_rate, 522 int frame_rate,
524 base::Time timestamp) { 523 base::Time timestamp) {
525 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 524 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
526 DCHECK_NE(buffer->id(), VideoCaptureBufferPool::kInvalidId); 525 DCHECK_NE(buffer->id(), VideoCaptureBufferPool::kInvalidId);
527 526
528 VideoCaptureFormat frame_format( 527 media::VideoCaptureFormat frame_format(
529 dimensions, frame_rate, media::PIXEL_FORMAT_I420); 528 dimensions.width(),
529 dimensions.height(),
530 frame_rate,
531 media::VariableResolutionVideoCaptureDevice);
530 532
531 int count = 0; 533 int count = 0;
532 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { 534 if (state_ == VIDEO_CAPTURE_STATE_STARTED) {
533 for (ControllerClients::iterator client_it = controller_clients_.begin(); 535 for (ControllerClients::iterator client_it = controller_clients_.begin();
534 client_it != controller_clients_.end(); ++client_it) { 536 client_it != controller_clients_.end(); ++client_it) {
535 ControllerClient* client = *client_it; 537 ControllerClient* client = *client_it;
536 if (client->session_closed) 538 if (client->session_closed)
537 continue; 539 continue;
538 540
539 bool is_new_buffer = client->known_buffers.insert(buffer->id()).second; 541 bool is_new_buffer = client->known_buffers.insert(buffer->id()).second;
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 } 604 }
603 return NULL; 605 return NULL;
604 } 606 }
605 607
606 VideoCaptureController::ControllerClient* 608 VideoCaptureController::ControllerClient*
607 VideoCaptureController::FindClient( 609 VideoCaptureController::FindClient(
608 int session_id, 610 int session_id,
609 const ControllerClients& clients) { 611 const ControllerClients& clients) {
610 for (ControllerClients::const_iterator client_it = clients.begin(); 612 for (ControllerClients::const_iterator client_it = clients.begin();
611 client_it != clients.end(); ++client_it) { 613 client_it != clients.end(); ++client_it) {
612 if ((*client_it)->session_id == session_id) { 614 if ((*client_it)->parameters.session_id == session_id) {
613 return *client_it; 615 return *client_it;
614 } 616 }
615 } 617 }
616 return NULL; 618 return NULL;
617 } 619 }
618 620
619 int VideoCaptureController::GetClientCount() { 621 int VideoCaptureController::GetClientCount() {
620 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 622 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
621 return controller_clients_.size(); 623 return controller_clients_.size();
622 } 624 }
623 625
624 } // namespace content 626 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698