| 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...) Expand all 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...) Expand all 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...) Expand all 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 |