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

Side by Side Diff: media/capture/content/thread_safe_capture_oracle.cc

Issue 1865283003: Revert of Tab/Desktop Capture: Use requests instead of timer-based refreshing. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@video_refresh_from_sinks
Patch Set: Created 4 years, 8 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "media/capture/content/thread_safe_capture_oracle.h" 5 #include "media/capture/content/thread_safe_capture_oracle.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/bits.h" 11 #include "base/bits.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/memory/scoped_ptr.h" 13 #include "base/memory/scoped_ptr.h"
14 #include "base/numerics/safe_conversions.h"
15 #include "base/synchronization/lock.h" 14 #include "base/synchronization/lock.h"
16 #include "base/time/time.h" 15 #include "base/time/time.h"
17 #include "base/trace_event/trace_event.h" 16 #include "base/trace_event/trace_event.h"
18 #include "media/base/video_capture_types.h" 17 #include "media/base/video_capture_types.h"
19 #include "media/base/video_frame.h" 18 #include "media/base/video_frame.h"
20 #include "media/base/video_frame_metadata.h" 19 #include "media/base/video_frame_metadata.h"
21 #include "media/base/video_util.h" 20 #include "media/base/video_util.h"
22 #include "ui/gfx/geometry/rect.h" 21 #include "ui/gfx/geometry/rect.h"
23 22
24 namespace media { 23 namespace media {
(...skipping 26 matching lines...) Expand all
51 50
52 bool ThreadSafeCaptureOracle::ObserveEventAndDecideCapture( 51 bool ThreadSafeCaptureOracle::ObserveEventAndDecideCapture(
53 VideoCaptureOracle::Event event, 52 VideoCaptureOracle::Event event,
54 const gfx::Rect& damage_rect, 53 const gfx::Rect& damage_rect,
55 base::TimeTicks event_time, 54 base::TimeTicks event_time,
56 scoped_refptr<VideoFrame>* storage, 55 scoped_refptr<VideoFrame>* storage,
57 CaptureFrameCallback* callback) { 56 CaptureFrameCallback* callback) {
58 // Grab the current time before waiting to acquire the |lock_|. 57 // Grab the current time before waiting to acquire the |lock_|.
59 const base::TimeTicks capture_begin_time = base::TimeTicks::Now(); 58 const base::TimeTicks capture_begin_time = base::TimeTicks::Now();
60 59
61 gfx::Size visible_size; 60 base::AutoLock guard(lock_);
62 gfx::Size coded_size;
63 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> output_buffer;
64 double attenuated_utilization;
65 int frame_number;
66 base::TimeDelta estimated_frame_duration;
67 {
68 base::AutoLock guard(lock_);
69 61
70 if (!client_) 62 if (!client_)
71 return false; // Capture is stopped. 63 return false; // Capture is stopped.
72 64
73 if (!oracle_.ObserveEventAndDecideCapture(event, damage_rect, event_time)) { 65 const bool should_capture =
66 oracle_.ObserveEventAndDecideCapture(event, damage_rect, event_time);
67 const gfx::Size visible_size = oracle_.capture_size();
68 // TODO(miu): Clients should request exact padding, instead of this
69 // memory-wasting hack to make frames that are compatible with all HW
70 // encoders. http://crbug.com/555911
71 const gfx::Size coded_size(base::bits::Align(visible_size.width(), 16),
72 base::bits::Align(visible_size.height(), 16));
73
74 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> output_buffer(
75 client_->ReserveOutputBuffer(coded_size,
76 params_.requested_format.pixel_format,
77 params_.requested_format.pixel_storage));
78 // Get the current buffer pool utilization and attenuate it: The utilization
79 // reported to the oracle is in terms of a maximum sustainable amount (not the
80 // absolute maximum).
81 const double attenuated_utilization =
82 client_->GetBufferPoolUtilization() *
83 (100.0 / kTargetMaxPoolUtilizationPercent);
84
85 const char* event_name =
86 (event == VideoCaptureOracle::kTimerPoll
87 ? "poll"
88 : (event == VideoCaptureOracle::kCompositorUpdate ? "gpu"
89 : "unknown"));
90
91 // Consider the various reasons not to initiate a capture.
92 if (should_capture && !output_buffer.get()) {
93 TRACE_EVENT_INSTANT1("gpu.capture", "PipelineLimited",
94 TRACE_EVENT_SCOPE_THREAD, "trigger", event_name);
95 oracle_.RecordWillNotCapture(attenuated_utilization);
96 return false;
97 } else if (!should_capture && output_buffer.get()) {
98 if (event == VideoCaptureOracle::kCompositorUpdate) {
74 // This is a normal and acceptable way to drop a frame. We've hit our 99 // This is a normal and acceptable way to drop a frame. We've hit our
75 // capture rate limit: for example, the content is animating at 60fps but 100 // capture rate limit: for example, the content is animating at 60fps but
76 // we're capturing at 30fps. 101 // we're capturing at 30fps.
77 TRACE_EVENT_INSTANT1("gpu.capture", "FpsRateLimited", 102 TRACE_EVENT_INSTANT1("gpu.capture", "FpsRateLimited",
78 TRACE_EVENT_SCOPE_THREAD, "trigger", 103 TRACE_EVENT_SCOPE_THREAD, "trigger", event_name);
79 VideoCaptureOracle::EventAsString(event));
80 return false;
81 } 104 }
82 105 return false;
83 visible_size = oracle_.capture_size(); 106 } else if (!should_capture && !output_buffer.get()) {
84 // TODO(miu): Clients should request exact padding, instead of this 107 // We decided not to capture, but we wouldn't have been able to if we wanted
85 // memory-wasting hack to make frames that are compatible with all HW 108 // to because no output buffer was available.
86 // encoders. http://crbug.com/555911 109 TRACE_EVENT_INSTANT1("gpu.capture", "NearlyPipelineLimited",
87 coded_size.SetSize(base::bits::Align(visible_size.width(), 16), 110 TRACE_EVENT_SCOPE_THREAD, "trigger", event_name);
88 base::bits::Align(visible_size.height(), 16)); 111 return false;
89
90 if (event == VideoCaptureOracle::kPassiveRefreshRequest) {
91 output_buffer = client_->ResurrectLastOutputBuffer(
92 coded_size, params_.requested_format.pixel_format,
93 params_.requested_format.pixel_storage);
94 if (!output_buffer) {
95 TRACE_EVENT_INSTANT0("gpu.capture", "ResurrectionFailed",
96 TRACE_EVENT_SCOPE_THREAD);
97 return false;
98 }
99 } else {
100 output_buffer = client_->ReserveOutputBuffer(
101 coded_size, params_.requested_format.pixel_format,
102 params_.requested_format.pixel_storage);
103 }
104
105 // Get the current buffer pool utilization and attenuate it: The utilization
106 // reported to the oracle is in terms of a maximum sustainable amount (not
107 // the absolute maximum).
108 attenuated_utilization = client_->GetBufferPoolUtilization() *
109 (100.0 / kTargetMaxPoolUtilizationPercent);
110
111 if (!output_buffer) {
112 TRACE_EVENT_INSTANT2(
113 "gpu.capture", "PipelineLimited", TRACE_EVENT_SCOPE_THREAD, "trigger",
114 VideoCaptureOracle::EventAsString(event), "atten_util_percent",
115 base::saturated_cast<int>(attenuated_utilization * 100.0 + 0.5));
116 oracle_.RecordWillNotCapture(attenuated_utilization);
117 return false;
118 }
119
120 frame_number = oracle_.RecordCapture(attenuated_utilization);
121 estimated_frame_duration = oracle_.estimated_frame_duration();
122 } // End of critical section.
123
124 if (attenuated_utilization >= 1.0) {
125 TRACE_EVENT_INSTANT2(
126 "gpu.capture", "NearlyPipelineLimited", TRACE_EVENT_SCOPE_THREAD,
127 "trigger", VideoCaptureOracle::EventAsString(event),
128 "atten_util_percent",
129 base::saturated_cast<int>(attenuated_utilization * 100.0 + 0.5));
130 } 112 }
131 113
114 const int frame_number = oracle_.RecordCapture(attenuated_utilization);
132 TRACE_EVENT_ASYNC_BEGIN2("gpu.capture", "Capture", output_buffer.get(), 115 TRACE_EVENT_ASYNC_BEGIN2("gpu.capture", "Capture", output_buffer.get(),
133 "frame_number", frame_number, "trigger", 116 "frame_number", frame_number, "trigger", event_name);
134 VideoCaptureOracle::EventAsString(event));
135 117
136 DCHECK_EQ(media::PIXEL_STORAGE_CPU, params_.requested_format.pixel_storage); 118 DCHECK_EQ(media::PIXEL_STORAGE_CPU, params_.requested_format.pixel_storage);
137 *storage = VideoFrame::WrapExternalSharedMemory( 119 *storage = VideoFrame::WrapExternalSharedMemory(
138 params_.requested_format.pixel_format, coded_size, 120 params_.requested_format.pixel_format, coded_size,
139 gfx::Rect(visible_size), visible_size, 121 gfx::Rect(visible_size), visible_size,
140 static_cast<uint8_t*>(output_buffer->data()), 122 static_cast<uint8_t*>(output_buffer->data()),
141 output_buffer->mapped_size(), base::SharedMemory::NULLHandle(), 0u, 123 output_buffer->mapped_size(), base::SharedMemory::NULLHandle(), 0u,
142 base::TimeDelta()); 124 base::TimeDelta());
143 if (!(*storage)) 125 if (!(*storage))
144 return false; 126 return false;
145 *callback = base::Bind(&ThreadSafeCaptureOracle::DidCaptureFrame, this, 127 *callback =
146 frame_number, base::Passed(&output_buffer), 128 base::Bind(&ThreadSafeCaptureOracle::DidCaptureFrame, this, frame_number,
147 capture_begin_time, estimated_frame_duration); 129 base::Passed(&output_buffer), capture_begin_time,
148 130 oracle_.estimated_frame_duration());
149 return true; 131 return true;
150 } 132 }
151 133
152 bool ThreadSafeCaptureOracle::AttemptPassiveRefresh() {
153 const base::TimeTicks refresh_time = base::TimeTicks::Now();
154
155 scoped_refptr<VideoFrame> frame;
156 CaptureFrameCallback capture_callback;
157 if (!ObserveEventAndDecideCapture(VideoCaptureOracle::kPassiveRefreshRequest,
158 gfx::Rect(), refresh_time, &frame,
159 &capture_callback)) {
160 return false;
161 }
162
163 capture_callback.Run(frame, refresh_time, true);
164 return true;
165 }
166
167 gfx::Size ThreadSafeCaptureOracle::GetCaptureSize() const { 134 gfx::Size ThreadSafeCaptureOracle::GetCaptureSize() const {
168 base::AutoLock guard(lock_); 135 base::AutoLock guard(lock_);
169 return oracle_.capture_size(); 136 return oracle_.capture_size();
170 } 137 }
171 138
172 void ThreadSafeCaptureOracle::UpdateCaptureSize(const gfx::Size& source_size) { 139 void ThreadSafeCaptureOracle::UpdateCaptureSize(const gfx::Size& source_size) {
173 base::AutoLock guard(lock_); 140 base::AutoLock guard(lock_);
174 VLOG(1) << "Source size changed to " << source_size.ToString(); 141 VLOG(1) << "Source size changed to " << source_size.ToString();
175 oracle_.SetSourceSize(source_size); 142 oracle_.SetSourceSize(source_size);
176 } 143 }
(...skipping 12 matching lines...) Expand all
189 } 156 }
190 157
191 void ThreadSafeCaptureOracle::DidCaptureFrame( 158 void ThreadSafeCaptureOracle::DidCaptureFrame(
192 int frame_number, 159 int frame_number,
193 scoped_ptr<VideoCaptureDevice::Client::Buffer> buffer, 160 scoped_ptr<VideoCaptureDevice::Client::Buffer> buffer,
194 base::TimeTicks capture_begin_time, 161 base::TimeTicks capture_begin_time,
195 base::TimeDelta estimated_frame_duration, 162 base::TimeDelta estimated_frame_duration,
196 const scoped_refptr<VideoFrame>& frame, 163 const scoped_refptr<VideoFrame>& frame,
197 base::TimeTicks timestamp, 164 base::TimeTicks timestamp,
198 bool success) { 165 bool success) {
166 base::AutoLock guard(lock_);
199 TRACE_EVENT_ASYNC_END2("gpu.capture", "Capture", buffer.get(), "success", 167 TRACE_EVENT_ASYNC_END2("gpu.capture", "Capture", buffer.get(), "success",
200 success, "timestamp", timestamp.ToInternalValue()); 168 success, "timestamp", timestamp.ToInternalValue());
201 169
202 base::AutoLock guard(lock_);
203
204 if (oracle_.CompleteCapture(frame_number, success, &timestamp)) { 170 if (oracle_.CompleteCapture(frame_number, success, &timestamp)) {
205 TRACE_EVENT_INSTANT0("gpu.capture", "CaptureSucceeded", 171 TRACE_EVENT_INSTANT0("gpu.capture", "CaptureSucceeded",
206 TRACE_EVENT_SCOPE_THREAD); 172 TRACE_EVENT_SCOPE_THREAD);
207 173
208 if (!client_) 174 if (!client_)
209 return; // Capture is stopped. 175 return; // Capture is stopped.
210 176
211 frame->metadata()->SetDouble(VideoFrameMetadata::FRAME_RATE, 177 frame->metadata()->SetDouble(VideoFrameMetadata::FRAME_RATE,
212 params_.requested_format.frame_rate); 178 params_.requested_format.frame_rate);
213 frame->metadata()->SetTimeTicks(VideoFrameMetadata::CAPTURE_BEGIN_TIME, 179 frame->metadata()->SetTimeTicks(VideoFrameMetadata::CAPTURE_BEGIN_TIME,
(...skipping 18 matching lines...) Expand all
232 // destructor. |metadata| is still valid for read-access at this point. 198 // destructor. |metadata| is still valid for read-access at this point.
233 double utilization = -1.0; 199 double utilization = -1.0;
234 if (metadata->GetDouble(media::VideoFrameMetadata::RESOURCE_UTILIZATION, 200 if (metadata->GetDouble(media::VideoFrameMetadata::RESOURCE_UTILIZATION,
235 &utilization)) { 201 &utilization)) {
236 base::AutoLock guard(lock_); 202 base::AutoLock guard(lock_);
237 oracle_.RecordConsumerFeedback(frame_number, utilization); 203 oracle_.RecordConsumerFeedback(frame_number, utilization);
238 } 204 }
239 } 205 }
240 206
241 } // namespace media 207 } // namespace media
OLDNEW
« no previous file with comments | « media/capture/content/thread_safe_capture_oracle.h ('k') | media/capture/content/video_capture_oracle.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698