| 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 e99b56caefc899888676afa745bd3eadcc383005..f3ba5a428de864e26e721086452ed9869aa929fe 100644
|
| --- a/media/capture/content/thread_safe_capture_oracle.cc
|
| +++ b/media/capture/content/thread_safe_capture_oracle.cc
|
| @@ -11,7 +11,6 @@
|
| #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"
|
| @@ -58,80 +57,63 @@
|
| // Grab the current time before waiting to acquire the |lock_|.
|
| const base::TimeTicks capture_begin_time = base::TimeTicks::Now();
|
|
|
| - 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.
|
| -
|
| - if (!oracle_.ObserveEventAndDecideCapture(event, damage_rect, event_time)) {
|
| + 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) {
|
| // 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",
|
| - VideoCaptureOracle::EventAsString(event));
|
| - return false;
|
| + TRACE_EVENT_SCOPE_THREAD, "trigger", event_name);
|
| }
|
| -
|
| - 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));
|
| + 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;
|
| }
|
|
|
| + const int frame_number = oracle_.RecordCapture(attenuated_utilization);
|
| TRACE_EVENT_ASYNC_BEGIN2("gpu.capture", "Capture", output_buffer.get(),
|
| - "frame_number", frame_number, "trigger",
|
| - VideoCaptureOracle::EventAsString(event));
|
| + "frame_number", frame_number, "trigger", event_name);
|
|
|
| DCHECK_EQ(media::PIXEL_STORAGE_CPU, params_.requested_format.pixel_storage);
|
| *storage = VideoFrame::WrapExternalSharedMemory(
|
| @@ -142,25 +124,10 @@
|
| base::TimeDelta());
|
| if (!(*storage))
|
| return false;
|
| - *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,
|
| - gfx::Rect(), refresh_time, &frame,
|
| - &capture_callback)) {
|
| - return false;
|
| - }
|
| -
|
| - capture_callback.Run(frame, refresh_time, true);
|
| + *callback =
|
| + base::Bind(&ThreadSafeCaptureOracle::DidCaptureFrame, this, frame_number,
|
| + base::Passed(&output_buffer), capture_begin_time,
|
| + oracle_.estimated_frame_duration());
|
| return true;
|
| }
|
|
|
| @@ -196,10 +163,9 @@
|
| 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, ×tamp)) {
|
| TRACE_EVENT_INSTANT0("gpu.capture", "CaptureSucceeded",
|
|
|