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

Side by Side Diff: webrtc/test/frame_generator_capturer.cc

Issue 2716643002: Add framerate to VideoSinkWants and ability to signal on overuse (Closed)
Patch Set: Addressed comments, fixed missing include Created 3 years, 9 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 19 matching lines...) Expand all
30 // Repeats in |repeat_interval_ms|. One-time if |repeat_interval_ms| == 0. 30 // Repeats in |repeat_interval_ms|. One-time if |repeat_interval_ms| == 0.
31 InsertFrameTask( 31 InsertFrameTask(
32 webrtc::test::FrameGeneratorCapturer* frame_generator_capturer, 32 webrtc::test::FrameGeneratorCapturer* frame_generator_capturer,
33 uint32_t repeat_interval_ms) 33 uint32_t repeat_interval_ms)
34 : frame_generator_capturer_(frame_generator_capturer), 34 : frame_generator_capturer_(frame_generator_capturer),
35 repeat_interval_ms_(repeat_interval_ms), 35 repeat_interval_ms_(repeat_interval_ms),
36 intended_run_time_ms_(-1) {} 36 intended_run_time_ms_(-1) {}
37 37
38 private: 38 private:
39 bool Run() override { 39 bool Run() override {
40 bool task_completed = true;
40 if (repeat_interval_ms_ > 0) { 41 if (repeat_interval_ms_ > 0) {
41 int64_t delay_ms; 42 // This is not a one-off frame. Check if the frame interval for this
42 int64_t time_now_ms = rtc::TimeMillis(); 43 // task queue is the same same as the current configures frame rate.
stefan-webrtc 2017/03/21 15:37:36 configured
sprang_webrtc 2017/03/21 15:59:18 Done.
43 if (intended_run_time_ms_ > 0) { 44 uint32_t current_interval_ms =
44 delay_ms = time_now_ms - intended_run_time_ms_; 45 1000 / frame_generator_capturer_->GetCurrentConfiguredFramerate();
46 if (repeat_interval_ms_ != current_interval_ms) {
47 // Frame rate has changed since task was started, create a new instance.
48 rtc::TaskQueue::Current()->PostDelayedTask(
49 std::unique_ptr<rtc::QueuedTask>(new InsertFrameTask(
50 frame_generator_capturer_, current_interval_ms)),
51 current_interval_ms);
45 } else { 52 } else {
46 delay_ms = 0; 53 // Schedule the next frame capture event to happen at approximately the
47 intended_run_time_ms_ = time_now_ms; 54 // correct absolute time point.
48 } 55 int64_t delay_ms;
49 intended_run_time_ms_ += repeat_interval_ms_; 56 int64_t time_now_ms = rtc::TimeMillis();
50 if (delay_ms < repeat_interval_ms_) { 57 if (intended_run_time_ms_ > 0) {
51 rtc::TaskQueue::Current()->PostDelayedTask( 58 delay_ms = time_now_ms - intended_run_time_ms_;
52 std::unique_ptr<rtc::QueuedTask>(this), 59 } else {
53 repeat_interval_ms_ - delay_ms); 60 delay_ms = 0;
54 } else { 61 intended_run_time_ms_ = time_now_ms;
55 rtc::TaskQueue::Current()->PostDelayedTask( 62 }
56 std::unique_ptr<rtc::QueuedTask>(this), 0); 63 intended_run_time_ms_ += repeat_interval_ms_;
57 LOG(LS_ERROR) 64 if (delay_ms < repeat_interval_ms_) {
58 << "Frame Generator Capturer can't keep up with requested fps"; 65 rtc::TaskQueue::Current()->PostDelayedTask(
66 std::unique_ptr<rtc::QueuedTask>(this),
67 repeat_interval_ms_ - delay_ms);
68 } else {
69 rtc::TaskQueue::Current()->PostDelayedTask(
70 std::unique_ptr<rtc::QueuedTask>(this), 0);
71 LOG(LS_ERROR)
72 << "Frame Generator Capturer can't keep up with requested fps";
73 }
74 // Repost of this instance, make sure it is not deleted.
75 task_completed = false;
59 } 76 }
60 } 77 }
61 frame_generator_capturer_->InsertFrame(); 78 frame_generator_capturer_->InsertFrame();
62 // Task should be deleted only if it's not repeating. 79 // Task should be deleted only if it's not repeating.
63 return repeat_interval_ms_ == 0; 80 return task_completed;
64 } 81 }
65 82
66 webrtc::test::FrameGeneratorCapturer* const frame_generator_capturer_; 83 webrtc::test::FrameGeneratorCapturer* const frame_generator_capturer_;
67 const uint32_t repeat_interval_ms_; 84 const uint32_t repeat_interval_ms_;
68 int64_t intended_run_time_ms_; 85 int64_t intended_run_time_ms_;
69 }; 86 };
70 87
71 FrameGeneratorCapturer* FrameGeneratorCapturer::Create(int width, 88 FrameGeneratorCapturer* FrameGeneratorCapturer::Create(int width,
72 int height, 89 int height,
73 int target_fps, 90 int target_fps,
74 Clock* clock) { 91 Clock* clock) {
75 FrameGeneratorCapturer* capturer = new FrameGeneratorCapturer( 92 std::unique_ptr<FrameGeneratorCapturer> capturer(new FrameGeneratorCapturer(
76 clock, FrameGenerator::CreateSquareGenerator(width, height), target_fps); 93 clock, FrameGenerator::CreateSquareGenerator(width, height), target_fps));
77 if (!capturer->Init()) { 94 if (!capturer->Init())
78 delete capturer; 95 return nullptr;
79 return NULL;
80 }
81 96
82 return capturer; 97 return capturer.release();
83 } 98 }
84 99
85 FrameGeneratorCapturer* FrameGeneratorCapturer::CreateFromYuvFile( 100 FrameGeneratorCapturer* FrameGeneratorCapturer::CreateFromYuvFile(
86 const std::string& file_name, 101 const std::string& file_name,
87 size_t width, 102 size_t width,
88 size_t height, 103 size_t height,
89 int target_fps, 104 int target_fps,
90 Clock* clock) { 105 Clock* clock) {
91 FrameGeneratorCapturer* capturer = new FrameGeneratorCapturer( 106 std::unique_ptr<FrameGeneratorCapturer> capturer(new FrameGeneratorCapturer(
92 clock, FrameGenerator::CreateFromYuvFile( 107 clock,
93 std::vector<std::string>(1, file_name), width, height, 1), 108 FrameGenerator::CreateFromYuvFile(std::vector<std::string>(1, file_name),
94 target_fps); 109 width, height, 1),
95 if (!capturer->Init()) { 110 target_fps));
96 delete capturer; 111 if (!capturer->Init())
97 return NULL; 112 return nullptr;
98 }
99 113
100 return capturer; 114 return capturer.release();
101 } 115 }
102 116
103 FrameGeneratorCapturer::FrameGeneratorCapturer( 117 FrameGeneratorCapturer::FrameGeneratorCapturer(
104 Clock* clock, 118 Clock* clock,
105 std::unique_ptr<FrameGenerator> frame_generator, 119 std::unique_ptr<FrameGenerator> frame_generator,
106 int target_fps) 120 int target_fps)
107 : clock_(clock), 121 : clock_(clock),
108 sending_(false), 122 sending_(false),
109 sink_(nullptr), 123 sink_(nullptr),
110 sink_wants_observer_(nullptr), 124 sink_wants_observer_(nullptr),
(...skipping 11 matching lines...) Expand all
122 } 136 }
123 137
124 void FrameGeneratorCapturer::SetFakeRotation(VideoRotation rotation) { 138 void FrameGeneratorCapturer::SetFakeRotation(VideoRotation rotation) {
125 rtc::CritScope cs(&lock_); 139 rtc::CritScope cs(&lock_);
126 fake_rotation_ = rotation; 140 fake_rotation_ = rotation;
127 } 141 }
128 142
129 bool FrameGeneratorCapturer::Init() { 143 bool FrameGeneratorCapturer::Init() {
130 // This check is added because frame_generator_ might be file based and should 144 // This check is added because frame_generator_ might be file based and should
131 // not crash because a file moved. 145 // not crash because a file moved.
132 if (frame_generator_.get() == NULL) 146 if (frame_generator_.get() == nullptr)
133 return false; 147 return false;
134 148
149 int framerate_fps = GetCurrentConfiguredFramerate();
135 task_queue_.PostDelayedTask( 150 task_queue_.PostDelayedTask(
136 std::unique_ptr<rtc::QueuedTask>( 151 std::unique_ptr<rtc::QueuedTask>(
137 new InsertFrameTask(this, 1000 / target_fps_)), 152 new InsertFrameTask(this, 1000 / framerate_fps)),
138 1000 / target_fps_); 153 1000 / framerate_fps);
139 154
140 return true; 155 return true;
141 } 156 }
142 157
143 void FrameGeneratorCapturer::InsertFrame() { 158 void FrameGeneratorCapturer::InsertFrame() {
144 { 159 rtc::CritScope cs(&lock_);
145 rtc::CritScope cs(&lock_); 160 if (sending_) {
146 if (sending_) { 161 VideoFrame* frame = frame_generator_->NextFrame();
147 VideoFrame* frame = frame_generator_->NextFrame(); 162 frame->set_ntp_time_ms(clock_->CurrentNtpInMilliseconds());
148 frame->set_ntp_time_ms(clock_->CurrentNtpInMilliseconds()); 163 frame->set_rotation(fake_rotation_);
149 frame->set_rotation(fake_rotation_); 164 if (first_frame_capture_time_ == -1) {
150 if (first_frame_capture_time_ == -1) { 165 first_frame_capture_time_ = frame->ntp_time_ms();
151 first_frame_capture_time_ = frame->ntp_time_ms(); 166 }
152 } 167
153 if (sink_) 168 if (sink_) {
154 sink_->OnFrame(*frame); 169 rtc::Optional<VideoFrame> out_frame = AdaptFrame(*frame);
170 if (out_frame)
171 sink_->OnFrame(*out_frame);
155 } 172 }
156 } 173 }
157 } 174 }
158 175
159 void FrameGeneratorCapturer::Start() { 176 void FrameGeneratorCapturer::Start() {
160 rtc::CritScope cs(&lock_); 177 rtc::CritScope cs(&lock_);
161 sending_ = true; 178 sending_ = true;
162 } 179 }
163 180
164 void FrameGeneratorCapturer::Stop() { 181 void FrameGeneratorCapturer::Stop() {
(...skipping 13 matching lines...) Expand all
178 } 195 }
179 196
180 void FrameGeneratorCapturer::AddOrUpdateSink( 197 void FrameGeneratorCapturer::AddOrUpdateSink(
181 rtc::VideoSinkInterface<VideoFrame>* sink, 198 rtc::VideoSinkInterface<VideoFrame>* sink,
182 const rtc::VideoSinkWants& wants) { 199 const rtc::VideoSinkWants& wants) {
183 rtc::CritScope cs(&lock_); 200 rtc::CritScope cs(&lock_);
184 RTC_CHECK(!sink_ || sink_ == sink); 201 RTC_CHECK(!sink_ || sink_ == sink);
185 sink_ = sink; 202 sink_ = sink;
186 if (sink_wants_observer_) 203 if (sink_wants_observer_)
187 sink_wants_observer_->OnSinkWantsChanged(sink, wants); 204 sink_wants_observer_->OnSinkWantsChanged(sink, wants);
205
206 // Handle framerate within this class, just pass on resolution for possible
207 // adaptation.
208 rtc::VideoSinkWants resolution_wants = wants;
209 resolution_wants.max_framerate_fps = std::numeric_limits<int>::max();
210 VideoCapturer::AddOrUpdateSink(sink, resolution_wants);
211
212 // Ignore any requests for framerate higher than initially configured.
213 if (wants.max_framerate_fps < target_fps_) {
214 wanted_fps_.emplace(wants.max_framerate_fps);
215 } else {
216 wanted_fps_.reset();
217 }
188 } 218 }
189 219
190 void FrameGeneratorCapturer::RemoveSink( 220 void FrameGeneratorCapturer::RemoveSink(
191 rtc::VideoSinkInterface<VideoFrame>* sink) { 221 rtc::VideoSinkInterface<VideoFrame>* sink) {
192 rtc::CritScope cs(&lock_); 222 rtc::CritScope cs(&lock_);
193 RTC_CHECK(sink_ == sink); 223 RTC_CHECK(sink_ == sink);
194 sink_ = nullptr; 224 sink_ = nullptr;
195 } 225 }
196 226
197 void FrameGeneratorCapturer::ForceFrame() { 227 void FrameGeneratorCapturer::ForceFrame() {
198 // One-time non-repeating task, 228 // One-time non-repeating task,
199 // therefore repeat_interval_ms is 0 in InsertFrameTask() 229 // therefore repeat_interval_ms is 0 in InsertFrameTask()
200 task_queue_.PostTask( 230 task_queue_.PostTask(
201 std::unique_ptr<rtc::QueuedTask>(new InsertFrameTask(this, 0))); 231 std::unique_ptr<rtc::QueuedTask>(new InsertFrameTask(this, 0)));
202 } 232 }
203 233
234 int FrameGeneratorCapturer::GetCurrentConfiguredFramerate() {
235 rtc::CritScope cs(&lock_);
236 if (wanted_fps_ && *wanted_fps_ < target_fps_)
237 return *wanted_fps_;
238 return target_fps_;
239 }
240
204 } // namespace test 241 } // namespace test
205 } // namespace webrtc 242 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698