OLD | NEW |
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 | 8 |
9 #include <memory> | 9 #include <memory> |
10 #include <utility> | 10 #include <utility> |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 if (!oracle_.ObserveEventAndDecideCapture(event, damage_rect, event_time)) { | 74 if (!oracle_.ObserveEventAndDecideCapture(event, damage_rect, event_time)) { |
75 // This is a normal and acceptable way to drop a frame. We've hit our | 75 // This is a normal and acceptable way to drop a frame. We've hit our |
76 // capture rate limit: for example, the content is animating at 60fps but | 76 // capture rate limit: for example, the content is animating at 60fps but |
77 // we're capturing at 30fps. | 77 // we're capturing at 30fps. |
78 TRACE_EVENT_INSTANT1("gpu.capture", "FpsRateLimited", | 78 TRACE_EVENT_INSTANT1("gpu.capture", "FpsRateLimited", |
79 TRACE_EVENT_SCOPE_THREAD, "trigger", | 79 TRACE_EVENT_SCOPE_THREAD, "trigger", |
80 VideoCaptureOracle::EventAsString(event)); | 80 VideoCaptureOracle::EventAsString(event)); |
81 return false; | 81 return false; |
82 } | 82 } |
83 | 83 |
| 84 frame_number = oracle_.next_frame_number(); |
84 visible_size = oracle_.capture_size(); | 85 visible_size = oracle_.capture_size(); |
85 // TODO(miu): Clients should request exact padding, instead of this | 86 // TODO(miu): Clients should request exact padding, instead of this |
86 // memory-wasting hack to make frames that are compatible with all HW | 87 // memory-wasting hack to make frames that are compatible with all HW |
87 // encoders. http://crbug.com/555911 | 88 // encoders. http://crbug.com/555911 |
88 coded_size.SetSize(base::bits::Align(visible_size.width(), 16), | 89 coded_size.SetSize(base::bits::Align(visible_size.width(), 16), |
89 base::bits::Align(visible_size.height(), 16)); | 90 base::bits::Align(visible_size.height(), 16)); |
90 | 91 |
91 if (event == VideoCaptureOracle::kPassiveRefreshRequest) { | 92 if (event == VideoCaptureOracle::kPassiveRefreshRequest) { |
92 output_buffer = client_->ResurrectLastOutputBuffer( | 93 output_buffer = client_->ResurrectLastOutputBuffer( |
93 coded_size, params_.requested_format.pixel_format, | 94 coded_size, params_.requested_format.pixel_format, |
94 params_.requested_format.pixel_storage); | 95 params_.requested_format.pixel_storage, frame_number); |
95 if (!output_buffer) { | 96 if (!output_buffer) { |
96 TRACE_EVENT_INSTANT0("gpu.capture", "ResurrectionFailed", | 97 TRACE_EVENT_INSTANT0("gpu.capture", "ResurrectionFailed", |
97 TRACE_EVENT_SCOPE_THREAD); | 98 TRACE_EVENT_SCOPE_THREAD); |
98 return false; | 99 return false; |
99 } | 100 } |
100 } else { | 101 } else { |
101 output_buffer = client_->ReserveOutputBuffer( | 102 output_buffer = client_->ReserveOutputBuffer( |
102 coded_size, params_.requested_format.pixel_format, | 103 coded_size, params_.requested_format.pixel_format, |
103 params_.requested_format.pixel_storage); | 104 params_.requested_format.pixel_storage, frame_number); |
104 } | 105 } |
105 | 106 |
106 // Get the current buffer pool utilization and attenuate it: The utilization | 107 // Get the current buffer pool utilization and attenuate it: The utilization |
107 // reported to the oracle is in terms of a maximum sustainable amount (not | 108 // reported to the oracle is in terms of a maximum sustainable amount (not |
108 // the absolute maximum). | 109 // the absolute maximum). |
109 attenuated_utilization = client_->GetBufferPoolUtilization() * | 110 attenuated_utilization = client_->GetBufferPoolUtilization() * |
110 (100.0 / kTargetMaxPoolUtilizationPercent); | 111 (100.0 / kTargetMaxPoolUtilizationPercent); |
111 | 112 |
112 if (!output_buffer) { | 113 if (!output_buffer) { |
113 TRACE_EVENT_INSTANT2( | 114 TRACE_EVENT_INSTANT2( |
114 "gpu.capture", "PipelineLimited", TRACE_EVENT_SCOPE_THREAD, "trigger", | 115 "gpu.capture", "PipelineLimited", TRACE_EVENT_SCOPE_THREAD, "trigger", |
115 VideoCaptureOracle::EventAsString(event), "atten_util_percent", | 116 VideoCaptureOracle::EventAsString(event), "atten_util_percent", |
116 base::saturated_cast<int>(attenuated_utilization * 100.0 + 0.5)); | 117 base::saturated_cast<int>(attenuated_utilization * 100.0 + 0.5)); |
117 oracle_.RecordWillNotCapture(attenuated_utilization); | 118 oracle_.RecordWillNotCapture(attenuated_utilization); |
118 return false; | 119 return false; |
119 } | 120 } |
120 | 121 |
121 frame_number = oracle_.RecordCapture(attenuated_utilization); | 122 oracle_.RecordCapture(attenuated_utilization); |
122 estimated_frame_duration = oracle_.estimated_frame_duration(); | 123 estimated_frame_duration = oracle_.estimated_frame_duration(); |
123 } // End of critical section. | 124 } // End of critical section. |
124 | 125 |
125 if (attenuated_utilization >= 1.0) { | 126 if (attenuated_utilization >= 1.0) { |
126 TRACE_EVENT_INSTANT2( | 127 TRACE_EVENT_INSTANT2( |
127 "gpu.capture", "NearlyPipelineLimited", TRACE_EVENT_SCOPE_THREAD, | 128 "gpu.capture", "NearlyPipelineLimited", TRACE_EVENT_SCOPE_THREAD, |
128 "trigger", VideoCaptureOracle::EventAsString(event), | 129 "trigger", VideoCaptureOracle::EventAsString(event), |
129 "atten_util_percent", | 130 "atten_util_percent", |
130 base::saturated_cast<int>(attenuated_utilization * 100.0 + 0.5)); | 131 base::saturated_cast<int>(attenuated_utilization * 100.0 + 0.5)); |
131 } | 132 } |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 params_.requested_format.frame_rate); | 222 params_.requested_format.frame_rate); |
222 frame->metadata()->SetTimeTicks(VideoFrameMetadata::CAPTURE_BEGIN_TIME, | 223 frame->metadata()->SetTimeTicks(VideoFrameMetadata::CAPTURE_BEGIN_TIME, |
223 capture_begin_time); | 224 capture_begin_time); |
224 frame->metadata()->SetTimeTicks(VideoFrameMetadata::CAPTURE_END_TIME, | 225 frame->metadata()->SetTimeTicks(VideoFrameMetadata::CAPTURE_END_TIME, |
225 base::TimeTicks::Now()); | 226 base::TimeTicks::Now()); |
226 frame->metadata()->SetTimeDelta(VideoFrameMetadata::FRAME_DURATION, | 227 frame->metadata()->SetTimeDelta(VideoFrameMetadata::FRAME_DURATION, |
227 estimated_frame_duration); | 228 estimated_frame_duration); |
228 frame->metadata()->SetTimeTicks(VideoFrameMetadata::REFERENCE_TIME, | 229 frame->metadata()->SetTimeTicks(VideoFrameMetadata::REFERENCE_TIME, |
229 reference_time); | 230 reference_time); |
230 | 231 |
231 frame->AddDestructionObserver( | |
232 base::Bind(&ThreadSafeCaptureOracle::DidConsumeFrame, this, | |
233 frame_number, frame->metadata())); | |
234 | |
235 client_->OnIncomingCapturedVideoFrame(std::move(buffer), std::move(frame)); | 232 client_->OnIncomingCapturedVideoFrame(std::move(buffer), std::move(frame)); |
236 } | 233 } |
237 } | 234 } |
238 | 235 |
239 void ThreadSafeCaptureOracle::DidConsumeFrame( | 236 void ThreadSafeCaptureOracle::OnConsumerReportingUtilization( |
240 int frame_number, | 237 int frame_number, |
241 const media::VideoFrameMetadata* metadata) { | 238 double utilization) { |
242 // Note: This function may be called on any thread by the VideoFrame | 239 base::AutoLock guard(lock_); |
243 // destructor. |metadata| is still valid for read-access at this point. | 240 oracle_.RecordConsumerFeedback(frame_number, utilization); |
244 double utilization = -1.0; | |
245 if (metadata->GetDouble(media::VideoFrameMetadata::RESOURCE_UTILIZATION, | |
246 &utilization)) { | |
247 base::AutoLock guard(lock_); | |
248 oracle_.RecordConsumerFeedback(frame_number, utilization); | |
249 } | |
250 } | 241 } |
251 | 242 |
252 } // namespace media | 243 } // namespace media |
OLD | NEW |