OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 "content/browser/media/capture/video_capture_oracle.h" | 5 #include "content/browser/media/capture/video_capture_oracle.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/format_macros.h" | 9 #include "base/format_macros.h" |
10 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
(...skipping 20 matching lines...) Loading... |
31 const base::TimeDelta expected_delta = | 31 const base::TimeDelta expected_delta = |
32 base::TimeDelta::FromSeconds(1) / frame_rate; | 32 base::TimeDelta::FromSeconds(1) / frame_rate; |
33 return (delta - expected_delta).InMillisecondsF() / | 33 return (delta - expected_delta).InMillisecondsF() / |
34 expected_delta.InMillisecondsF(); | 34 expected_delta.InMillisecondsF(); |
35 } | 35 } |
36 | 36 |
37 } // anonymous namespace | 37 } // anonymous namespace |
38 | 38 |
39 VideoCaptureOracle::VideoCaptureOracle(base::TimeDelta min_capture_period) | 39 VideoCaptureOracle::VideoCaptureOracle(base::TimeDelta min_capture_period) |
40 : next_frame_number_(0), | 40 : next_frame_number_(0), |
41 last_delivered_frame_number_(-1), | 41 last_successfully_delivered_frame_number_(-1), |
| 42 num_frames_pending_(0), |
42 smoothing_sampler_(min_capture_period, | 43 smoothing_sampler_(min_capture_period, |
43 kNumRedundantCapturesOfStaticContent), | 44 kNumRedundantCapturesOfStaticContent), |
44 content_sampler_(min_capture_period) { | 45 content_sampler_(min_capture_period) { |
45 } | 46 } |
46 | 47 |
47 VideoCaptureOracle::~VideoCaptureOracle() {} | 48 VideoCaptureOracle::~VideoCaptureOracle() {} |
48 | 49 |
49 bool VideoCaptureOracle::ObserveEventAndDecideCapture( | 50 bool VideoCaptureOracle::ObserveEventAndDecideCapture( |
50 Event event, | 51 Event event, |
51 const gfx::Rect& damage_rect, | 52 const gfx::Rect& damage_rect, |
(...skipping 21 matching lines...) Loading... |
73 } | 74 } |
74 } else { | 75 } else { |
75 should_sample = smoothing_sampler_.ShouldSample(); | 76 should_sample = smoothing_sampler_.ShouldSample(); |
76 if (should_sample) | 77 if (should_sample) |
77 duration_of_next_frame_ = smoothing_sampler_.min_capture_period(); | 78 duration_of_next_frame_ = smoothing_sampler_.min_capture_period(); |
78 } | 79 } |
79 break; | 80 break; |
80 case kTimerPoll: | 81 case kTimerPoll: |
81 // While the timer is firing, only allow a sampling if there are none | 82 // While the timer is firing, only allow a sampling if there are none |
82 // currently in-progress. | 83 // currently in-progress. |
83 if (last_delivered_frame_number_ == (next_frame_number_ - 1)) { | 84 if (num_frames_pending_ == 0) { |
84 should_sample = smoothing_sampler_.IsOverdueForSamplingAt(event_time); | 85 should_sample = smoothing_sampler_.IsOverdueForSamplingAt(event_time); |
85 if (should_sample) | 86 if (should_sample) |
86 duration_of_next_frame_ = smoothing_sampler_.min_capture_period(); | 87 duration_of_next_frame_ = smoothing_sampler_.min_capture_period(); |
87 } | 88 } |
88 break; | 89 break; |
89 case kNumEvents: | 90 case kNumEvents: |
90 NOTREACHED(); | 91 NOTREACHED(); |
91 break; | 92 break; |
92 } | 93 } |
93 | 94 |
94 SetFrameTimestamp(next_frame_number_, event_time); | 95 SetFrameTimestamp(next_frame_number_, event_time); |
95 return should_sample; | 96 return should_sample; |
96 } | 97 } |
97 | 98 |
98 int VideoCaptureOracle::RecordCapture() { | 99 int VideoCaptureOracle::RecordCapture() { |
99 smoothing_sampler_.RecordSample(); | 100 smoothing_sampler_.RecordSample(); |
100 content_sampler_.RecordSample(GetFrameTimestamp(next_frame_number_)); | 101 content_sampler_.RecordSample(GetFrameTimestamp(next_frame_number_)); |
| 102 num_frames_pending_++; |
101 return next_frame_number_++; | 103 return next_frame_number_++; |
102 } | 104 } |
103 | 105 |
104 bool VideoCaptureOracle::CompleteCapture(int frame_number, | 106 bool VideoCaptureOracle::CompleteCapture(int frame_number, |
105 bool capture_was_successful, | 107 bool capture_was_successful, |
106 base::TimeTicks* frame_timestamp) { | 108 base::TimeTicks* frame_timestamp) { |
107 // Drop frame if previous frame number is higher. | 109 num_frames_pending_--; |
108 if (last_delivered_frame_number_ > frame_number) { | 110 |
| 111 // Drop frame if previously delivered frame number is higher. |
| 112 if (last_successfully_delivered_frame_number_ > frame_number) { |
109 LOG_IF(WARNING, capture_was_successful) | 113 LOG_IF(WARNING, capture_was_successful) |
110 << "Out of order frame delivery detected (have #" << frame_number | 114 << "Out of order frame delivery detected (have #" << frame_number |
111 << ", last was #" << last_delivered_frame_number_ | 115 << ", last was #" << last_successfully_delivered_frame_number_ |
112 << "). Dropping frame."; | 116 << "). Dropping frame."; |
113 return false; | 117 return false; |
114 } | 118 } |
115 DCHECK_NE(last_delivered_frame_number_, frame_number); | |
116 last_delivered_frame_number_ = frame_number; | |
117 | 119 |
118 if (!capture_was_successful) { | 120 if (!capture_was_successful) { |
119 VLOG(2) << "Capture of frame #" << frame_number << " was not successful."; | 121 VLOG(2) << "Capture of frame #" << frame_number << " was not successful."; |
120 return false; | 122 return false; |
121 } | 123 } |
122 | 124 |
| 125 DCHECK_NE(last_successfully_delivered_frame_number_, frame_number); |
| 126 last_successfully_delivered_frame_number_ = frame_number; |
| 127 |
123 *frame_timestamp = GetFrameTimestamp(frame_number); | 128 *frame_timestamp = GetFrameTimestamp(frame_number); |
124 | 129 |
125 // If enabled, log a measurement of how this frame timestamp has incremented | 130 // If enabled, log a measurement of how this frame timestamp has incremented |
126 // in relation to an ideal increment. | 131 // in relation to an ideal increment. |
127 if (VLOG_IS_ON(2) && frame_number > 0) { | 132 if (VLOG_IS_ON(2) && frame_number > 0) { |
128 const base::TimeDelta delta = | 133 const base::TimeDelta delta = |
129 *frame_timestamp - GetFrameTimestamp(frame_number - 1); | 134 *frame_timestamp - GetFrameTimestamp(frame_number - 1); |
130 if (content_sampler_.HasProposal()) { | 135 if (content_sampler_.HasProposal()) { |
131 const double estimated_frame_rate = | 136 const double estimated_frame_rate = |
132 1000000.0 / content_sampler_.detected_period().InMicroseconds(); | 137 1000000.0 / content_sampler_.detected_period().InMicroseconds(); |
(...skipping 27 matching lines...) Loading... |
160 DCHECK_LT(next_frame_number_ - frame_number, kMaxFrameTimestamps); | 165 DCHECK_LT(next_frame_number_ - frame_number, kMaxFrameTimestamps); |
161 return frame_timestamps_[frame_number % kMaxFrameTimestamps]; | 166 return frame_timestamps_[frame_number % kMaxFrameTimestamps]; |
162 } | 167 } |
163 | 168 |
164 void VideoCaptureOracle::SetFrameTimestamp(int frame_number, | 169 void VideoCaptureOracle::SetFrameTimestamp(int frame_number, |
165 base::TimeTicks timestamp) { | 170 base::TimeTicks timestamp) { |
166 frame_timestamps_[frame_number % kMaxFrameTimestamps] = timestamp; | 171 frame_timestamps_[frame_number % kMaxFrameTimestamps] = timestamp; |
167 } | 172 } |
168 | 173 |
169 } // namespace content | 174 } // namespace content |
OLD | NEW |