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

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

Issue 2923993002: Revert of Periodically update codec bit/frame rate settings. (Closed)
Patch Set: Created 3 years, 6 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
« no previous file with comments | « webrtc/test/fake_encoder.h ('k') | webrtc/video/video_send_stream_tests.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/fake_encoder.h" 11 #include "webrtc/test/fake_encoder.h"
12 12
13 #include <string.h> 13 #include <string.h>
14 14
15 #include <algorithm> 15 #include <algorithm>
16 #include <memory> 16 #include <memory>
17 17
18 #include "webrtc/base/checks.h" 18 #include "webrtc/base/checks.h"
19 #include "webrtc/common_types.h" 19 #include "webrtc/common_types.h"
20 #include "webrtc/modules/video_coding/include/video_codec_interface.h" 20 #include "webrtc/modules/video_coding/include/video_codec_interface.h"
21 #include "webrtc/system_wrappers/include/sleep.h" 21 #include "webrtc/system_wrappers/include/sleep.h"
22 #include "webrtc/test/gtest.h" 22 #include "webrtc/test/gtest.h"
23 23
24 namespace webrtc { 24 namespace webrtc {
25 namespace test { 25 namespace test {
26 26
27 const int kKeyframeSizeFactor = 10;
28
29 FakeEncoder::FakeEncoder(Clock* clock) 27 FakeEncoder::FakeEncoder(Clock* clock)
30 : clock_(clock), 28 : clock_(clock),
31 callback_(nullptr), 29 callback_(nullptr),
32 configured_input_framerate_(-1),
33 max_target_bitrate_kbps_(-1), 30 max_target_bitrate_kbps_(-1),
34 pending_keyframe_(true), 31 last_encode_time_ms_(0) {
35 debt_bytes_(0) {
36 // Generate some arbitrary not-all-zero data 32 // Generate some arbitrary not-all-zero data
37 for (size_t i = 0; i < sizeof(encoded_buffer_); ++i) { 33 for (size_t i = 0; i < sizeof(encoded_buffer_); ++i) {
38 encoded_buffer_[i] = static_cast<uint8_t>(i); 34 encoded_buffer_[i] = static_cast<uint8_t>(i);
39 } 35 }
40 } 36 }
41 37
42 void FakeEncoder::SetMaxBitrate(int max_kbps) { 38 void FakeEncoder::SetMaxBitrate(int max_kbps) {
43 RTC_DCHECK_GE(max_kbps, -1); // max_kbps == -1 disables it. 39 RTC_DCHECK_GE(max_kbps, -1); // max_kbps == -1 disables it.
44 rtc::CritScope cs(&crit_sect_); 40 rtc::CritScope cs(&crit_sect_);
45 max_target_bitrate_kbps_ = max_kbps; 41 max_target_bitrate_kbps_ = max_kbps;
46 } 42 }
47 43
48 int32_t FakeEncoder::InitEncode(const VideoCodec* config, 44 int32_t FakeEncoder::InitEncode(const VideoCodec* config,
49 int32_t number_of_cores, 45 int32_t number_of_cores,
50 size_t max_payload_size) { 46 size_t max_payload_size) {
51 rtc::CritScope cs(&crit_sect_); 47 rtc::CritScope cs(&crit_sect_);
52 config_ = *config; 48 config_ = *config;
53 target_bitrate_.SetBitrate(0, 0, config_.startBitrate * 1000); 49 target_bitrate_.SetBitrate(0, 0, config_.startBitrate * 1000);
54 configured_input_framerate_ = config_.maxFramerate;
55 pending_keyframe_ = true;
56 return 0; 50 return 0;
57 } 51 }
58 52
59 int32_t FakeEncoder::Encode(const VideoFrame& input_image, 53 int32_t FakeEncoder::Encode(const VideoFrame& input_image,
60 const CodecSpecificInfo* codec_specific_info, 54 const CodecSpecificInfo* codec_specific_info,
61 const std::vector<FrameType>* frame_types) { 55 const std::vector<FrameType>* frame_types) {
62 unsigned char max_framerate; 56 unsigned char max_framerate;
63 unsigned char num_simulcast_streams; 57 unsigned char num_simulcast_streams;
64 SimulcastStream simulcast_streams[kMaxSimulcastStreams]; 58 SimulcastStream simulcast_streams[kMaxSimulcastStreams];
65 EncodedImageCallback* callback; 59 EncodedImageCallback* callback;
66 uint32_t target_bitrate_sum_kbps; 60 uint32_t target_bitrate_sum_kbps;
67 int max_target_bitrate_kbps; 61 int max_target_bitrate_kbps;
62 int64_t last_encode_time_ms;
68 size_t num_encoded_bytes; 63 size_t num_encoded_bytes;
69 int framerate;
70 VideoCodecMode mode; 64 VideoCodecMode mode;
71 bool keyframe;
72 { 65 {
73 rtc::CritScope cs(&crit_sect_); 66 rtc::CritScope cs(&crit_sect_);
74 max_framerate = config_.maxFramerate; 67 max_framerate = config_.maxFramerate;
75 num_simulcast_streams = config_.numberOfSimulcastStreams; 68 num_simulcast_streams = config_.numberOfSimulcastStreams;
76 for (int i = 0; i < num_simulcast_streams; ++i) { 69 for (int i = 0; i < num_simulcast_streams; ++i) {
77 simulcast_streams[i] = config_.simulcastStream[i]; 70 simulcast_streams[i] = config_.simulcastStream[i];
78 } 71 }
79 callback = callback_; 72 callback = callback_;
80 target_bitrate_sum_kbps = target_bitrate_.get_sum_kbps(); 73 target_bitrate_sum_kbps = target_bitrate_.get_sum_kbps();
81 max_target_bitrate_kbps = max_target_bitrate_kbps_; 74 max_target_bitrate_kbps = max_target_bitrate_kbps_;
75 last_encode_time_ms = last_encode_time_ms_;
82 num_encoded_bytes = sizeof(encoded_buffer_); 76 num_encoded_bytes = sizeof(encoded_buffer_);
83 mode = config_.mode; 77 mode = config_.mode;
84 if (configured_input_framerate_ > 0) {
85 framerate = configured_input_framerate_;
86 } else {
87 framerate = max_framerate;
88 }
89 keyframe = pending_keyframe_;
90 pending_keyframe_ = false;
91 } 78 }
92 79
93 for (FrameType frame_type : *frame_types) { 80 int64_t time_now_ms = clock_->TimeInMilliseconds();
94 if (frame_type == kVideoFrameKey) { 81 const bool first_encode = (last_encode_time_ms == 0);
95 keyframe = true; 82 RTC_DCHECK_GT(max_framerate, 0);
96 break; 83 int64_t time_since_last_encode_ms = 1000 / max_framerate;
97 } 84 if (!first_encode) {
85 // For all frames but the first we can estimate the display time by looking
86 // at the display time of the previous frame.
87 time_since_last_encode_ms = time_now_ms - last_encode_time_ms;
88 }
89 if (time_since_last_encode_ms > 3 * 1000 / max_framerate) {
90 // Rudimentary check to make sure we don't widely overshoot bitrate target
91 // when resuming encoding after a suspension.
92 time_since_last_encode_ms = 3 * 1000 / max_framerate;
98 } 93 }
99 94
100 RTC_DCHECK_GT(max_framerate, 0); 95 size_t bits_available =
96 static_cast<size_t>(target_bitrate_sum_kbps * time_since_last_encode_ms);
97 size_t min_bits = static_cast<size_t>(simulcast_streams[0].minBitrate *
98 time_since_last_encode_ms);
101 99
102 size_t bitrate = target_bitrate_sum_kbps; 100 if (bits_available < min_bits)
103 bitrate = 101 bits_available = min_bits;
104 std::max(bitrate, static_cast<size_t>(simulcast_streams[0].minBitrate)); 102 size_t max_bits =
105 if (max_target_bitrate_kbps > 0) 103 static_cast<size_t>(max_target_bitrate_kbps * time_since_last_encode_ms);
106 bitrate = std::min(bitrate, static_cast<size_t>(max_target_bitrate_kbps)); 104 if (max_bits > 0 && max_bits < bits_available)
105 bits_available = max_bits;
107 106
108 size_t bits_available = target_bitrate_sum_kbps * 1000 / framerate; 107 {
108 rtc::CritScope cs(&crit_sect_);
109 last_encode_time_ms_ = time_now_ms;
110 }
109 111
110 RTC_DCHECK_GT(num_simulcast_streams, 0); 112 RTC_DCHECK_GT(num_simulcast_streams, 0);
111 for (unsigned char i = 0; i < num_simulcast_streams; ++i) { 113 for (unsigned char i = 0; i < num_simulcast_streams; ++i) {
112 CodecSpecificInfo specifics; 114 CodecSpecificInfo specifics;
113 memset(&specifics, 0, sizeof(specifics)); 115 memset(&specifics, 0, sizeof(specifics));
114 specifics.codecType = kVideoCodecGeneric; 116 specifics.codecType = kVideoCodecGeneric;
115 specifics.codecSpecific.generic.simulcast_idx = i; 117 specifics.codecSpecific.generic.simulcast_idx = i;
116 size_t min_stream_bits = static_cast<size_t>( 118 size_t min_stream_bits = static_cast<size_t>(
117 (simulcast_streams[i].minBitrate * 1000) / framerate); 119 simulcast_streams[i].minBitrate * time_since_last_encode_ms);
118 size_t max_stream_bits = static_cast<size_t>( 120 size_t max_stream_bits = static_cast<size_t>(
119 (simulcast_streams[i].maxBitrate * 1000) / framerate); 121 simulcast_streams[i].maxBitrate * time_since_last_encode_ms);
120 size_t stream_bits = (bits_available > max_stream_bits) ? max_stream_bits : 122 size_t stream_bits = (bits_available > max_stream_bits) ? max_stream_bits :
121 bits_available; 123 bits_available;
122 size_t stream_bytes = (stream_bits + 7) / 8; 124 size_t stream_bytes = (stream_bits + 7) / 8;
123 if (keyframe) { 125 if (first_encode) {
124 // The first frame is a key frame and should be larger. 126 // The first frame is a key frame and should be larger.
125 // Store the overshoot bytes and distribute them over the coming frames, 127 // TODO(holmer): The FakeEncoder should store the bits_available between
126 // so that we on average meet the bitrate target. 128 // encodes so that it can compensate for oversized frames.
127 debt_bytes_ += (kKeyframeSizeFactor - 1) * stream_bytes; 129 stream_bytes *= 10;
128 stream_bytes *= kKeyframeSizeFactor;
129 } else {
130 if (debt_bytes_ > 0) {
131 // Pay at most half of the frame size for old debts.
132 size_t payment_size = std::min(stream_bytes / 2, debt_bytes_);
133 debt_bytes_ -= payment_size;
134 stream_bytes -= payment_size;
135 }
136 } 130 }
137
138 if (stream_bytes > num_encoded_bytes) 131 if (stream_bytes > num_encoded_bytes)
139 stream_bytes = num_encoded_bytes; 132 stream_bytes = num_encoded_bytes;
140 133
141 // Always encode something on the first frame. 134 // Always encode something on the first frame.
142 if (min_stream_bits > bits_available && i > 0) 135 if (min_stream_bits > bits_available && i > 0)
143 continue; 136 continue;
144 137
145 std::unique_ptr<uint8_t[]> encoded_buffer(new uint8_t[num_encoded_bytes]); 138 std::unique_ptr<uint8_t[]> encoded_buffer(new uint8_t[num_encoded_bytes]);
146 memcpy(encoded_buffer.get(), encoded_buffer_, num_encoded_bytes); 139 memcpy(encoded_buffer.get(), encoded_buffer_, num_encoded_bytes);
147 EncodedImage encoded(encoded_buffer.get(), stream_bytes, num_encoded_bytes); 140 EncodedImage encoded(encoded_buffer.get(), stream_bytes, num_encoded_bytes);
(...skipping 27 matching lines...) Expand all
175 int32_t FakeEncoder::Release() { return 0; } 168 int32_t FakeEncoder::Release() { return 0; }
176 169
177 int32_t FakeEncoder::SetChannelParameters(uint32_t packet_loss, int64_t rtt) { 170 int32_t FakeEncoder::SetChannelParameters(uint32_t packet_loss, int64_t rtt) {
178 return 0; 171 return 0;
179 } 172 }
180 173
181 int32_t FakeEncoder::SetRateAllocation(const BitrateAllocation& rate_allocation, 174 int32_t FakeEncoder::SetRateAllocation(const BitrateAllocation& rate_allocation,
182 uint32_t framerate) { 175 uint32_t framerate) {
183 rtc::CritScope cs(&crit_sect_); 176 rtc::CritScope cs(&crit_sect_);
184 target_bitrate_ = rate_allocation; 177 target_bitrate_ = rate_allocation;
185 configured_input_framerate_ = framerate;
186 return 0; 178 return 0;
187 } 179 }
188 180
189 const char* FakeEncoder::kImplementationName = "fake_encoder"; 181 const char* FakeEncoder::kImplementationName = "fake_encoder";
190 const char* FakeEncoder::ImplementationName() const { 182 const char* FakeEncoder::ImplementationName() const {
191 return kImplementationName; 183 return kImplementationName;
192 } 184 }
193 185
194 int FakeEncoder::GetConfiguredInputFramerate() const {
195 rtc::CritScope cs(&crit_sect_);
196 return configured_input_framerate_;
197 }
198
199 FakeH264Encoder::FakeH264Encoder(Clock* clock) 186 FakeH264Encoder::FakeH264Encoder(Clock* clock)
200 : FakeEncoder(clock), callback_(nullptr), idr_counter_(0) { 187 : FakeEncoder(clock), callback_(nullptr), idr_counter_(0) {
201 FakeEncoder::RegisterEncodeCompleteCallback(this); 188 FakeEncoder::RegisterEncodeCompleteCallback(this);
202 } 189 }
203 190
204 int32_t FakeH264Encoder::RegisterEncodeCompleteCallback( 191 int32_t FakeH264Encoder::RegisterEncodeCompleteCallback(
205 EncodedImageCallback* callback) { 192 EncodedImageCallback* callback) {
206 rtc::CritScope cs(&local_crit_sect_); 193 rtc::CritScope cs(&local_crit_sect_);
207 callback_ = callback; 194 callback_ = callback;
208 return 0; 195 return 0;
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); 355 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_);
369 356
370 queue1_.reset(); 357 queue1_.reset();
371 queue2_.reset(); 358 queue2_.reset();
372 359
373 return FakeH264Encoder::Release(); 360 return FakeH264Encoder::Release();
374 } 361 }
375 362
376 } // namespace test 363 } // namespace test
377 } // namespace webrtc 364 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/test/fake_encoder.h ('k') | webrtc/video/video_send_stream_tests.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698