| Index: content/renderer/media/video_capture_impl.cc
|
| diff --git a/content/renderer/media/video_capture_impl.cc b/content/renderer/media/video_capture_impl.cc
|
| index 007b0bc6d953cde6030097bd2f8730465fa7b3b4..e5791356a565c16f27f84e7b3681257cfd1bb1e3 100644
|
| --- a/content/renderer/media/video_capture_impl.cc
|
| +++ b/content/renderer/media/video_capture_impl.cc
|
| @@ -22,6 +22,20 @@
|
|
|
| namespace content {
|
|
|
| +namespace {
|
| +
|
| +// This is called on an unknown thread when the VideoFrame destructor executes.
|
| +// As of this writing, this callback mechanism is the only interface in
|
| +// VideoFrame to provide the final value for |release_sync_point|.
|
| +// VideoCaptureImpl::DidFinishConsumingFrame() will read the value saved here,
|
| +// and pass it back to the IO thread to pass back to the host via the
|
| +// BufferReady IPC.
|
| +void SaveReleaseSyncPoint(uint32* storage, uint32 release_sync_point) {
|
| + *storage = release_sync_point;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| class VideoCaptureImpl::ClientBuffer
|
| : public base::RefCountedThreadSafe<ClientBuffer> {
|
| public:
|
| @@ -220,7 +234,7 @@ void VideoCaptureImpl::OnBufferReceived(int buffer_id,
|
| DCHECK(io_task_runner_->BelongsToCurrentThread());
|
|
|
| if (state_ != VIDEO_CAPTURE_STATE_STARTED || suspended_) {
|
| - Send(new VideoCaptureHostMsg_BufferReady(device_id_, buffer_id, 0));
|
| + Send(new VideoCaptureHostMsg_BufferReady(device_id_, buffer_id, 0, -1.0));
|
| return;
|
| }
|
|
|
| @@ -249,12 +263,14 @@ void VideoCaptureImpl::OnBufferReceived(int buffer_id,
|
| 0,
|
| timestamp - first_frame_timestamp_);
|
| frame->AddDestructionObserver(
|
| - media::BindToCurrentLoop(
|
| - base::Bind(&VideoCaptureImpl::OnClientBufferFinished,
|
| - weak_factory_.GetWeakPtr(),
|
| - buffer_id,
|
| - buffer,
|
| - 0)));
|
| + base::Bind(&VideoCaptureImpl::DidFinishConsumingFrame,
|
| + frame->metadata(),
|
| + nullptr,
|
| + media::BindToCurrentLoop(
|
| + base::Bind(&VideoCaptureImpl::OnClientBufferFinished,
|
| + weak_factory_.GetWeakPtr(),
|
| + buffer_id,
|
| + buffer))));
|
| frame->metadata()->MergeInternalValuesFrom(metadata);
|
|
|
| for (const auto& client : clients_)
|
| @@ -270,21 +286,31 @@ void VideoCaptureImpl::OnMailboxBufferReceived(
|
| DCHECK(io_task_runner_->BelongsToCurrentThread());
|
|
|
| if (state_ != VIDEO_CAPTURE_STATE_STARTED || suspended_) {
|
| - Send(new VideoCaptureHostMsg_BufferReady(device_id_, buffer_id, 0));
|
| + Send(new VideoCaptureHostMsg_BufferReady(device_id_, buffer_id, 0, -1.0));
|
| return;
|
| }
|
|
|
| if (first_frame_timestamp_.is_null())
|
| first_frame_timestamp_ = timestamp;
|
|
|
| + uint32* const release_sync_point_storage =
|
| + new uint32(0); // Deleted in DidFinishConsumingFrame().
|
| scoped_refptr<media::VideoFrame> frame = media::VideoFrame::WrapNativeTexture(
|
| mailbox_holder,
|
| - media::BindToCurrentLoop(base::Bind(
|
| - &VideoCaptureImpl::OnClientBufferFinished, weak_factory_.GetWeakPtr(),
|
| - buffer_id, scoped_refptr<ClientBuffer>())),
|
| + base::Bind(&SaveReleaseSyncPoint, release_sync_point_storage),
|
| packed_frame_size, gfx::Rect(packed_frame_size), packed_frame_size,
|
| timestamp - first_frame_timestamp_, false /* allow_overlay */,
|
| true /* has_alpha */);
|
| + frame->AddDestructionObserver(
|
| + base::Bind(&VideoCaptureImpl::DidFinishConsumingFrame,
|
| + frame->metadata(),
|
| + release_sync_point_storage,
|
| + media::BindToCurrentLoop(base::Bind(
|
| + &VideoCaptureImpl::OnClientBufferFinished,
|
| + weak_factory_.GetWeakPtr(),
|
| + buffer_id,
|
| + scoped_refptr<ClientBuffer>()))));
|
| +
|
| frame->metadata()->MergeInternalValuesFrom(metadata);
|
|
|
| for (const auto& client : clients_)
|
| @@ -294,10 +320,13 @@ void VideoCaptureImpl::OnMailboxBufferReceived(
|
| void VideoCaptureImpl::OnClientBufferFinished(
|
| int buffer_id,
|
| const scoped_refptr<ClientBuffer>& /* ignored_buffer */,
|
| - uint32 release_sync_point) {
|
| + uint32 release_sync_point,
|
| + double consumer_resource_utilization) {
|
| DCHECK(io_task_runner_->BelongsToCurrentThread());
|
| - Send(new VideoCaptureHostMsg_BufferReady(
|
| - device_id_, buffer_id, release_sync_point));
|
| + Send(new VideoCaptureHostMsg_BufferReady(device_id_,
|
| + buffer_id,
|
| + release_sync_point,
|
| + consumer_resource_utilization));
|
| }
|
|
|
| void VideoCaptureImpl::OnStateChanged(VideoCaptureState state) {
|
| @@ -429,4 +458,27 @@ bool VideoCaptureImpl::RemoveClient(int client_id, ClientInfoMap* clients) {
|
| return found;
|
| }
|
|
|
| +// static
|
| +void VideoCaptureImpl::DidFinishConsumingFrame(
|
| + const media::VideoFrameMetadata* metadata,
|
| + uint32* release_sync_point_storage,
|
| + const base::Callback<void(uint32, double)>& callback_to_io_thread) {
|
| + // Note: This function may be called on any thread by the VideoFrame
|
| + // destructor. |metadata| is still valid for read-access at this point.
|
| +
|
| + uint32 release_sync_point = 0u;
|
| + if (release_sync_point_storage) {
|
| + release_sync_point = *release_sync_point_storage;
|
| + delete release_sync_point_storage;
|
| + }
|
| +
|
| + double consumer_resource_utilization = -1.0;
|
| + if (!metadata->GetDouble(media::VideoFrameMetadata::RESOURCE_UTILIZATION,
|
| + &consumer_resource_utilization)) {
|
| + consumer_resource_utilization = -1.0;
|
| + }
|
| +
|
| + callback_to_io_thread.Run(release_sync_point, consumer_resource_utilization);
|
| +}
|
| +
|
| } // namespace content
|
|
|