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

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 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
11 #include "webrtc/test/frame_generator_capturer.h" 11 #include "webrtc/test/frame_generator_capturer.h"
12 12
13 #include "webrtc/api/video/i420_buffer.h"
13 #include "webrtc/base/criticalsection.h" 14 #include "webrtc/base/criticalsection.h"
14 #include "webrtc/base/platform_thread.h" 15 #include "webrtc/base/platform_thread.h"
16 #include "webrtc/media/base/videoadapter.h"
15 #include "webrtc/system_wrappers/include/clock.h" 17 #include "webrtc/system_wrappers/include/clock.h"
16 #include "webrtc/system_wrappers/include/event_wrapper.h" 18 #include "webrtc/system_wrappers/include/event_wrapper.h"
17 #include "webrtc/system_wrappers/include/sleep.h" 19 #include "webrtc/system_wrappers/include/sleep.h"
18 #include "webrtc/test/frame_generator.h" 20 #include "webrtc/test/frame_generator.h"
19 #include "webrtc/video_send_stream.h" 21 #include "webrtc/video_send_stream.h"
20 22
21 namespace webrtc { 23 namespace webrtc {
22 namespace test { 24 namespace test {
23 25
24 FrameGeneratorCapturer* FrameGeneratorCapturer::Create(int width, 26 FrameGeneratorCapturer* FrameGeneratorCapturer::Create(int width,
25 int height, 27 int height,
26 int target_fps, 28 int target_fps,
27 Clock* clock) { 29 Clock* clock) {
28 FrameGeneratorCapturer* capturer = new FrameGeneratorCapturer( 30 std::unique_ptr<FrameGeneratorCapturer> capturer(new FrameGeneratorCapturer(
29 clock, FrameGenerator::CreateSquareGenerator(width, height), target_fps); 31 clock, FrameGenerator::CreateSquareGenerator(width, height), target_fps));
30 if (!capturer->Init()) { 32 if (!capturer->Init())
31 delete capturer; 33 return nullptr;
32 return NULL;
33 }
34 34
35 return capturer; 35 return capturer.release();
36 } 36 }
37 37
38 FrameGeneratorCapturer* FrameGeneratorCapturer::CreateFromYuvFile( 38 FrameGeneratorCapturer* FrameGeneratorCapturer::CreateFromYuvFile(
39 const std::string& file_name, 39 const std::string& file_name,
40 size_t width, 40 size_t width,
41 size_t height, 41 size_t height,
42 int target_fps, 42 int target_fps,
43 Clock* clock) { 43 Clock* clock) {
44 FrameGeneratorCapturer* capturer = new FrameGeneratorCapturer( 44 std::unique_ptr<FrameGeneratorCapturer> capturer(new FrameGeneratorCapturer(
45 clock, FrameGenerator::CreateFromYuvFile( 45 clock,
46 std::vector<std::string>(1, file_name), width, height, 1), 46 FrameGenerator::CreateFromYuvFile(std::vector<std::string>(1, file_name),
47 target_fps); 47 width, height, 1),
48 if (!capturer->Init()) { 48 target_fps));
49 delete capturer; 49 if (!capturer->Init())
50 return NULL; 50 return nullptr;
51 }
52 51
53 return capturer; 52 return capturer.release();
54 } 53 }
55 54
56 FrameGeneratorCapturer::FrameGeneratorCapturer( 55 FrameGeneratorCapturer::FrameGeneratorCapturer(
57 Clock* clock, 56 Clock* clock,
58 std::unique_ptr<FrameGenerator> frame_generator, 57 std::unique_ptr<FrameGenerator> frame_generator,
59 int target_fps) 58 int target_fps)
60 : clock_(clock), 59 : clock_(clock),
61 sending_(false), 60 sending_(false),
62 sink_(nullptr), 61 sink_(nullptr),
63 sink_wants_observer_(nullptr), 62 sink_wants_observer_(nullptr),
64 tick_(EventTimerWrapper::Create()), 63 tick_(EventTimerWrapper::Create()),
65 thread_(FrameGeneratorCapturer::Run, this, "FrameGeneratorCapturer"), 64 thread_(FrameGeneratorCapturer::Run, this, "FrameGeneratorCapturer"),
66 frame_generator_(std::move(frame_generator)), 65 frame_generator_(std::move(frame_generator)),
67 target_fps_(target_fps), 66 target_fps_(target_fps),
68 first_frame_capture_time_(-1) { 67 first_frame_capture_time_(-1) {
69 RTC_DCHECK(frame_generator_); 68 RTC_DCHECK(frame_generator_);
70 RTC_DCHECK_GT(target_fps, 0); 69 RTC_DCHECK_GT(target_fps, 0);
71 } 70 }
72 71
73 FrameGeneratorCapturer::~FrameGeneratorCapturer() { 72 FrameGeneratorCapturer::~FrameGeneratorCapturer() {
74 Stop(); 73 Stop();
75
76 thread_.Stop(); 74 thread_.Stop();
77 } 75 }
78 76
79 void FrameGeneratorCapturer::SetFakeRotation(VideoRotation rotation) { 77 void FrameGeneratorCapturer::SetFakeRotation(VideoRotation rotation) {
80 rtc::CritScope cs(&lock_); 78 rtc::CritScope cs(&lock_);
81 fake_rotation_ = rotation; 79 fake_rotation_ = rotation;
82 } 80 }
83 81
84 bool FrameGeneratorCapturer::Init() { 82 bool FrameGeneratorCapturer::Init() {
85 // This check is added because frame_generator_ might be file based and should 83 // This check is added because frame_generator_ might be file based and should
86 // not crash because a file moved. 84 // not crash because a file moved.
87 if (frame_generator_.get() == NULL) 85 if (frame_generator_.get() == nullptr)
88 return false; 86 return false;
89 87
90 if (!tick_->StartTimer(true, 1000 / target_fps_)) 88 {
91 return false; 89 rtc::CritScope cs(&lock_);
90 RTC_DCHECK(tick_->StartTimer(false, 1000 / target_fps_));
91 }
92 thread_.Start(); 92 thread_.Start();
93 thread_.SetPriority(rtc::kHighPriority); 93 thread_.SetPriority(rtc::kHighPriority);
94 return true; 94 return true;
95 } 95 }
96 96
97 bool FrameGeneratorCapturer::Run(void* obj) { 97 bool FrameGeneratorCapturer::Run(void* obj) {
98 static_cast<FrameGeneratorCapturer*>(obj)->InsertFrame(); 98 static_cast<FrameGeneratorCapturer*>(obj)->InsertFrame();
99 return true; 99 return true;
100 } 100 }
101 101
102 void FrameGeneratorCapturer::InsertFrame() { 102 void FrameGeneratorCapturer::InsertFrame() {
103 int64_t start_tims_ms = rtc::TimeMillis();
104 int64_t sleep_time_ms;
103 { 105 {
104 rtc::CritScope cs(&lock_); 106 rtc::CritScope cs(&lock_);
105 if (sending_) { 107 if (sending_) {
106 VideoFrame* frame = frame_generator_->NextFrame(); 108 VideoFrame* frame = frame_generator_->NextFrame();
107 frame->set_ntp_time_ms(clock_->CurrentNtpInMilliseconds()); 109 frame->set_ntp_time_ms(clock_->CurrentNtpInMilliseconds());
108 frame->set_rotation(fake_rotation_); 110 frame->set_rotation(fake_rotation_);
109 if (first_frame_capture_time_ == -1) { 111 if (first_frame_capture_time_ == -1) {
110 first_frame_capture_time_ = frame->ntp_time_ms(); 112 first_frame_capture_time_ = frame->ntp_time_ms();
111 } 113 }
112 if (sink_) 114
113 sink_->OnFrame(*frame); 115 if (sink_) {
116 rtc::Optional<VideoFrame> out_frame = AdaptFrame(*frame);
117 if (out_frame)
118 sink_->OnFrame(*out_frame);
119 }
120 }
121
122 if (wanted_fps_) {
123 sleep_time_ms = 1000 / *wanted_fps_;
124 } else {
125 sleep_time_ms = 1000 / target_fps_;
114 } 126 }
115 } 127 }
116 tick_->Wait(WEBRTC_EVENT_INFINITE); 128
129 int64_t correction_delta = rtc::TimeMillis() - start_tims_ms;
130 sleep_time_ms -= correction_delta;
131 if (sleep_time_ms > 0)
132 tick_->Wait(sleep_time_ms);
117 } 133 }
118 134
119 void FrameGeneratorCapturer::Start() { 135 void FrameGeneratorCapturer::Start() {
120 rtc::CritScope cs(&lock_); 136 rtc::CritScope cs(&lock_);
121 sending_ = true; 137 sending_ = true;
122 } 138 }
123 139
124 void FrameGeneratorCapturer::Stop() { 140 void FrameGeneratorCapturer::Stop() {
125 rtc::CritScope cs(&lock_); 141 rtc::CritScope cs(&lock_);
126 sending_ = false; 142 sending_ = false;
(...skipping 11 matching lines...) Expand all
138 } 154 }
139 155
140 void FrameGeneratorCapturer::AddOrUpdateSink( 156 void FrameGeneratorCapturer::AddOrUpdateSink(
141 rtc::VideoSinkInterface<VideoFrame>* sink, 157 rtc::VideoSinkInterface<VideoFrame>* sink,
142 const rtc::VideoSinkWants& wants) { 158 const rtc::VideoSinkWants& wants) {
143 rtc::CritScope cs(&lock_); 159 rtc::CritScope cs(&lock_);
144 RTC_CHECK(!sink_ || sink_ == sink); 160 RTC_CHECK(!sink_ || sink_ == sink);
145 sink_ = sink; 161 sink_ = sink;
146 if (sink_wants_observer_) 162 if (sink_wants_observer_)
147 sink_wants_observer_->OnSinkWantsChanged(sink, wants); 163 sink_wants_observer_->OnSinkWantsChanged(sink, wants);
164
165 // Handle framerate within this class, just pass on resolution for possible
166 // adaptation.
167 rtc::VideoSinkWants resolution_wants = wants;
168 resolution_wants.max_framerate_fps = std::numeric_limits<int>::max();
169 VideoCapturer::AddOrUpdateSink(sink, resolution_wants);
170
171 if (wants.max_framerate_fps < target_fps_)
172 wanted_fps_.emplace(wants.max_framerate_fps);
148 } 173 }
149 174
150 void FrameGeneratorCapturer::RemoveSink( 175 void FrameGeneratorCapturer::RemoveSink(
151 rtc::VideoSinkInterface<VideoFrame>* sink) { 176 rtc::VideoSinkInterface<VideoFrame>* sink) {
152 rtc::CritScope cs(&lock_); 177 rtc::CritScope cs(&lock_);
153 RTC_CHECK(sink_ == sink); 178 RTC_CHECK(sink_ == sink);
154 sink_ = nullptr; 179 sink_ = nullptr;
155 } 180 }
156 181
157 void FrameGeneratorCapturer::ForceFrame() { 182 void FrameGeneratorCapturer::ForceFrame() {
158 tick_->Set(); 183 tick_->Set();
159 } 184 }
160 } // test 185 } // test
161 } // webrtc 186 } // webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698