Index: media/capture/video_capture_oracle.h |
diff --git a/media/capture/video_capture_oracle.h b/media/capture/video_capture_oracle.h |
index 8e2980dab0a0aba8e9402f113d5375c6f7680fa8..94bdc009bcebc0664db9d1b1a7e2b7af10be1571 100644 |
--- a/media/capture/video_capture_oracle.h |
+++ b/media/capture/video_capture_oracle.h |
@@ -10,6 +10,8 @@ |
#include "base/time/time.h" |
#include "media/base/media_export.h" |
#include "media/capture/animated_content_sampler.h" |
+#include "media/capture/capture_resolution_chooser.h" |
+#include "media/capture/feedback_signal_accumulator.h" |
#include "media/capture/smooth_event_sampler.h" |
#include "ui/gfx/geometry/rect.h" |
@@ -34,9 +36,18 @@ class MEDIA_EXPORT VideoCaptureOracle { |
kMinTimerPollPeriodMillis = 125, // 8 FPS |
}; |
- explicit VideoCaptureOracle(base::TimeDelta min_capture_period); |
+ VideoCaptureOracle(base::TimeDelta min_capture_period, |
+ const gfx::Size& max_frame_size, |
+ media::ResolutionChangePolicy resolution_change_policy, |
+ bool enable_auto_throttling); |
+ |
virtual ~VideoCaptureOracle(); |
+ // Sets the source content size. This may not have an immediate effect on the |
+ // proposed capture size, as the oracle will prevent too-frequent changes from |
+ // occurring. |
+ void SetSourceSize(const gfx::Size& source_size); |
+ |
// Record a event of type |event|, and decide whether the caller should do a |
// frame capture. |damage_rect| is the region of a frame about to be drawn, |
// and may be an empty Rect, if this is not known. If the caller accepts the |
@@ -45,9 +56,14 @@ class MEDIA_EXPORT VideoCaptureOracle { |
const gfx::Rect& damage_rect, |
base::TimeTicks event_time); |
- // Record the start of a capture. Returns a frame_number to be used with |
- // CompleteCapture(). |
- int RecordCapture(); |
+ // Record and update internal state based on whether the frame capture will be |
+ // started. |pool_utilization| is a value in the range 0.0 to 1.0 to indicate |
+ // the current buffer pool utilization relative to a sustainable maximum (not |
+ // the absolute maximum). This method should only be called if the last call |
+ // to ObserveEventAndDecideCapture() returned true. The first method returns |
+ // the |frame_number| to be used with CompleteCapture(). |
+ int RecordCapture(double pool_utilization); |
+ void RecordWillNotCapture(double pool_utilization); |
// Notify of the completion of a capture, and whether it was successful. |
// Returns true iff the captured frame should be delivered. |frame_timestamp| |
@@ -57,6 +73,15 @@ class MEDIA_EXPORT VideoCaptureOracle { |
bool capture_was_successful, |
base::TimeTicks* frame_timestamp); |
+ // Record the resource utilization feedback for a frame that was processed by |
+ // the consumer. This allows the oracle to reduce/increase future data volume |
+ // if the consumer is overloaded/under-utilized. |resource_utilization| is a |
+ // value in the range 0.0 to 1.0 to indicate the current consumer resource |
+ // utilization relative to a sustainable maximum (not the absolute maximum). |
+ // This method should only be called for frames where CompleteCapture() |
+ // returned true. |
+ void RecordConsumerFeedback(int frame_number, double resource_utilization); |
+ |
base::TimeDelta min_capture_period() const { |
return smoothing_sampler_.min_capture_period(); |
} |
@@ -68,11 +93,46 @@ class MEDIA_EXPORT VideoCaptureOracle { |
return duration_of_next_frame_; |
} |
+ // Returns the capture frame size the client should use. This is updated by |
+ // calls to ObserveEventAndDecideCapture(). The oracle prevents too-frequent |
+ // changes to the capture size, to avoid stressing the end-to-end pipeline. |
+ gfx::Size capture_size() const { return capture_size_; } |
+ |
private: |
- // Retrieve/Assign a frame timestamp by capture |frame_number|. |
+ // Retrieve/Assign a frame timestamp by capture |frame_number|. Only valid |
+ // when IsFrameInRecentHistory(frame_number) returns true. |
base::TimeTicks GetFrameTimestamp(int frame_number) const; |
void SetFrameTimestamp(int frame_number, base::TimeTicks timestamp); |
+ // Returns true if the frame timestamp ring-buffer currently includes a |
+ // slot for the given |frame_number|. |
+ bool IsFrameInRecentHistory(int frame_number) const; |
+ |
+ // Queries the ResolutionChooser to update |capture_size_|, and resets all the |
+ // FeedbackSignalAccumulator members to stable-state starting values. The |
+ // accumulators are reset such that they can only apply feedback updates for |
+ // future frames (those with a timestamp after |last_frame_time|). |
+ void CommitCaptureSizeAndReset(base::TimeTicks last_frame_time); |
+ |
+ // Called after a capture or no-capture decision was recorded. This analyzes |
+ // current state and may result in a future change to the capture frame size. |
+ void AnalyzeAndAdjust(base::TimeTicks analyze_time); |
+ |
+ // Analyzes current feedback signal accumulators for an indication that the |
+ // capture size should be decreased. Returns either a decreased area, or -1 |
+ // if no decrease should be made. |
+ int AnalyzeForDecreasedArea(base::TimeTicks analyze_time); |
+ |
+ // Analyzes current feedback signal accumulators for an indication that the |
+ // the system has had excellent long-term performance and the capture size |
+ // should be increased to improve quality. Returns either an increased area, |
+ // or -1 if no increase should be made. |
+ int AnalyzeForIncreasedArea(base::TimeTicks analyze_time); |
+ |
+ // Set to false to prevent the oracle from automatically adjusting the capture |
+ // size in response to end-to-end utilization. |
+ const bool auto_throttling_enabled_; |
+ |
// Incremented every time a paint or update event occurs. |
int next_frame_number_; |
@@ -98,11 +158,40 @@ class MEDIA_EXPORT VideoCaptureOracle { |
SmoothEventSampler smoothing_sampler_; |
AnimatedContentSampler content_sampler_; |
+ // Determines video capture frame sizes. |
+ CaptureResolutionChooser resolution_chooser_; |
+ |
+ // The current capture size. |resolution_chooser_| may hold an updated value |
+ // because the oracle prevents this size from changing too frequently. This |
+ // avoids over-stressing consumers (e.g., when a window is being activly |
+ // drag-resized) and allowing the end-to-end system time to stabilize. |
+ gfx::Size capture_size_; |
+ |
// Recent history of frame timestamps proposed by VideoCaptureOracle. This is |
// a ring-buffer, and should only be accessed by the Get/SetFrameTimestamp() |
// methods. |
enum { kMaxFrameTimestamps = 16 }; |
base::TimeTicks frame_timestamps_[kMaxFrameTimestamps]; |
+ |
+ // Recent average buffer pool utilization for capture. |
+ FeedbackSignalAccumulator buffer_pool_utilization_; |
+ |
+ // Estimated maximum frame area that currently can be handled by the consumer, |
+ // in number of pixels per frame. This is used to adjust the capture size up |
+ // or down to a data volume the consumer can handle. Note that some consumers |
+ // do not provide feedback, and the analysis logic should account for that. |
+ FeedbackSignalAccumulator estimated_capable_area_; |
+ |
+ // The time of the first analysis which concluded the end-to-end system was |
+ // under-utilized. If null, the system is not currently under-utilized. This |
+ // is used to determine when a proving period has elapsed that justifies an |
+ // increase in capture size. |
+ base::TimeTicks start_time_of_underutilization_; |
+ |
+ // The timestamp of the frame where |content_sampler_| last detected |
+ // animation. This determines whether capture size increases will be |
+ // aggressive (because content is not animating). |
+ base::TimeTicks last_time_animation_was_detected_; |
}; |
} // namespace media |