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

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

Issue 83793004: Implement IPCs and VideoCapture::Client interfaces for texture capture (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: e296ac98 Win32 bits. Created 6 years, 9 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
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
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 typedef std::map<int, scoped_refptr<media::VideoFrame> > ActiveBufferMap;
82 ActiveBufferMap active_buffers;
79 83
80 // State of capture session, controlled by VideoCaptureManager directly. This 84 // State of capture session, controlled by VideoCaptureManager directly. This
81 // transitions to true as soon as StopSession() occurs, at which point the 85 // 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 86 // client is sent an OnEnded() event. However, because the client retains a
83 // VideoCaptureController* pointer, its ControllerClient entry lives on until 87 // VideoCaptureController* pointer, its ControllerClient entry lives on until
84 // it unregisters itself via RemoveClient(), which may happen asynchronously. 88 // it unregisters itself via RemoveClient(), which may happen asynchronously.
85 // 89 //
86 // TODO(nick): If we changed the semantics of VideoCaptureHost so that 90 // TODO(nick): If we changed the semantics of VideoCaptureHost so that
87 // OnEnded() events were processed synchronously (with the RemoveClient() done 91 // OnEnded() events were processed synchronously (with the RemoveClient() done
88 // implicitly), we could avoid tracking this state here in the Controller, and 92 // implicitly), we could avoid tracking this state here in the Controller, and
(...skipping 14 matching lines...) Expand all
103 public: 107 public:
104 explicit VideoCaptureDeviceClient( 108 explicit VideoCaptureDeviceClient(
105 const base::WeakPtr<VideoCaptureController>& controller, 109 const base::WeakPtr<VideoCaptureController>& controller,
106 const scoped_refptr<VideoCaptureBufferPool>& buffer_pool); 110 const scoped_refptr<VideoCaptureBufferPool>& buffer_pool);
107 virtual ~VideoCaptureDeviceClient(); 111 virtual ~VideoCaptureDeviceClient();
108 112
109 // VideoCaptureDevice::Client implementation. 113 // VideoCaptureDevice::Client implementation.
110 virtual scoped_refptr<Buffer> ReserveOutputBuffer( 114 virtual scoped_refptr<Buffer> ReserveOutputBuffer(
111 media::VideoFrame::Format format, 115 media::VideoFrame::Format format,
112 const gfx::Size& size) OVERRIDE; 116 const gfx::Size& size) OVERRIDE;
113 virtual void OnIncomingCapturedFrame(const uint8* data, 117 virtual void OnIncomingCapturedData(const uint8* data,
114 int length, 118 int length,
115 base::TimeTicks timestamp, 119 const VideoCaptureFormat& frame_format,
116 int rotation, 120 int rotation,
117 const VideoCaptureFormat& frame_format) 121 base::TimeTicks timestamp) OVERRIDE;
118 OVERRIDE; 122 virtual void OnIncomingCapturedVideoFrame(
119 virtual void OnIncomingCapturedBuffer(const scoped_refptr<Buffer>& buffer, 123 const scoped_refptr<Buffer>& buffer,
120 media::VideoFrame::Format format, 124 const VideoCaptureFormat& buffer_format,
121 const gfx::Size& dimensions, 125 const scoped_refptr<media::VideoFrame>& frame,
122 base::TimeTicks timestamp, 126 base::TimeTicks timestamp) OVERRIDE;
123 int frame_rate) OVERRIDE;
124 virtual void OnError(const std::string& reason) OVERRIDE; 127 virtual void OnError(const std::string& reason) OVERRIDE;
125 128
126 private: 129 private:
127 scoped_refptr<Buffer> DoReserveOutputBuffer(media::VideoFrame::Format format, 130 scoped_refptr<Buffer> DoReserveOutputBuffer(media::VideoFrame::Format format,
128 const gfx::Size& dimensions); 131 const gfx::Size& dimensions);
129 132
130 // The controller to which we post events. 133 // The controller to which we post events.
131 const base::WeakPtr<VideoCaptureController> controller_; 134 const base::WeakPtr<VideoCaptureController> controller_;
132 135
133 // The pool of shared-memory buffers used for capturing. 136 // The pool of shared-memory buffers used for capturing.
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 const VideoCaptureControllerID& id, 202 const VideoCaptureControllerID& id,
200 VideoCaptureControllerEventHandler* event_handler) { 203 VideoCaptureControllerEventHandler* event_handler) {
201 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 204 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
202 DVLOG(1) << "VideoCaptureController::RemoveClient, id " << id.device_id; 205 DVLOG(1) << "VideoCaptureController::RemoveClient, id " << id.device_id;
203 206
204 ControllerClient* client = FindClient(id, event_handler, controller_clients_); 207 ControllerClient* client = FindClient(id, event_handler, controller_clients_);
205 if (!client) 208 if (!client)
206 return kInvalidMediaCaptureSessionId; 209 return kInvalidMediaCaptureSessionId;
207 210
208 // Take back all buffers held by the |client|. 211 // Take back all buffers held by the |client|.
209 for (std::set<int>::iterator buffer_it = client->active_buffers.begin(); 212 for (ControllerClient::ActiveBufferMap::iterator buffer_it =
213 client->active_buffers.begin();
210 buffer_it != client->active_buffers.end(); 214 buffer_it != client->active_buffers.end();
211 ++buffer_it) { 215 ++buffer_it) {
212 int buffer_id = *buffer_it; 216 buffer_pool_->RelinquishConsumerHold(buffer_it->first, 1);
213 buffer_pool_->RelinquishConsumerHold(buffer_id, 1);
214 } 217 }
215 client->active_buffers.clear(); 218 client->active_buffers.clear();
216 219
217 int session_id = client->session_id; 220 int session_id = client->session_id;
218 controller_clients_.remove(client); 221 controller_clients_.remove(client);
219 delete client; 222 delete client;
220 223
221 return session_id; 224 return session_id;
222 } 225 }
223 226
224 void VideoCaptureController::StopSession(int session_id) { 227 void VideoCaptureController::StopSession(int session_id) {
225 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 228 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
226 DVLOG(1) << "VideoCaptureController::StopSession, id " << session_id; 229 DVLOG(1) << "VideoCaptureController::StopSession, id " << session_id;
227 230
228 ControllerClient* client = FindClient(session_id, controller_clients_); 231 ControllerClient* client = FindClient(session_id, controller_clients_);
229 232
230 if (client) { 233 if (client) {
231 client->session_closed = true; 234 client->session_closed = true;
232 client->event_handler->OnEnded(client->controller_id); 235 client->event_handler->OnEnded(client->controller_id);
233 } 236 }
234 } 237 }
235 238
236 void VideoCaptureController::ReturnBuffer( 239 void VideoCaptureController::ReturnBuffer(
237 const VideoCaptureControllerID& id, 240 const VideoCaptureControllerID& id,
238 VideoCaptureControllerEventHandler* event_handler, 241 VideoCaptureControllerEventHandler* event_handler,
239 int buffer_id) { 242 int buffer_id,
243 uint32 sync_point) {
240 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 244 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
241 245
242 ControllerClient* client = FindClient(id, event_handler, controller_clients_); 246 ControllerClient* client = FindClient(id, event_handler, controller_clients_);
243 247
244 // If this buffer is not held by this client, or this client doesn't exist 248 // If this buffer is not held by this client, or this client doesn't exist
245 // in controller, do nothing. 249 // in controller, do nothing.
246 if (!client || !client->active_buffers.erase(buffer_id)) { 250 ControllerClient::ActiveBufferMap::iterator iter;
251 if (!client || (iter = client->active_buffers.find(buffer_id)) ==
252 client->active_buffers.end()) {
247 NOTREACHED(); 253 NOTREACHED();
248 return; 254 return;
249 } 255 }
256 scoped_refptr<media::VideoFrame> frame = iter->second;
257 client->active_buffers.erase(iter);
258
259 if (frame->format() == media::VideoFrame::NATIVE_TEXTURE)
260 frame->mailbox_holder()->sync_point = sync_point;
250 261
251 buffer_pool_->RelinquishConsumerHold(buffer_id, 1); 262 buffer_pool_->RelinquishConsumerHold(buffer_id, 1);
252 } 263 }
253 264
254 const media::VideoCaptureFormat& 265 const media::VideoCaptureFormat&
255 VideoCaptureController::GetVideoCaptureFormat() const { 266 VideoCaptureController::GetVideoCaptureFormat() const {
256 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 267 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
257 return video_capture_format_; 268 return video_capture_format_;
258 } 269 }
259 270
260 scoped_refptr<media::VideoCaptureDevice::Client::Buffer> 271 scoped_refptr<media::VideoCaptureDevice::Client::Buffer>
261 VideoCaptureController::VideoCaptureDeviceClient::ReserveOutputBuffer( 272 VideoCaptureController::VideoCaptureDeviceClient::ReserveOutputBuffer(
262 media::VideoFrame::Format format, 273 media::VideoFrame::Format format,
263 const gfx::Size& size) { 274 const gfx::Size& size) {
264 return DoReserveOutputBuffer(format, size); 275 return DoReserveOutputBuffer(format, size);
265 } 276 }
266 277
267 void VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedFrame( 278 void VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedData(
268 const uint8* data, 279 const uint8* data,
269 int length, 280 int length,
270 base::TimeTicks timestamp, 281 const VideoCaptureFormat& frame_format,
271 int rotation, 282 int rotation,
272 const VideoCaptureFormat& frame_format) { 283 base::TimeTicks timestamp) {
273 TRACE_EVENT0("video", "VideoCaptureController::OnIncomingCapturedFrame"); 284 TRACE_EVENT0("video", "VideoCaptureController::OnIncomingCapturedData");
274 285
275 if (!frame_format.IsValid()) 286 if (!frame_format.IsValid())
276 return; 287 return;
277 288
278 // Chopped pixels in width/height in case video capture device has odd 289 // Chopped pixels in width/height in case video capture device has odd
279 // numbers for width/height. 290 // numbers for width/height.
280 int chopped_width = 0; 291 int chopped_width = 0;
281 int chopped_height = 0; 292 int chopped_height = 0;
282 int new_unrotated_width = frame_format.frame_size.width(); 293 int new_unrotated_width = frame_format.frame_size.width();
283 int new_unrotated_height = frame_format.frame_size.height(); 294 int new_unrotated_height = frame_format.frame_size.height();
(...skipping 12 matching lines...) Expand all
296 if (rotation == 90 || rotation == 270) { 307 if (rotation == 90 || rotation == 270) {
297 destination_width = new_unrotated_height; 308 destination_width = new_unrotated_height;
298 destination_height = new_unrotated_width; 309 destination_height = new_unrotated_width;
299 } 310 }
300 const gfx::Size dimensions(destination_width, destination_height); 311 const gfx::Size dimensions(destination_width, destination_height);
301 scoped_refptr<Buffer> buffer = 312 scoped_refptr<Buffer> buffer =
302 DoReserveOutputBuffer(media::VideoFrame::I420, dimensions); 313 DoReserveOutputBuffer(media::VideoFrame::I420, dimensions);
303 314
304 if (!buffer) 315 if (!buffer)
305 return; 316 return;
317 uint8* yplane = NULL;
306 #if !defined(AVOID_LIBYUV_FOR_ANDROID_WEBVIEW) 318 #if !defined(AVOID_LIBYUV_FOR_ANDROID_WEBVIEW)
307 bool flip = false; 319 bool flip = false;
308 uint8* yplane = reinterpret_cast<uint8*>(buffer->data()); 320 yplane = reinterpret_cast<uint8*>(buffer->data());
309 uint8* uplane = 321 uint8* uplane =
310 yplane + 322 yplane +
311 media::VideoFrame::PlaneAllocationSize( 323 media::VideoFrame::PlaneAllocationSize(
312 media::VideoFrame::I420, media::VideoFrame::kYPlane, dimensions); 324 media::VideoFrame::I420, media::VideoFrame::kYPlane, dimensions);
313 uint8* vplane = 325 uint8* vplane =
314 uplane + 326 uplane +
315 media::VideoFrame::PlaneAllocationSize( 327 media::VideoFrame::PlaneAllocationSize(
316 media::VideoFrame::I420, media::VideoFrame::kUPlane, dimensions); 328 media::VideoFrame::I420, media::VideoFrame::kUPlane, dimensions);
317 int yplane_stride = dimensions.width(); 329 int yplane_stride = dimensions.width();
318 int uv_plane_stride = yplane_stride / 2; 330 int uv_plane_stride = yplane_stride / 2;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 new_unrotated_width, 399 new_unrotated_width,
388 new_unrotated_height, 400 new_unrotated_height,
389 rotation_mode, 401 rotation_mode,
390 origin_colorspace); 402 origin_colorspace);
391 #else 403 #else
392 // Libyuv is not linked in for Android WebView builds, but video capture is 404 // 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, 405 // not used in those builds either. Whenever libyuv is added in that build,
394 // address all these #ifdef parts, see http://crbug.com/299611 . 406 // address all these #ifdef parts, see http://crbug.com/299611 .
395 NOTREACHED(); 407 NOTREACHED();
396 #endif // if !defined(AVOID_LIBYUV_FOR_ANDROID_WEBVIEW) 408 #endif // if !defined(AVOID_LIBYUV_FOR_ANDROID_WEBVIEW)
409 VideoCaptureFormat format(
410 dimensions, frame_format.frame_rate, media::PIXEL_FORMAT_I420);
411 scoped_refptr<media::VideoFrame> frame =
412 media::VideoFrame::WrapExternalPackedMemory(
413 media::VideoFrame::I420,
414 dimensions,
415 gfx::Rect(dimensions),
416 dimensions,
417 yplane,
418 media::VideoFrame::AllocationSize(media::VideoFrame::I420,
419 dimensions),
420 base::SharedMemory::NULLHandle(),
421 base::TimeDelta(),
422 base::Closure());
423 DCHECK(frame);
397 BrowserThread::PostTask( 424 BrowserThread::PostTask(
398 BrowserThread::IO, 425 BrowserThread::IO,
399 FROM_HERE, 426 FROM_HERE,
400 base::Bind( 427 base::Bind(
401 &VideoCaptureController::DoIncomingCapturedI420BufferOnIOThread, 428 &VideoCaptureController::DoIncomingCapturedVideoFrameOnIOThread,
402 controller_, 429 controller_,
403 buffer, 430 buffer,
404 dimensions, 431 format,
405 frame_format.frame_rate, 432 frame,
406 timestamp)); 433 timestamp));
407 } 434 }
408 435
409 void VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedBuffer( 436 void
437 VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedVideoFrame(
410 const scoped_refptr<Buffer>& buffer, 438 const scoped_refptr<Buffer>& buffer,
411 media::VideoFrame::Format format, 439 const VideoCaptureFormat& buffer_format,
412 const gfx::Size& dimensions, 440 const scoped_refptr<media::VideoFrame>& frame,
413 base::TimeTicks timestamp, 441 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( 442 BrowserThread::PostTask(
420 BrowserThread::IO, 443 BrowserThread::IO,
421 FROM_HERE, 444 FROM_HERE,
422 base::Bind( 445 base::Bind(
423 &VideoCaptureController::DoIncomingCapturedI420BufferOnIOThread, 446 &VideoCaptureController::DoIncomingCapturedVideoFrameOnIOThread,
424 controller_, 447 controller_,
425 buffer, 448 buffer,
426 dimensions, 449 buffer_format,
427 frame_rate, 450 frame,
428 timestamp)); 451 timestamp));
429 } 452 }
430 453
431 void VideoCaptureController::VideoCaptureDeviceClient::OnError( 454 void VideoCaptureController::VideoCaptureDeviceClient::OnError(
432 const std::string& reason) { 455 const std::string& reason) {
433 MediaStreamManager::SendMessageToNativeLog( 456 MediaStreamManager::SendMessageToNativeLog(
434 "Error on video capture: " + reason); 457 "Error on video capture: " + reason);
435 BrowserThread::PostTask(BrowserThread::IO, 458 BrowserThread::PostTask(BrowserThread::IO,
436 FROM_HERE, 459 FROM_HERE,
437 base::Bind(&VideoCaptureController::DoErrorOnIOThread, controller_)); 460 base::Bind(&VideoCaptureController::DoErrorOnIOThread, controller_));
438 } 461 }
439 462
440 scoped_refptr<media::VideoCaptureDevice::Client::Buffer> 463 scoped_refptr<media::VideoCaptureDevice::Client::Buffer>
441 VideoCaptureController::VideoCaptureDeviceClient::DoReserveOutputBuffer( 464 VideoCaptureController::VideoCaptureDeviceClient::DoReserveOutputBuffer(
442 media::VideoFrame::Format format, 465 media::VideoFrame::Format format,
443 const gfx::Size& dimensions) { 466 const gfx::Size& dimensions) {
444 // The capture pipeline expects I420 for now. 467 size_t frame_bytes = 0;
445 DCHECK_EQ(format, media::VideoFrame::I420) 468 if (format == media::VideoFrame::NATIVE_TEXTURE) {
446 << "Non-I420 output buffer requested"; 469 DCHECK_EQ(dimensions.width(), 0);
470 DCHECK_EQ(dimensions.height(), 0);
471 } else {
472 // The capture pipeline expects I420 for now.
473 DCHECK_EQ(format, media::VideoFrame::I420)
474 << "Non-I420 output buffer format " << format << " requested";
475 frame_bytes = media::VideoFrame::AllocationSize(format, dimensions);
476 }
447 477
448 int buffer_id_to_drop = VideoCaptureBufferPool::kInvalidId; 478 int buffer_id_to_drop = VideoCaptureBufferPool::kInvalidId;
449 const size_t frame_bytes =
450 media::VideoFrame::AllocationSize(format, dimensions);
451
452 int buffer_id = 479 int buffer_id =
453 buffer_pool_->ReserveForProducer(frame_bytes, &buffer_id_to_drop); 480 buffer_pool_->ReserveForProducer(frame_bytes, &buffer_id_to_drop);
454 if (buffer_id == VideoCaptureBufferPool::kInvalidId) 481 if (buffer_id == VideoCaptureBufferPool::kInvalidId)
455 return NULL; 482 return NULL;
456 void* data; 483 void* data;
457 size_t size; 484 size_t size;
458 buffer_pool_->GetBufferInfo(buffer_id, &data, &size); 485 buffer_pool_->GetBufferInfo(buffer_id, &data, &size);
459 486
460 scoped_refptr<media::VideoCaptureDevice::Client::Buffer> output_buffer( 487 scoped_refptr<media::VideoCaptureDevice::Client::Buffer> output_buffer(
461 new PoolBuffer(buffer_pool_, buffer_id, data, size)); 488 new PoolBuffer(buffer_pool_, buffer_id, data, size));
462 489
463 if (buffer_id_to_drop != VideoCaptureBufferPool::kInvalidId) { 490 if (buffer_id_to_drop != VideoCaptureBufferPool::kInvalidId) {
464 BrowserThread::PostTask(BrowserThread::IO, 491 BrowserThread::PostTask(BrowserThread::IO,
465 FROM_HERE, 492 FROM_HERE,
466 base::Bind(&VideoCaptureController::DoBufferDestroyedOnIOThread, 493 base::Bind(&VideoCaptureController::DoBufferDestroyedOnIOThread,
467 controller_, buffer_id_to_drop)); 494 controller_, buffer_id_to_drop));
468 } 495 }
469 496
470 return output_buffer; 497 return output_buffer;
471 } 498 }
472 499
473 VideoCaptureController::~VideoCaptureController() { 500 VideoCaptureController::~VideoCaptureController() {
474 STLDeleteContainerPointers(controller_clients_.begin(), 501 STLDeleteContainerPointers(controller_clients_.begin(),
475 controller_clients_.end()); 502 controller_clients_.end());
476 } 503 }
477 504
478 void VideoCaptureController::DoIncomingCapturedI420BufferOnIOThread( 505 void VideoCaptureController::DoIncomingCapturedVideoFrameOnIOThread(
479 scoped_refptr<media::VideoCaptureDevice::Client::Buffer> buffer, 506 const scoped_refptr<media::VideoCaptureDevice::Client::Buffer>& buffer,
480 const gfx::Size& dimensions, 507 const media::VideoCaptureFormat& buffer_format,
481 int frame_rate, 508 const scoped_refptr<media::VideoFrame>& frame,
482 base::TimeTicks timestamp) { 509 base::TimeTicks timestamp) {
483 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 510 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
484 DCHECK_NE(buffer->id(), VideoCaptureBufferPool::kInvalidId); 511 DCHECK_NE(buffer->id(), VideoCaptureBufferPool::kInvalidId);
485 512
486 VideoCaptureFormat frame_format(
487 dimensions, frame_rate, media::PIXEL_FORMAT_I420);
488
489 int count = 0; 513 int count = 0;
490 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { 514 if (state_ == VIDEO_CAPTURE_STATE_STARTED) {
491 for (ControllerClients::iterator client_it = controller_clients_.begin(); 515 for (ControllerClients::iterator client_it = controller_clients_.begin();
492 client_it != controller_clients_.end(); ++client_it) { 516 client_it != controller_clients_.end(); ++client_it) {
493 ControllerClient* client = *client_it; 517 ControllerClient* client = *client_it;
494 if (client->session_closed) 518 if (client->session_closed)
495 continue; 519 continue;
496 520
497 bool is_new_buffer = client->known_buffers.insert(buffer->id()).second; 521 if (frame->format() == media::VideoFrame::NATIVE_TEXTURE) {
498 if (is_new_buffer) { 522 client->event_handler->OnMailboxBufferReady(client->controller_id,
499 // On the first use of a buffer on a client, share the memory handle. 523 buffer->id(),
500 size_t memory_size = 0; 524 *frame->mailbox_holder(),
501 base::SharedMemoryHandle remote_handle = buffer_pool_->ShareToProcess( 525 buffer_format,
502 buffer->id(), client->render_process_handle, &memory_size); 526 timestamp);
503 client->event_handler->OnBufferCreated( 527 } else {
504 client->controller_id, remote_handle, memory_size, buffer->id()); 528 bool is_new_buffer = client->known_buffers.insert(buffer->id()).second;
529 if (is_new_buffer) {
530 // On the first use of a buffer on a client, share the memory handle.
531 size_t memory_size = 0;
532 base::SharedMemoryHandle remote_handle = buffer_pool_->ShareToProcess(
533 buffer->id(), client->render_process_handle, &memory_size);
534 client->event_handler->OnBufferCreated(
535 client->controller_id, remote_handle, memory_size, buffer->id());
536 }
537
538 client->event_handler->OnBufferReady(
539 client->controller_id, buffer->id(), buffer_format, timestamp);
505 } 540 }
506 541
507 client->event_handler->OnBufferReady( 542 bool inserted =
508 client->controller_id, buffer->id(), timestamp, frame_format); 543 client->active_buffers.insert(std::make_pair(buffer->id(), frame))
509 bool inserted = client->active_buffers.insert(buffer->id()).second; 544 .second;
510 DCHECK(inserted) << "Unexpected duplicate buffer: " << buffer->id(); 545 DCHECK(inserted) << "Unexpected duplicate buffer: " << buffer->id();
511 count++; 546 count++;
512 } 547 }
513 } 548 }
514 549
515 buffer_pool_->HoldForConsumers(buffer->id(), count); 550 buffer_pool_->HoldForConsumers(buffer->id(), count);
516 } 551 }
517 552
518 void VideoCaptureController::DoErrorOnIOThread() { 553 void VideoCaptureController::DoErrorOnIOThread() {
519 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 554 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 } 608 }
574 return NULL; 609 return NULL;
575 } 610 }
576 611
577 int VideoCaptureController::GetClientCount() { 612 int VideoCaptureController::GetClientCount() {
578 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 613 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
579 return controller_clients_.size(); 614 return controller_clients_.size();
580 } 615 }
581 616
582 } // namespace content 617 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698