Chromium Code Reviews| 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 // Notes about usage of this object by VideoCaptureImplManager. | 5 // Notes about usage of this object by VideoCaptureImplManager. |
| 6 // | 6 // |
| 7 // VideoCaptureImplManager access this object by using a Unretained() | 7 // VideoCaptureImplManager access this object by using a Unretained() |
| 8 // binding and tasks on the IO thread. It is then important that | 8 // binding and tasks on the IO thread. It is then important that |
| 9 // VideoCaptureImpl never post task to itself. All operations must be | 9 // VideoCaptureImpl never post task to itself. All operations must be |
| 10 // synchronous. | 10 // synchronous. |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 24 namespace content { | 24 namespace content { |
| 25 | 25 |
| 26 namespace { | 26 namespace { |
| 27 | 27 |
| 28 // This is called on an unknown thread when the VideoFrame destructor executes. | 28 // This is called on an unknown thread when the VideoFrame destructor executes. |
| 29 // As of this writing, this callback mechanism is the only interface in | 29 // As of this writing, this callback mechanism is the only interface in |
| 30 // VideoFrame to provide the final value for |release_sync_point|. | 30 // VideoFrame to provide the final value for |release_sync_point|. |
| 31 // VideoCaptureImpl::DidFinishConsumingFrame() will read the value saved here, | 31 // VideoCaptureImpl::DidFinishConsumingFrame() will read the value saved here, |
| 32 // and pass it back to the IO thread to pass back to the host via the | 32 // and pass it back to the IO thread to pass back to the host via the |
| 33 // BufferReady IPC. | 33 // BufferReady IPC. |
| 34 void SaveReleaseSyncPoint(uint32* storage, uint32 release_sync_point) { | 34 void SaveReleaseSyncPoint(uint32* sync_point_storage, |
| 35 *storage = release_sync_point; | 35 gpu::SyncToken* sync_token_storage, |
| 36 uint32 release_sync_point, | |
| 37 const gpu::SyncToken& release_sync_token) { | |
| 38 *sync_point_storage = release_sync_point; | |
| 39 *sync_token_storage = release_sync_token; | |
| 36 } | 40 } |
| 37 | 41 |
| 38 } // namespace | 42 } // namespace |
| 39 | 43 |
| 40 // A holder of a memory-backed buffer and accessors to it. | 44 // A holder of a memory-backed buffer and accessors to it. |
| 41 class VideoCaptureImpl::ClientBuffer | 45 class VideoCaptureImpl::ClientBuffer |
| 42 : public base::RefCountedThreadSafe<ClientBuffer> { | 46 : public base::RefCountedThreadSafe<ClientBuffer> { |
| 43 public: | 47 public: |
| 44 ClientBuffer(scoped_ptr<base::SharedMemory> buffer, size_t buffer_size) | 48 ClientBuffer(scoped_ptr<base::SharedMemory> buffer, size_t buffer_size) |
| 45 : buffer_(buffer.Pass()), buffer_size_(buffer_size) {} | 49 : buffer_(buffer.Pass()), buffer_size_(buffer_size) {} |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 307 int buffer_id, | 311 int buffer_id, |
| 308 base::TimeTicks timestamp, | 312 base::TimeTicks timestamp, |
| 309 const base::DictionaryValue& metadata, | 313 const base::DictionaryValue& metadata, |
| 310 media::VideoPixelFormat pixel_format, | 314 media::VideoPixelFormat pixel_format, |
| 311 media::VideoFrame::StorageType storage_type, | 315 media::VideoFrame::StorageType storage_type, |
| 312 const gfx::Size& coded_size, | 316 const gfx::Size& coded_size, |
| 313 const gfx::Rect& visible_rect, | 317 const gfx::Rect& visible_rect, |
| 314 const std::vector<gpu::MailboxHolder>& mailbox_holders) { | 318 const std::vector<gpu::MailboxHolder>& mailbox_holders) { |
| 315 DCHECK(io_task_runner_->BelongsToCurrentThread()); | 319 DCHECK(io_task_runner_->BelongsToCurrentThread()); |
| 316 if (state_ != VIDEO_CAPTURE_STATE_STARTED || suspended_) { | 320 if (state_ != VIDEO_CAPTURE_STATE_STARTED || suspended_) { |
| 317 Send(new VideoCaptureHostMsg_BufferReady(device_id_, buffer_id, 0, -1.0)); | 321 Send(new VideoCaptureHostMsg_BufferReady(device_id_, buffer_id, 0, |
| 322 gpu::SyncToken(), -1.0)); | |
| 318 return; | 323 return; |
| 319 } | 324 } |
| 320 if (first_frame_timestamp_.is_null()) | 325 if (first_frame_timestamp_.is_null()) |
| 321 first_frame_timestamp_ = timestamp; | 326 first_frame_timestamp_ = timestamp; |
| 322 | 327 |
| 323 // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc | 328 // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc |
| 324 TRACE_EVENT_INSTANT2("cast_perf_test", "OnBufferReceived", | 329 TRACE_EVENT_INSTANT2("cast_perf_test", "OnBufferReceived", |
| 325 TRACE_EVENT_SCOPE_THREAD, "timestamp", | 330 TRACE_EVENT_SCOPE_THREAD, "timestamp", |
| 326 timestamp.ToInternalValue(), "time_delta", | 331 timestamp.ToInternalValue(), "time_delta", |
| 327 (timestamp - first_frame_timestamp_).ToInternalValue()); | 332 (timestamp - first_frame_timestamp_).ToInternalValue()); |
| 328 | 333 |
| 329 scoped_refptr<media::VideoFrame> frame; | 334 scoped_refptr<media::VideoFrame> frame; |
| 330 base::Callback<void(uint32, double)> buffer_finished_callback; | 335 BufferFinishedCB buffer_finished_callback; |
| 331 uint32* release_sync_point_storage = new uint32(0); | 336 uint32* release_sync_point_storage = new uint32(0); |
| 337 gpu::SyncToken* release_sync_token_storage = new gpu::SyncToken; | |
|
dcheng
2015/10/27 19:09:28
It doesn't have to be this CL, but can we make own
David Yen
2015/10/28 22:03:43
I will create a follow up CL for this.
| |
| 332 if (mailbox_holders.empty()) { | 338 if (mailbox_holders.empty()) { |
| 333 DCHECK_EQ(media::PIXEL_FORMAT_I420, pixel_format); | 339 DCHECK_EQ(media::PIXEL_FORMAT_I420, pixel_format); |
| 334 const auto& iter = client_buffers_.find(buffer_id); | 340 const auto& iter = client_buffers_.find(buffer_id); |
| 335 DCHECK(iter != client_buffers_.end()); | 341 DCHECK(iter != client_buffers_.end()); |
| 336 const scoped_refptr<ClientBuffer> buffer = iter->second; | 342 const scoped_refptr<ClientBuffer> buffer = iter->second; |
| 337 frame = media::VideoFrame::WrapExternalSharedMemory( | 343 frame = media::VideoFrame::WrapExternalSharedMemory( |
| 338 pixel_format, | 344 pixel_format, |
| 339 coded_size, | 345 coded_size, |
| 340 visible_rect, | 346 visible_rect, |
| 341 gfx::Size(visible_rect.width(), visible_rect.height()), | 347 gfx::Size(visible_rect.width(), visible_rect.height()), |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 352 for (const auto& mailbox_holder : mailbox_holders) | 358 for (const auto& mailbox_holder : mailbox_holders) |
| 353 DCHECK(mailbox_holder.mailbox.Verify()); | 359 DCHECK(mailbox_holder.mailbox.Verify()); |
| 354 DCHECK(mailbox_holders.size() == 1u || mailbox_holders.size() == 3u); | 360 DCHECK(mailbox_holders.size() == 1u || mailbox_holders.size() == 3u); |
| 355 #endif | 361 #endif |
| 356 | 362 |
| 357 scoped_refptr<ClientBuffer2> buffer; | 363 scoped_refptr<ClientBuffer2> buffer; |
| 358 if (mailbox_holders.size() == | 364 if (mailbox_holders.size() == |
| 359 media::VideoFrame::NumPlanes(media::PIXEL_FORMAT_ARGB)) { | 365 media::VideoFrame::NumPlanes(media::PIXEL_FORMAT_ARGB)) { |
| 360 DCHECK_EQ(media::PIXEL_FORMAT_ARGB, pixel_format); | 366 DCHECK_EQ(media::PIXEL_FORMAT_ARGB, pixel_format); |
| 361 frame = media::VideoFrame::WrapNativeTexture( | 367 frame = media::VideoFrame::WrapNativeTexture( |
| 362 pixel_format, | 368 pixel_format, mailbox_holders[0], |
| 363 mailbox_holders[0], | 369 base::Bind(&SaveReleaseSyncPoint, release_sync_point_storage, |
| 364 base::Bind(&SaveReleaseSyncPoint, release_sync_point_storage), | 370 release_sync_token_storage), |
| 365 coded_size, | 371 coded_size, gfx::Rect(coded_size), coded_size, |
| 366 gfx::Rect(coded_size), | |
| 367 coded_size, | |
| 368 timestamp - first_frame_timestamp_); | 372 timestamp - first_frame_timestamp_); |
| 369 } else if (mailbox_holders.size() == | 373 } else if (mailbox_holders.size() == |
| 370 media::VideoFrame::NumPlanes(media::PIXEL_FORMAT_I420)) { | 374 media::VideoFrame::NumPlanes(media::PIXEL_FORMAT_I420)) { |
| 371 DCHECK_EQ(media::PIXEL_FORMAT_I420, pixel_format); | 375 DCHECK_EQ(media::PIXEL_FORMAT_I420, pixel_format); |
| 372 const auto& iter = client_buffer2s_.find(buffer_id); | 376 const auto& iter = client_buffer2s_.find(buffer_id); |
| 373 DCHECK(iter != client_buffer2s_.end()); | 377 DCHECK(iter != client_buffer2s_.end()); |
| 374 buffer = iter->second; | 378 buffer = iter->second; |
| 375 frame = media::VideoFrame::WrapYUV420NativeTextures( | 379 frame = media::VideoFrame::WrapYUV420NativeTextures( |
| 376 mailbox_holders[media::VideoFrame::kYPlane], | 380 mailbox_holders[media::VideoFrame::kYPlane], |
| 377 mailbox_holders[media::VideoFrame::kUPlane], | 381 mailbox_holders[media::VideoFrame::kUPlane], |
| 378 mailbox_holders[media::VideoFrame::kVPlane], | 382 mailbox_holders[media::VideoFrame::kVPlane], |
| 379 base::Bind(&SaveReleaseSyncPoint, release_sync_point_storage), | 383 base::Bind(&SaveReleaseSyncPoint, release_sync_point_storage, |
| 380 coded_size, | 384 release_sync_token_storage), |
| 381 gfx::Rect(coded_size), | 385 coded_size, gfx::Rect(coded_size), coded_size, |
| 382 coded_size, | |
| 383 timestamp - first_frame_timestamp_); | 386 timestamp - first_frame_timestamp_); |
| 384 } | 387 } |
| 385 buffer_finished_callback = media::BindToCurrentLoop( | 388 buffer_finished_callback = media::BindToCurrentLoop( |
| 386 base::Bind(&VideoCaptureImpl::OnClientBufferFinished2, | 389 base::Bind(&VideoCaptureImpl::OnClientBufferFinished2, |
| 387 weak_factory_.GetWeakPtr(), buffer_id, buffer)); | 390 weak_factory_.GetWeakPtr(), buffer_id, buffer)); |
| 388 } | 391 } |
| 389 frame->metadata()->SetTimeTicks(media::VideoFrameMetadata::REFERENCE_TIME, | 392 frame->metadata()->SetTimeTicks(media::VideoFrameMetadata::REFERENCE_TIME, |
| 390 timestamp); | 393 timestamp); |
| 391 frame->AddDestructionObserver( | 394 frame->AddDestructionObserver( |
| 392 base::Bind(&VideoCaptureImpl::DidFinishConsumingFrame, frame->metadata(), | 395 base::Bind(&VideoCaptureImpl::DidFinishConsumingFrame, frame->metadata(), |
| 393 release_sync_point_storage, buffer_finished_callback)); | 396 release_sync_point_storage, release_sync_token_storage, |
| 397 buffer_finished_callback)); | |
| 394 | 398 |
| 395 frame->metadata()->MergeInternalValuesFrom(metadata); | 399 frame->metadata()->MergeInternalValuesFrom(metadata); |
| 396 | 400 |
| 397 for (const auto& client : clients_) | 401 for (const auto& client : clients_) |
| 398 client.second.deliver_frame_cb.Run(frame, timestamp); | 402 client.second.deliver_frame_cb.Run(frame, timestamp); |
| 399 } | 403 } |
| 400 | 404 |
| 401 void VideoCaptureImpl::OnClientBufferFinished( | 405 void VideoCaptureImpl::OnClientBufferFinished( |
| 402 int buffer_id, | 406 int buffer_id, |
| 403 const scoped_refptr<ClientBuffer>& /* ignored_buffer */, | 407 const scoped_refptr<ClientBuffer>& /* ignored_buffer */, |
| 404 uint32 release_sync_point, | 408 uint32 release_sync_point, |
| 409 const gpu::SyncToken& release_sync_token, | |
| 405 double consumer_resource_utilization) { | 410 double consumer_resource_utilization) { |
| 406 DCHECK(io_task_runner_->BelongsToCurrentThread()); | 411 DCHECK(io_task_runner_->BelongsToCurrentThread()); |
| 407 Send(new VideoCaptureHostMsg_BufferReady(device_id_, buffer_id, | 412 Send(new VideoCaptureHostMsg_BufferReady( |
| 408 release_sync_point, | 413 device_id_, buffer_id, release_sync_point, release_sync_token, |
| 409 consumer_resource_utilization)); | 414 consumer_resource_utilization)); |
| 410 } | 415 } |
| 411 void VideoCaptureImpl::OnClientBufferFinished2( | 416 void VideoCaptureImpl::OnClientBufferFinished2( |
| 412 int buffer_id, | 417 int buffer_id, |
| 413 const scoped_refptr<ClientBuffer2>& gpu_memory_buffer /* ignored_buffer */, | 418 const scoped_refptr<ClientBuffer2>& gpu_memory_buffer /* ignored_buffer */, |
| 414 uint32 release_sync_point, | 419 uint32 release_sync_point, |
| 420 const gpu::SyncToken& release_sync_token, | |
| 415 double consumer_resource_utilization) { | 421 double consumer_resource_utilization) { |
| 416 OnClientBufferFinished(buffer_id, scoped_refptr<ClientBuffer>(), | 422 OnClientBufferFinished(buffer_id, scoped_refptr<ClientBuffer>(), |
| 417 release_sync_point, consumer_resource_utilization); | 423 release_sync_point, release_sync_token, |
| 424 consumer_resource_utilization); | |
| 418 } | 425 } |
| 419 | 426 |
| 420 void VideoCaptureImpl::OnStateChanged(VideoCaptureState state) { | 427 void VideoCaptureImpl::OnStateChanged(VideoCaptureState state) { |
| 421 DCHECK(io_task_runner_->BelongsToCurrentThread()); | 428 DCHECK(io_task_runner_->BelongsToCurrentThread()); |
| 422 | 429 |
| 423 switch (state) { | 430 switch (state) { |
| 424 case VIDEO_CAPTURE_STATE_STARTED: | 431 case VIDEO_CAPTURE_STATE_STARTED: |
| 425 // Camera has started in the browser process. Since we have already | 432 // Camera has started in the browser process. Since we have already |
| 426 // told all clients that we have started there's nothing to do. | 433 // told all clients that we have started there's nothing to do. |
| 427 break; | 434 break; |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 544 clients->erase(it); | 551 clients->erase(it); |
| 545 found = true; | 552 found = true; |
| 546 } | 553 } |
| 547 return found; | 554 return found; |
| 548 } | 555 } |
| 549 | 556 |
| 550 // static | 557 // static |
| 551 void VideoCaptureImpl::DidFinishConsumingFrame( | 558 void VideoCaptureImpl::DidFinishConsumingFrame( |
| 552 const media::VideoFrameMetadata* metadata, | 559 const media::VideoFrameMetadata* metadata, |
| 553 uint32* release_sync_point_storage, | 560 uint32* release_sync_point_storage, |
| 554 const base::Callback<void(uint32, double)>& callback_to_io_thread) { | 561 gpu::SyncToken* release_sync_token_storage, |
| 562 const BufferFinishedCB& callback_to_io_thread) { | |
| 555 // Note: This function may be called on any thread by the VideoFrame | 563 // Note: This function may be called on any thread by the VideoFrame |
| 556 // destructor. |metadata| is still valid for read-access at this point. | 564 // destructor. |metadata| is still valid for read-access at this point. |
| 557 | 565 |
| 558 uint32 release_sync_point = 0u; | 566 uint32 release_sync_point = 0u; |
| 559 if (release_sync_point_storage) { | 567 if (release_sync_point_storage) { |
| 560 release_sync_point = *release_sync_point_storage; | 568 release_sync_point = *release_sync_point_storage; |
| 561 delete release_sync_point_storage; | 569 delete release_sync_point_storage; |
| 562 } | 570 } |
| 563 | 571 |
| 572 gpu::SyncToken release_sync_token; | |
| 573 if (release_sync_token_storage) { | |
| 574 release_sync_token = *release_sync_token_storage; | |
| 575 delete release_sync_token_storage; | |
| 576 } | |
| 577 | |
| 564 double consumer_resource_utilization = -1.0; | 578 double consumer_resource_utilization = -1.0; |
| 565 if (!metadata->GetDouble(media::VideoFrameMetadata::RESOURCE_UTILIZATION, | 579 if (!metadata->GetDouble(media::VideoFrameMetadata::RESOURCE_UTILIZATION, |
| 566 &consumer_resource_utilization)) { | 580 &consumer_resource_utilization)) { |
| 567 consumer_resource_utilization = -1.0; | 581 consumer_resource_utilization = -1.0; |
| 568 } | 582 } |
| 569 | 583 |
| 570 callback_to_io_thread.Run(release_sync_point, consumer_resource_utilization); | 584 callback_to_io_thread.Run(release_sync_point, release_sync_token, |
| 585 consumer_resource_utilization); | |
| 571 } | 586 } |
| 572 | 587 |
| 573 } // namespace content | 588 } // namespace content |
| OLD | NEW |