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

Unified Diff: media/capture/content/thread_safe_capture_oracle.cc

Issue 1864813002: 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: Fix WCVCD unit tests that test resize policies. 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 side-by-side diff with in-line comments
Download patch
Index: media/capture/content/thread_safe_capture_oracle.cc
diff --git a/media/capture/content/thread_safe_capture_oracle.cc b/media/capture/content/thread_safe_capture_oracle.cc
index f3ba5a428de864e26e721086452ed9869aa929fe..e99b56caefc899888676afa745bd3eadcc383005 100644
--- a/media/capture/content/thread_safe_capture_oracle.cc
+++ b/media/capture/content/thread_safe_capture_oracle.cc
@@ -11,6 +11,7 @@
#include "base/bits.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
+#include "base/numerics/safe_conversions.h"
#include "base/synchronization/lock.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
@@ -57,63 +58,80 @@ bool ThreadSafeCaptureOracle::ObserveEventAndDecideCapture(
// Grab the current time before waiting to acquire the |lock_|.
const base::TimeTicks capture_begin_time = base::TimeTicks::Now();
- base::AutoLock guard(lock_);
+ gfx::Size visible_size;
+ gfx::Size coded_size;
+ scoped_ptr<media::VideoCaptureDevice::Client::Buffer> output_buffer;
+ double attenuated_utilization;
+ int frame_number;
+ base::TimeDelta estimated_frame_duration;
+ {
+ base::AutoLock guard(lock_);
- if (!client_)
- return false; // Capture is stopped.
-
- const bool should_capture =
- oracle_.ObserveEventAndDecideCapture(event, damage_rect, event_time);
- const gfx::Size visible_size = oracle_.capture_size();
- // TODO(miu): Clients should request exact padding, instead of this
- // memory-wasting hack to make frames that are compatible with all HW
- // encoders. http://crbug.com/555911
- const gfx::Size coded_size(base::bits::Align(visible_size.width(), 16),
- base::bits::Align(visible_size.height(), 16));
-
- scoped_ptr<media::VideoCaptureDevice::Client::Buffer> output_buffer(
- client_->ReserveOutputBuffer(coded_size,
- params_.requested_format.pixel_format,
- params_.requested_format.pixel_storage));
- // Get the current buffer pool utilization and attenuate it: The utilization
- // reported to the oracle is in terms of a maximum sustainable amount (not the
- // absolute maximum).
- const double attenuated_utilization =
- client_->GetBufferPoolUtilization() *
- (100.0 / kTargetMaxPoolUtilizationPercent);
-
- const char* event_name =
- (event == VideoCaptureOracle::kTimerPoll
- ? "poll"
- : (event == VideoCaptureOracle::kCompositorUpdate ? "gpu"
- : "unknown"));
-
- // Consider the various reasons not to initiate a capture.
- if (should_capture && !output_buffer.get()) {
- TRACE_EVENT_INSTANT1("gpu.capture", "PipelineLimited",
- TRACE_EVENT_SCOPE_THREAD, "trigger", event_name);
- oracle_.RecordWillNotCapture(attenuated_utilization);
- return false;
- } else if (!should_capture && output_buffer.get()) {
- if (event == VideoCaptureOracle::kCompositorUpdate) {
+ if (!client_)
+ return false; // Capture is stopped.
+
+ if (!oracle_.ObserveEventAndDecideCapture(event, damage_rect, event_time)) {
// This is a normal and acceptable way to drop a frame. We've hit our
// capture rate limit: for example, the content is animating at 60fps but
// we're capturing at 30fps.
TRACE_EVENT_INSTANT1("gpu.capture", "FpsRateLimited",
- TRACE_EVENT_SCOPE_THREAD, "trigger", event_name);
+ TRACE_EVENT_SCOPE_THREAD, "trigger",
+ VideoCaptureOracle::EventAsString(event));
+ return false;
}
- return false;
- } else if (!should_capture && !output_buffer.get()) {
- // We decided not to capture, but we wouldn't have been able to if we wanted
- // to because no output buffer was available.
- TRACE_EVENT_INSTANT1("gpu.capture", "NearlyPipelineLimited",
- TRACE_EVENT_SCOPE_THREAD, "trigger", event_name);
- return false;
+
+ visible_size = oracle_.capture_size();
+ // TODO(miu): Clients should request exact padding, instead of this
+ // memory-wasting hack to make frames that are compatible with all HW
+ // encoders. http://crbug.com/555911
+ coded_size.SetSize(base::bits::Align(visible_size.width(), 16),
+ base::bits::Align(visible_size.height(), 16));
+
+ if (event == VideoCaptureOracle::kPassiveRefreshRequest) {
+ output_buffer = client_->ResurrectLastOutputBuffer(
+ coded_size, params_.requested_format.pixel_format,
+ params_.requested_format.pixel_storage);
+ if (!output_buffer) {
+ TRACE_EVENT_INSTANT0("gpu.capture", "ResurrectionFailed",
+ TRACE_EVENT_SCOPE_THREAD);
+ return false;
+ }
+ } else {
+ output_buffer = client_->ReserveOutputBuffer(
+ coded_size, params_.requested_format.pixel_format,
+ params_.requested_format.pixel_storage);
+ }
+
+ // Get the current buffer pool utilization and attenuate it: The utilization
+ // reported to the oracle is in terms of a maximum sustainable amount (not
+ // the absolute maximum).
+ attenuated_utilization = client_->GetBufferPoolUtilization() *
+ (100.0 / kTargetMaxPoolUtilizationPercent);
+
+ if (!output_buffer) {
+ TRACE_EVENT_INSTANT2(
+ "gpu.capture", "PipelineLimited", TRACE_EVENT_SCOPE_THREAD, "trigger",
+ VideoCaptureOracle::EventAsString(event), "atten_util_percent",
+ base::saturated_cast<int>(attenuated_utilization * 100.0 + 0.5));
+ oracle_.RecordWillNotCapture(attenuated_utilization);
+ return false;
+ }
+
+ frame_number = oracle_.RecordCapture(attenuated_utilization);
+ estimated_frame_duration = oracle_.estimated_frame_duration();
+ } // End of critical section.
+
+ if (attenuated_utilization >= 1.0) {
+ TRACE_EVENT_INSTANT2(
+ "gpu.capture", "NearlyPipelineLimited", TRACE_EVENT_SCOPE_THREAD,
+ "trigger", VideoCaptureOracle::EventAsString(event),
+ "atten_util_percent",
+ base::saturated_cast<int>(attenuated_utilization * 100.0 + 0.5));
}
- const int frame_number = oracle_.RecordCapture(attenuated_utilization);
TRACE_EVENT_ASYNC_BEGIN2("gpu.capture", "Capture", output_buffer.get(),
- "frame_number", frame_number, "trigger", event_name);
+ "frame_number", frame_number, "trigger",
+ VideoCaptureOracle::EventAsString(event));
DCHECK_EQ(media::PIXEL_STORAGE_CPU, params_.requested_format.pixel_storage);
*storage = VideoFrame::WrapExternalSharedMemory(
@@ -124,10 +142,25 @@ bool ThreadSafeCaptureOracle::ObserveEventAndDecideCapture(
base::TimeDelta());
if (!(*storage))
return false;
- *callback =
- base::Bind(&ThreadSafeCaptureOracle::DidCaptureFrame, this, frame_number,
- base::Passed(&output_buffer), capture_begin_time,
- oracle_.estimated_frame_duration());
+ *callback = base::Bind(&ThreadSafeCaptureOracle::DidCaptureFrame, this,
+ frame_number, base::Passed(&output_buffer),
+ capture_begin_time, estimated_frame_duration);
+
+ return true;
+}
+
+bool ThreadSafeCaptureOracle::AttemptPassiveRefresh() {
+ const base::TimeTicks refresh_time = base::TimeTicks::Now();
+
+ scoped_refptr<VideoFrame> frame;
+ CaptureFrameCallback capture_callback;
+ if (!ObserveEventAndDecideCapture(VideoCaptureOracle::kPassiveRefreshRequest,
Irfan 2016/04/06 19:53:05 I do not have the full picture here, but how does
miu 2016/04/06 22:33:53 From the oracle's point-of-view, the passive frame
+ gfx::Rect(), refresh_time, &frame,
+ &capture_callback)) {
+ return false;
+ }
+
+ capture_callback.Run(frame, refresh_time, true);
return true;
}
@@ -163,10 +196,11 @@ void ThreadSafeCaptureOracle::DidCaptureFrame(
const scoped_refptr<VideoFrame>& frame,
base::TimeTicks timestamp,
bool success) {
- base::AutoLock guard(lock_);
TRACE_EVENT_ASYNC_END2("gpu.capture", "Capture", buffer.get(), "success",
success, "timestamp", timestamp.ToInternalValue());
+ base::AutoLock guard(lock_);
+
if (oracle_.CompleteCapture(frame_number, success, &timestamp)) {
TRACE_EVENT_INSTANT0("gpu.capture", "CaptureSucceeded",
TRACE_EVENT_SCOPE_THREAD);

Powered by Google App Engine
This is Rietveld 408576698