OLD | NEW |
---|---|
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 <map> | |
7 #include <set> | 8 #include <set> |
8 | 9 |
9 #include "base/bind.h" | 10 #include "base/bind.h" |
10 #include "base/debug/trace_event.h" | 11 #include "base/debug/trace_event.h" |
11 #include "base/stl_util.h" | 12 #include "base/stl_util.h" |
12 #include "content/browser/renderer_host/media/media_stream_manager.h" | 13 #include "content/browser/renderer_host/media/media_stream_manager.h" |
13 #include "content/browser/renderer_host/media/video_capture_manager.h" | 14 #include "content/browser/renderer_host/media/video_capture_manager.h" |
14 #include "content/public/browser/browser_thread.h" | 15 #include "content/public/browser/browser_thread.h" |
16 #include "gpu/command_buffer/common/mailbox_holder.h" | |
15 #include "media/base/video_frame.h" | 17 #include "media/base/video_frame.h" |
16 #include "media/base/video_util.h" | 18 #include "media/base/video_util.h" |
17 #include "media/base/yuv_convert.h" | 19 #include "media/base/yuv_convert.h" |
18 | 20 |
19 #if !defined(AVOID_LIBYUV_FOR_ANDROID_WEBVIEW) | 21 #if !defined(AVOID_LIBYUV_FOR_ANDROID_WEBVIEW) |
20 #include "third_party/libyuv/include/libyuv.h" | 22 #include "third_party/libyuv/include/libyuv.h" |
21 #endif | 23 #endif |
22 | 24 |
23 using media::VideoCaptureFormat; | 25 using media::VideoCaptureFormat; |
24 | 26 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
67 VideoCaptureControllerEventHandler* const event_handler; | 69 VideoCaptureControllerEventHandler* const event_handler; |
68 | 70 |
69 // Handle to the render process that will receive the capture buffers. | 71 // Handle to the render process that will receive the capture buffers. |
70 const base::ProcessHandle render_process_handle; | 72 const base::ProcessHandle render_process_handle; |
71 const media::VideoCaptureSessionId session_id; | 73 const media::VideoCaptureSessionId session_id; |
72 const media::VideoCaptureParams parameters; | 74 const media::VideoCaptureParams parameters; |
73 | 75 |
74 // Buffers that are currently known to this client. | 76 // Buffers that are currently known to this client. |
75 std::set<int> known_buffers; | 77 std::set<int> known_buffers; |
76 | 78 |
77 // Buffers currently held by this client. | 79 // Buffers currently held by this client, and syncpoint callback to call when |
78 std::set<int> active_buffers; | 80 // they are returned from the client. |
81 std::map<int, scoped_refptr<media::VideoFrame> > active_buffers; | |
79 | 82 |
80 // State of capture session, controlled by VideoCaptureManager directly. This | 83 // State of capture session, controlled by VideoCaptureManager directly. This |
81 // transitions to true as soon as StopSession() occurs, at which point the | 84 // 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 | 85 // client is sent an OnEnded() event. However, because the client retains a |
83 // VideoCaptureController* pointer, its ControllerClient entry lives on until | 86 // VideoCaptureController* pointer, its ControllerClient entry lives on until |
84 // it unregisters itself via RemoveClient(), which may happen asynchronously. | 87 // it unregisters itself via RemoveClient(), which may happen asynchronously. |
85 // | 88 // |
86 // TODO(nick): If we changed the semantics of VideoCaptureHost so that | 89 // TODO(nick): If we changed the semantics of VideoCaptureHost so that |
87 // OnEnded() events were processed synchronously (with the RemoveClient() done | 90 // OnEnded() events were processed synchronously (with the RemoveClient() done |
88 // implicitly), we could avoid tracking this state here in the Controller, and | 91 // implicitly), we could avoid tracking this state here in the Controller, and |
(...skipping 16 matching lines...) Expand all Loading... | |
105 const base::WeakPtr<VideoCaptureController>& controller, | 108 const base::WeakPtr<VideoCaptureController>& controller, |
106 const scoped_refptr<VideoCaptureBufferPool>& buffer_pool); | 109 const scoped_refptr<VideoCaptureBufferPool>& buffer_pool); |
107 virtual ~VideoCaptureDeviceClient(); | 110 virtual ~VideoCaptureDeviceClient(); |
108 | 111 |
109 // VideoCaptureDevice::Client implementation. | 112 // VideoCaptureDevice::Client implementation. |
110 virtual scoped_refptr<Buffer> ReserveOutputBuffer( | 113 virtual scoped_refptr<Buffer> ReserveOutputBuffer( |
111 media::VideoFrame::Format format, | 114 media::VideoFrame::Format format, |
112 const gfx::Size& size) OVERRIDE; | 115 const gfx::Size& size) OVERRIDE; |
113 virtual void OnIncomingCapturedFrame(const uint8* data, | 116 virtual void OnIncomingCapturedFrame(const uint8* data, |
114 int length, | 117 int length, |
115 base::TimeTicks timestamp, | 118 const VideoCaptureFormat& frame_format, |
116 int rotation, | 119 int rotation, |
117 const VideoCaptureFormat& frame_format) | 120 base::TimeTicks timestamp) OVERRIDE; |
118 OVERRIDE; | 121 virtual void OnIncomingCapturedVideoFrame( |
119 virtual void OnIncomingCapturedBuffer(const scoped_refptr<Buffer>& buffer, | 122 const scoped_refptr<Buffer>& buffer, |
120 media::VideoFrame::Format format, | 123 const VideoCaptureFormat& buffer_format, |
121 const gfx::Size& dimensions, | 124 const scoped_refptr<media::VideoFrame>& frame, |
122 base::TimeTicks timestamp, | 125 base::TimeTicks timestamp) OVERRIDE; |
123 int frame_rate) OVERRIDE; | |
124 virtual void OnError() OVERRIDE; | 126 virtual void OnError() OVERRIDE; |
125 | 127 |
126 private: | 128 private: |
127 scoped_refptr<Buffer> DoReserveOutputBuffer(media::VideoFrame::Format format, | 129 scoped_refptr<Buffer> DoReserveOutputBuffer(media::VideoFrame::Format format, |
128 const gfx::Size& dimensions); | 130 const gfx::Size& dimensions); |
129 | 131 |
130 // The controller to which we post events. | 132 // The controller to which we post events. |
131 const base::WeakPtr<VideoCaptureController> controller_; | 133 const base::WeakPtr<VideoCaptureController> controller_; |
132 | 134 |
133 // The pool of shared-memory buffers used for capturing. | 135 // The pool of shared-memory buffers used for capturing. |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
199 const VideoCaptureControllerID& id, | 201 const VideoCaptureControllerID& id, |
200 VideoCaptureControllerEventHandler* event_handler) { | 202 VideoCaptureControllerEventHandler* event_handler) { |
201 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 203 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
202 DVLOG(1) << "VideoCaptureController::RemoveClient, id " << id.device_id; | 204 DVLOG(1) << "VideoCaptureController::RemoveClient, id " << id.device_id; |
203 | 205 |
204 ControllerClient* client = FindClient(id, event_handler, controller_clients_); | 206 ControllerClient* client = FindClient(id, event_handler, controller_clients_); |
205 if (!client) | 207 if (!client) |
206 return kInvalidMediaCaptureSessionId; | 208 return kInvalidMediaCaptureSessionId; |
207 | 209 |
208 // Take back all buffers held by the |client|. | 210 // Take back all buffers held by the |client|. |
209 for (std::set<int>::iterator buffer_it = client->active_buffers.begin(); | 211 for (std::map<int, scoped_refptr<media::VideoFrame> >::iterator buffer_it = |
212 client->active_buffers.begin(); | |
210 buffer_it != client->active_buffers.end(); | 213 buffer_it != client->active_buffers.end(); |
211 ++buffer_it) { | 214 ++buffer_it) { |
212 int buffer_id = *buffer_it; | 215 buffer_pool_->RelinquishConsumerHold(buffer_it->first, 1); |
213 buffer_pool_->RelinquishConsumerHold(buffer_id, 1); | |
214 } | 216 } |
215 client->active_buffers.clear(); | 217 client->active_buffers.clear(); |
216 | 218 |
217 int session_id = client->session_id; | 219 int session_id = client->session_id; |
218 controller_clients_.remove(client); | 220 controller_clients_.remove(client); |
219 delete client; | 221 delete client; |
220 | 222 |
221 return session_id; | 223 return session_id; |
222 } | 224 } |
223 | 225 |
224 void VideoCaptureController::StopSession(int session_id) { | 226 void VideoCaptureController::StopSession(int session_id) { |
225 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 227 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
226 DVLOG(1) << "VideoCaptureController::StopSession, id " << session_id; | 228 DVLOG(1) << "VideoCaptureController::StopSession, id " << session_id; |
227 | 229 |
228 ControllerClient* client = FindClient(session_id, controller_clients_); | 230 ControllerClient* client = FindClient(session_id, controller_clients_); |
229 | 231 |
230 if (client) { | 232 if (client) { |
231 client->session_closed = true; | 233 client->session_closed = true; |
232 client->event_handler->OnEnded(client->controller_id); | 234 client->event_handler->OnEnded(client->controller_id); |
233 } | 235 } |
234 } | 236 } |
235 | 237 |
236 void VideoCaptureController::ReturnBuffer( | 238 void VideoCaptureController::ReturnBuffer( |
237 const VideoCaptureControllerID& id, | 239 const VideoCaptureControllerID& id, |
238 VideoCaptureControllerEventHandler* event_handler, | 240 VideoCaptureControllerEventHandler* event_handler, |
239 int buffer_id) { | 241 int buffer_id, |
242 uint32 sync_point) { | |
240 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 243 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
241 | 244 |
242 ControllerClient* client = FindClient(id, event_handler, controller_clients_); | 245 ControllerClient* client = FindClient(id, event_handler, controller_clients_); |
243 | 246 |
244 // If this buffer is not held by this client, or this client doesn't exist | 247 // If this buffer is not held by this client, or this client doesn't exist |
245 // in controller, do nothing. | 248 // in controller, do nothing. |
246 if (!client || !client->active_buffers.erase(buffer_id)) { | 249 std::map<int, scoped_refptr<media::VideoFrame> >::iterator iter; |
250 if (!client || (iter = client->active_buffers.find(buffer_id)) == | |
251 client->active_buffers.end()) { | |
247 NOTREACHED(); | 252 NOTREACHED(); |
248 return; | 253 return; |
249 } | 254 } |
255 scoped_refptr<media::VideoFrame> frame = iter->second; | |
256 client->active_buffers.erase(iter); | |
257 | |
258 if (frame->format() == media::VideoFrame::NATIVE_TEXTURE) | |
259 frame->mailbox_holder()->sync_point = sync_point; | |
250 | 260 |
251 buffer_pool_->RelinquishConsumerHold(buffer_id, 1); | 261 buffer_pool_->RelinquishConsumerHold(buffer_id, 1); |
252 } | 262 } |
253 | 263 |
254 const media::VideoCaptureFormat& | 264 const media::VideoCaptureFormat& |
255 VideoCaptureController::GetVideoCaptureFormat() const { | 265 VideoCaptureController::GetVideoCaptureFormat() const { |
256 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 266 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
257 return video_capture_format_; | 267 return video_capture_format_; |
258 } | 268 } |
259 | 269 |
260 scoped_refptr<media::VideoCaptureDevice::Client::Buffer> | 270 scoped_refptr<media::VideoCaptureDevice::Client::Buffer> |
261 VideoCaptureController::VideoCaptureDeviceClient::ReserveOutputBuffer( | 271 VideoCaptureController::VideoCaptureDeviceClient::ReserveOutputBuffer( |
262 media::VideoFrame::Format format, | 272 media::VideoFrame::Format format, |
263 const gfx::Size& size) { | 273 const gfx::Size& size) { |
264 return DoReserveOutputBuffer(format, size); | 274 return DoReserveOutputBuffer(format, size); |
265 } | 275 } |
266 | 276 |
267 void VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedFrame( | 277 void VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedFrame( |
268 const uint8* data, | 278 const uint8* data, |
269 int length, | 279 int length, |
270 base::TimeTicks timestamp, | 280 const VideoCaptureFormat& frame_format, |
271 int rotation, | 281 int rotation, |
272 const VideoCaptureFormat& frame_format) { | 282 base::TimeTicks timestamp) { |
273 TRACE_EVENT0("video", "VideoCaptureController::OnIncomingCapturedFrame"); | 283 TRACE_EVENT0("video", "VideoCaptureController::OnIncomingCapturedFrame"); |
274 | 284 |
275 if (!frame_format.IsValid()) | 285 if (!frame_format.IsValid()) |
276 return; | 286 return; |
277 | 287 |
278 // Chopped pixels in width/height in case video capture device has odd | 288 // Chopped pixels in width/height in case video capture device has odd |
279 // numbers for width/height. | 289 // numbers for width/height. |
280 int chopped_width = 0; | 290 int chopped_width = 0; |
281 int chopped_height = 0; | 291 int chopped_height = 0; |
282 int new_unrotated_width = frame_format.frame_size.width(); | 292 int new_unrotated_width = frame_format.frame_size.width(); |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
387 new_unrotated_width, | 397 new_unrotated_width, |
388 new_unrotated_height, | 398 new_unrotated_height, |
389 rotation_mode, | 399 rotation_mode, |
390 origin_colorspace); | 400 origin_colorspace); |
391 #else | 401 #else |
392 // Libyuv is not linked in for Android WebView builds, but video capture is | 402 // Libyuv is not linked in for Android WebView builds, but video capture is |
393 // not used in those builds either. Whenever libyuv is added in that build, | 403 // not used in those builds either. Whenever libyuv is added in that build, |
394 // address all these #ifdef parts, see http://crbug.com/299611 . | 404 // address all these #ifdef parts, see http://crbug.com/299611 . |
395 NOTREACHED(); | 405 NOTREACHED(); |
396 #endif // if !defined(AVOID_LIBYUV_FOR_ANDROID_WEBVIEW) | 406 #endif // if !defined(AVOID_LIBYUV_FOR_ANDROID_WEBVIEW) |
407 VideoCaptureFormat format( | |
408 dimensions, frame_format.frame_rate, media::PIXEL_FORMAT_I420); | |
409 scoped_refptr<media::VideoFrame> frame = | |
410 media::VideoFrame::WrapExternalPackedMemory( | |
411 media::VideoFrame::I420, | |
412 dimensions, | |
413 gfx::Rect(dimensions), | |
414 dimensions, | |
415 yplane, | |
416 media::VideoFrame::AllocationSize(media::VideoFrame::I420, | |
417 dimensions), | |
418 base::SharedMemory::NULLHandle(), | |
419 base::TimeDelta(), | |
420 base::Closure()); | |
421 DCHECK(frame); | |
397 BrowserThread::PostTask( | 422 BrowserThread::PostTask( |
398 BrowserThread::IO, | 423 BrowserThread::IO, |
399 FROM_HERE, | 424 FROM_HERE, |
400 base::Bind( | 425 base::Bind( |
401 &VideoCaptureController::DoIncomingCapturedI420BufferOnIOThread, | 426 &VideoCaptureController::DoIncomingCapturedVideoFrameOnIOThread, |
402 controller_, | 427 controller_, |
403 buffer, | 428 buffer, |
404 dimensions, | 429 format, |
405 frame_format.frame_rate, | 430 frame, |
406 timestamp)); | 431 timestamp)); |
407 } | 432 } |
408 | 433 |
409 void VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedBuffer( | 434 void |
435 VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedVideoFrame( | |
410 const scoped_refptr<Buffer>& buffer, | 436 const scoped_refptr<Buffer>& buffer, |
411 media::VideoFrame::Format format, | 437 const VideoCaptureFormat& buffer_format, |
412 const gfx::Size& dimensions, | 438 const scoped_refptr<media::VideoFrame>& frame, |
413 base::TimeTicks timestamp, | 439 base::TimeTicks timestamp) { |
414 int frame_rate) { | |
415 // The capture pipeline expects I420 for now. | |
416 DCHECK_EQ(format, media::VideoFrame::I420) | |
417 << "Non-I420 output buffer returned"; | |
418 | |
419 BrowserThread::PostTask( | 440 BrowserThread::PostTask( |
420 BrowserThread::IO, | 441 BrowserThread::IO, |
421 FROM_HERE, | 442 FROM_HERE, |
422 base::Bind( | 443 base::Bind( |
423 &VideoCaptureController::DoIncomingCapturedI420BufferOnIOThread, | 444 &VideoCaptureController::DoIncomingCapturedVideoFrameOnIOThread, |
mcasas
2014/01/21 14:34:02
I think the "unification" of VCC::VCDC::OnIncoming
| |
424 controller_, | 445 controller_, |
425 buffer, | 446 buffer, |
426 dimensions, | 447 buffer_format, |
427 frame_rate, | 448 frame, |
428 timestamp)); | 449 timestamp)); |
429 } | 450 } |
430 | 451 |
431 void VideoCaptureController::VideoCaptureDeviceClient::OnError() { | 452 void VideoCaptureController::VideoCaptureDeviceClient::OnError() { |
432 BrowserThread::PostTask(BrowserThread::IO, | 453 BrowserThread::PostTask(BrowserThread::IO, |
433 FROM_HERE, | 454 FROM_HERE, |
434 base::Bind(&VideoCaptureController::DoErrorOnIOThread, controller_)); | 455 base::Bind(&VideoCaptureController::DoErrorOnIOThread, controller_)); |
435 } | 456 } |
436 | 457 |
437 scoped_refptr<media::VideoCaptureDevice::Client::Buffer> | 458 scoped_refptr<media::VideoCaptureDevice::Client::Buffer> |
438 VideoCaptureController::VideoCaptureDeviceClient::DoReserveOutputBuffer( | 459 VideoCaptureController::VideoCaptureDeviceClient::DoReserveOutputBuffer( |
439 media::VideoFrame::Format format, | 460 media::VideoFrame::Format format, |
440 const gfx::Size& dimensions) { | 461 const gfx::Size& dimensions) { |
441 // The capture pipeline expects I420 for now. | 462 size_t frame_bytes = 0; |
442 DCHECK_EQ(format, media::VideoFrame::I420) | 463 if (format == media::VideoFrame::NATIVE_TEXTURE) { |
443 << "Non-I420 output buffer requested"; | 464 DCHECK_EQ(dimensions.width(), 0); |
465 DCHECK_EQ(dimensions.height(), 0); | |
466 } else { | |
467 // The capture pipeline expects I420 for now. | |
468 DCHECK_EQ(format, media::VideoFrame::I420) | |
469 << "Non-I420 output buffer format " << format << " requested"; | |
mcasas
2014/01/21 14:34:02
Being |format| numeric, not sure this DCHECK would
sheu
2014/01/29 01:19:20
Not very informative, but I think sufficient for a
| |
470 frame_bytes = media::VideoFrame::AllocationSize(format, dimensions); | |
471 } | |
444 | 472 |
445 int buffer_id_to_drop = VideoCaptureBufferPool::kInvalidId; | 473 int buffer_id_to_drop = VideoCaptureBufferPool::kInvalidId; |
446 const size_t frame_bytes = | |
447 media::VideoFrame::AllocationSize(format, dimensions); | |
448 | |
449 int buffer_id = | 474 int buffer_id = |
450 buffer_pool_->ReserveForProducer(frame_bytes, &buffer_id_to_drop); | 475 buffer_pool_->ReserveForProducer(frame_bytes, &buffer_id_to_drop); |
451 if (buffer_id == VideoCaptureBufferPool::kInvalidId) | 476 if (buffer_id == VideoCaptureBufferPool::kInvalidId) |
452 return NULL; | 477 return NULL; |
453 void* data; | 478 void* data; |
454 size_t size; | 479 size_t size; |
455 buffer_pool_->GetBufferInfo(buffer_id, &data, &size); | 480 buffer_pool_->GetBufferInfo(buffer_id, &data, &size); |
456 | 481 |
457 scoped_refptr<media::VideoCaptureDevice::Client::Buffer> output_buffer( | 482 scoped_refptr<media::VideoCaptureDevice::Client::Buffer> output_buffer( |
458 new PoolBuffer(buffer_pool_, buffer_id, data, size)); | 483 new PoolBuffer(buffer_pool_, buffer_id, data, size)); |
459 | 484 |
460 if (buffer_id_to_drop != VideoCaptureBufferPool::kInvalidId) { | 485 if (buffer_id_to_drop != VideoCaptureBufferPool::kInvalidId) { |
461 BrowserThread::PostTask(BrowserThread::IO, | 486 BrowserThread::PostTask(BrowserThread::IO, |
462 FROM_HERE, | 487 FROM_HERE, |
463 base::Bind(&VideoCaptureController::DoBufferDestroyedOnIOThread, | 488 base::Bind(&VideoCaptureController::DoBufferDestroyedOnIOThread, |
464 controller_, buffer_id_to_drop)); | 489 controller_, buffer_id_to_drop)); |
465 } | 490 } |
466 | 491 |
467 return output_buffer; | 492 return output_buffer; |
468 } | 493 } |
469 | 494 |
470 VideoCaptureController::~VideoCaptureController() { | 495 VideoCaptureController::~VideoCaptureController() { |
471 STLDeleteContainerPointers(controller_clients_.begin(), | 496 STLDeleteContainerPointers(controller_clients_.begin(), |
472 controller_clients_.end()); | 497 controller_clients_.end()); |
473 } | 498 } |
474 | 499 |
475 void VideoCaptureController::DoIncomingCapturedI420BufferOnIOThread( | 500 void VideoCaptureController::DoIncomingCapturedVideoFrameOnIOThread( |
476 scoped_refptr<media::VideoCaptureDevice::Client::Buffer> buffer, | 501 const scoped_refptr<media::VideoCaptureDevice::Client::Buffer>& buffer, |
477 const gfx::Size& dimensions, | 502 const media::VideoCaptureFormat& buffer_format, |
478 int frame_rate, | 503 const scoped_refptr<media::VideoFrame>& frame, |
479 base::TimeTicks timestamp) { | 504 base::TimeTicks timestamp) { |
480 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 505 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
481 DCHECK_NE(buffer->id(), VideoCaptureBufferPool::kInvalidId); | 506 DCHECK_NE(buffer->id(), VideoCaptureBufferPool::kInvalidId); |
482 | 507 |
483 VideoCaptureFormat frame_format( | |
484 dimensions, frame_rate, media::PIXEL_FORMAT_I420); | |
485 | |
486 int count = 0; | 508 int count = 0; |
487 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { | 509 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { |
488 for (ControllerClients::iterator client_it = controller_clients_.begin(); | 510 for (ControllerClients::iterator client_it = controller_clients_.begin(); |
489 client_it != controller_clients_.end(); ++client_it) { | 511 client_it != controller_clients_.end(); ++client_it) { |
490 ControllerClient* client = *client_it; | 512 ControllerClient* client = *client_it; |
491 if (client->session_closed) | 513 if (client->session_closed) |
492 continue; | 514 continue; |
493 | 515 |
494 bool is_new_buffer = client->known_buffers.insert(buffer->id()).second; | 516 if (frame->format() == media::VideoFrame::NATIVE_TEXTURE) { |
495 if (is_new_buffer) { | 517 client->event_handler->OnMailboxBufferReady(client->controller_id, |
496 // On the first use of a buffer on a client, share the memory handle. | 518 buffer->id(), |
497 size_t memory_size = 0; | 519 *frame->mailbox_holder(), |
498 base::SharedMemoryHandle remote_handle = buffer_pool_->ShareToProcess( | 520 buffer_format, |
499 buffer->id(), client->render_process_handle, &memory_size); | 521 timestamp); |
500 client->event_handler->OnBufferCreated( | 522 } else { |
501 client->controller_id, remote_handle, memory_size, buffer->id()); | 523 bool is_new_buffer = client->known_buffers.insert(buffer->id()).second; |
524 if (is_new_buffer) { | |
525 // On the first use of a buffer on a client, share the memory handle. | |
526 size_t memory_size = 0; | |
527 base::SharedMemoryHandle remote_handle = buffer_pool_->ShareToProcess( | |
528 buffer->id(), client->render_process_handle, &memory_size); | |
529 client->event_handler->OnBufferCreated( | |
530 client->controller_id, remote_handle, memory_size, buffer->id()); | |
531 } | |
532 | |
533 client->event_handler->OnBufferReady( | |
534 client->controller_id, buffer->id(), buffer_format, timestamp); | |
502 } | 535 } |
503 | 536 |
504 client->event_handler->OnBufferReady( | 537 bool inserted = |
505 client->controller_id, buffer->id(), timestamp, frame_format); | 538 client->active_buffers.insert(std::make_pair(buffer->id(), frame)) |
506 bool inserted = client->active_buffers.insert(buffer->id()).second; | 539 .second; |
507 DCHECK(inserted) << "Unexpected duplicate buffer: " << buffer->id(); | 540 DCHECK(inserted) << "Unexpected duplicate buffer: " << buffer->id(); |
508 count++; | 541 count++; |
509 } | 542 } |
510 } | 543 } |
511 | 544 |
512 buffer_pool_->HoldForConsumers(buffer->id(), count); | 545 buffer_pool_->HoldForConsumers(buffer->id(), count); |
513 } | 546 } |
514 | 547 |
515 void VideoCaptureController::DoErrorOnIOThread() { | 548 void VideoCaptureController::DoErrorOnIOThread() { |
516 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 549 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
570 } | 603 } |
571 return NULL; | 604 return NULL; |
572 } | 605 } |
573 | 606 |
574 int VideoCaptureController::GetClientCount() { | 607 int VideoCaptureController::GetClientCount() { |
575 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 608 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
576 return controller_clients_.size(); | 609 return controller_clients_.size(); |
577 } | 610 } |
578 | 611 |
579 } // namespace content | 612 } // namespace content |
OLD | NEW |