OLD | NEW |
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> |
| 14 |
13 #include <algorithm> | 15 #include <algorithm> |
| 16 #include <memory> |
14 | 17 |
15 #include "webrtc/base/atomicops.h" | 18 #include "webrtc/base/atomicops.h" |
16 #include "webrtc/base/checks.h" | 19 #include "webrtc/base/checks.h" |
| 20 #include "webrtc/common_types.h" |
17 #include "webrtc/modules/video_coding/include/video_codec_interface.h" | 21 #include "webrtc/modules/video_coding/include/video_codec_interface.h" |
18 #include "webrtc/system_wrappers/include/sleep.h" | 22 #include "webrtc/system_wrappers/include/sleep.h" |
19 #include "webrtc/test/gtest.h" | 23 #include "webrtc/test/gtest.h" |
20 | 24 |
21 namespace webrtc { | 25 namespace webrtc { |
22 namespace test { | 26 namespace test { |
23 | 27 |
24 FakeEncoder::FakeEncoder(Clock* clock) | 28 FakeEncoder::FakeEncoder(Clock* clock) |
25 : clock_(clock), | 29 : clock_(clock), |
26 callback_(NULL), | 30 callback_(nullptr), |
27 max_target_bitrate_kbps_(-1), | 31 max_target_bitrate_kbps_(-1), |
28 last_encode_time_ms_(0) { | 32 last_encode_time_ms_(0) { |
29 // Generate some arbitrary not-all-zero data | 33 // Generate some arbitrary not-all-zero data |
30 for (size_t i = 0; i < sizeof(encoded_buffer_); ++i) { | 34 for (size_t i = 0; i < sizeof(encoded_buffer_); ++i) { |
31 encoded_buffer_[i] = static_cast<uint8_t>(i); | 35 encoded_buffer_[i] = static_cast<uint8_t>(i); |
32 } | 36 } |
33 } | 37 } |
34 | 38 |
35 FakeEncoder::~FakeEncoder() {} | 39 FakeEncoder::~FakeEncoder() {} |
36 | 40 |
37 void FakeEncoder::SetMaxBitrate(int max_kbps) { | 41 void FakeEncoder::SetMaxBitrate(int max_kbps) { |
38 RTC_DCHECK_GE(max_kbps, -1); // max_kbps == -1 disables it. | 42 RTC_DCHECK_GE(max_kbps, -1); // max_kbps == -1 disables it. |
| 43 rtc::CritScope cs(&crit_sect_); |
39 max_target_bitrate_kbps_ = max_kbps; | 44 max_target_bitrate_kbps_ = max_kbps; |
40 } | 45 } |
41 | 46 |
42 int32_t FakeEncoder::InitEncode(const VideoCodec* config, | 47 int32_t FakeEncoder::InitEncode(const VideoCodec* config, |
43 int32_t number_of_cores, | 48 int32_t number_of_cores, |
44 size_t max_payload_size) { | 49 size_t max_payload_size) { |
| 50 rtc::CritScope cs(&crit_sect_); |
45 config_ = *config; | 51 config_ = *config; |
46 target_bitrate_.SetBitrate(0, 0, config_.startBitrate * 1000); | 52 target_bitrate_.SetBitrate(0, 0, config_.startBitrate * 1000); |
47 return 0; | 53 return 0; |
48 } | 54 } |
49 | 55 |
50 int32_t FakeEncoder::Encode(const VideoFrame& input_image, | 56 int32_t FakeEncoder::Encode(const VideoFrame& input_image, |
51 const CodecSpecificInfo* codec_specific_info, | 57 const CodecSpecificInfo* codec_specific_info, |
52 const std::vector<FrameType>* frame_types) { | 58 const std::vector<FrameType>* frame_types) { |
53 RTC_DCHECK_GT(config_.maxFramerate, 0); | 59 unsigned char max_framerate; |
54 int64_t time_since_last_encode_ms = 1000 / config_.maxFramerate; | 60 unsigned char num_simulcast_streams; |
| 61 SimulcastStream simulcast_streams[kMaxSimulcastStreams]; |
| 62 EncodedImageCallback* callback; |
| 63 uint32_t target_bitrate_sum_kbps; |
| 64 int max_target_bitrate_kbps; |
| 65 int64_t last_encode_time_ms; |
| 66 size_t num_encoded_bytes; |
| 67 { |
| 68 rtc::CritScope cs(&crit_sect_); |
| 69 max_framerate = config_.maxFramerate; |
| 70 num_simulcast_streams = config_.numberOfSimulcastStreams; |
| 71 for (int i = 0; i < num_simulcast_streams; ++i) { |
| 72 simulcast_streams[i] = config_.simulcastStream[i]; |
| 73 } |
| 74 callback = callback_; |
| 75 target_bitrate_sum_kbps = target_bitrate_.get_sum_kbps(); |
| 76 max_target_bitrate_kbps = max_target_bitrate_kbps_; |
| 77 last_encode_time_ms = last_encode_time_ms_; |
| 78 num_encoded_bytes = sizeof(encoded_buffer_); |
| 79 } |
| 80 |
55 int64_t time_now_ms = clock_->TimeInMilliseconds(); | 81 int64_t time_now_ms = clock_->TimeInMilliseconds(); |
56 const bool first_encode = last_encode_time_ms_ == 0; | 82 const bool first_encode = (last_encode_time_ms == 0); |
| 83 RTC_DCHECK_GT(max_framerate, 0); |
| 84 int64_t time_since_last_encode_ms = 1000 / max_framerate; |
57 if (!first_encode) { | 85 if (!first_encode) { |
58 // For all frames but the first we can estimate the display time by looking | 86 // For all frames but the first we can estimate the display time by looking |
59 // at the display time of the previous frame. | 87 // at the display time of the previous frame. |
60 time_since_last_encode_ms = time_now_ms - last_encode_time_ms_; | 88 time_since_last_encode_ms = time_now_ms - last_encode_time_ms; |
61 } | 89 } |
62 if (time_since_last_encode_ms > 3 * 1000 / config_.maxFramerate) { | 90 if (time_since_last_encode_ms > 3 * 1000 / max_framerate) { |
63 // Rudimentary check to make sure we don't widely overshoot bitrate target | 91 // Rudimentary check to make sure we don't widely overshoot bitrate target |
64 // when resuming encoding after a suspension. | 92 // when resuming encoding after a suspension. |
65 time_since_last_encode_ms = 3 * 1000 / config_.maxFramerate; | 93 time_since_last_encode_ms = 3 * 1000 / max_framerate; |
66 } | 94 } |
67 | 95 |
68 size_t bits_available = static_cast<size_t>(target_bitrate_.get_sum_kbps() * | 96 size_t bits_available = |
69 time_since_last_encode_ms); | 97 static_cast<size_t>(target_bitrate_sum_kbps * time_since_last_encode_ms); |
70 size_t min_bits = static_cast<size_t>( | 98 size_t min_bits = static_cast<size_t>(simulcast_streams[0].minBitrate * |
71 config_.simulcastStream[0].minBitrate * time_since_last_encode_ms); | 99 time_since_last_encode_ms); |
| 100 |
72 if (bits_available < min_bits) | 101 if (bits_available < min_bits) |
73 bits_available = min_bits; | 102 bits_available = min_bits; |
74 size_t max_bits = | 103 size_t max_bits = |
75 static_cast<size_t>(max_target_bitrate_kbps_ * time_since_last_encode_ms); | 104 static_cast<size_t>(max_target_bitrate_kbps * time_since_last_encode_ms); |
76 if (max_bits > 0 && max_bits < bits_available) | 105 if (max_bits > 0 && max_bits < bits_available) |
77 bits_available = max_bits; | 106 bits_available = max_bits; |
78 last_encode_time_ms_ = time_now_ms; | |
79 | 107 |
80 RTC_DCHECK_GT(config_.numberOfSimulcastStreams, 0); | 108 { |
81 for (unsigned char i = 0; i < config_.numberOfSimulcastStreams; ++i) { | 109 rtc::CritScope cs(&crit_sect_); |
| 110 last_encode_time_ms_ = time_now_ms; |
| 111 } |
| 112 |
| 113 RTC_DCHECK_GT(num_simulcast_streams, 0); |
| 114 for (unsigned char i = 0; i < num_simulcast_streams; ++i) { |
82 CodecSpecificInfo specifics; | 115 CodecSpecificInfo specifics; |
83 memset(&specifics, 0, sizeof(specifics)); | 116 memset(&specifics, 0, sizeof(specifics)); |
84 specifics.codecType = kVideoCodecGeneric; | 117 specifics.codecType = kVideoCodecGeneric; |
85 specifics.codecSpecific.generic.simulcast_idx = i; | 118 specifics.codecSpecific.generic.simulcast_idx = i; |
86 size_t min_stream_bits = static_cast<size_t>( | 119 size_t min_stream_bits = static_cast<size_t>( |
87 config_.simulcastStream[i].minBitrate * time_since_last_encode_ms); | 120 simulcast_streams[i].minBitrate * time_since_last_encode_ms); |
88 size_t max_stream_bits = static_cast<size_t>( | 121 size_t max_stream_bits = static_cast<size_t>( |
89 config_.simulcastStream[i].maxBitrate * time_since_last_encode_ms); | 122 simulcast_streams[i].maxBitrate * time_since_last_encode_ms); |
90 size_t stream_bits = (bits_available > max_stream_bits) ? max_stream_bits : | 123 size_t stream_bits = (bits_available > max_stream_bits) ? max_stream_bits : |
91 bits_available; | 124 bits_available; |
92 size_t stream_bytes = (stream_bits + 7) / 8; | 125 size_t stream_bytes = (stream_bits + 7) / 8; |
93 if (first_encode) { | 126 if (first_encode) { |
94 // The first frame is a key frame and should be larger. | 127 // The first frame is a key frame and should be larger. |
95 // TODO(holmer): The FakeEncoder should store the bits_available between | 128 // TODO(holmer): The FakeEncoder should store the bits_available between |
96 // encodes so that it can compensate for oversized frames. | 129 // encodes so that it can compensate for oversized frames. |
97 stream_bytes *= 10; | 130 stream_bytes *= 10; |
98 } | 131 } |
99 if (stream_bytes > sizeof(encoded_buffer_)) | 132 if (stream_bytes > num_encoded_bytes) |
100 stream_bytes = sizeof(encoded_buffer_); | 133 stream_bytes = num_encoded_bytes; |
101 | 134 |
102 // Always encode something on the first frame. | 135 // Always encode something on the first frame. |
103 if (min_stream_bits > bits_available && i > 0) | 136 if (min_stream_bits > bits_available && i > 0) |
104 continue; | 137 continue; |
105 EncodedImage encoded( | 138 |
106 encoded_buffer_, stream_bytes, sizeof(encoded_buffer_)); | 139 std::unique_ptr<uint8_t[]> encoded_buffer(new uint8_t[num_encoded_bytes]); |
| 140 memcpy(encoded_buffer.get(), encoded_buffer_, num_encoded_bytes); |
| 141 EncodedImage encoded(encoded_buffer.get(), stream_bytes, num_encoded_bytes); |
107 encoded._timeStamp = input_image.timestamp(); | 142 encoded._timeStamp = input_image.timestamp(); |
108 encoded.capture_time_ms_ = input_image.render_time_ms(); | 143 encoded.capture_time_ms_ = input_image.render_time_ms(); |
109 encoded._frameType = (*frame_types)[i]; | 144 encoded._frameType = (*frame_types)[i]; |
110 encoded._encodedWidth = config_.simulcastStream[i].width; | 145 encoded._encodedWidth = simulcast_streams[i].width; |
111 encoded._encodedHeight = config_.simulcastStream[i].height; | 146 encoded._encodedHeight = simulcast_streams[i].height; |
112 encoded.rotation_ = input_image.rotation(); | 147 encoded.rotation_ = input_image.rotation(); |
113 RTC_DCHECK(callback_ != NULL); | |
114 specifics.codec_name = ImplementationName(); | 148 specifics.codec_name = ImplementationName(); |
115 if (callback_->OnEncodedImage(encoded, &specifics, NULL).error != | 149 RTC_DCHECK(callback); |
| 150 if (callback->OnEncodedImage(encoded, &specifics, nullptr).error != |
116 EncodedImageCallback::Result::OK) { | 151 EncodedImageCallback::Result::OK) { |
117 return -1; | 152 return -1; |
118 } | 153 } |
119 bits_available -= std::min(encoded._length * 8, bits_available); | 154 bits_available -= std::min(encoded._length * 8, bits_available); |
120 } | 155 } |
121 return 0; | 156 return 0; |
122 } | 157 } |
123 | 158 |
124 int32_t FakeEncoder::RegisterEncodeCompleteCallback( | 159 int32_t FakeEncoder::RegisterEncodeCompleteCallback( |
125 EncodedImageCallback* callback) { | 160 EncodedImageCallback* callback) { |
| 161 rtc::CritScope cs(&crit_sect_); |
126 callback_ = callback; | 162 callback_ = callback; |
127 return 0; | 163 return 0; |
128 } | 164 } |
129 | 165 |
130 int32_t FakeEncoder::Release() { return 0; } | 166 int32_t FakeEncoder::Release() { return 0; } |
131 | 167 |
132 int32_t FakeEncoder::SetChannelParameters(uint32_t packet_loss, int64_t rtt) { | 168 int32_t FakeEncoder::SetChannelParameters(uint32_t packet_loss, int64_t rtt) { |
133 return 0; | 169 return 0; |
134 } | 170 } |
135 | 171 |
136 int32_t FakeEncoder::SetRateAllocation(const BitrateAllocation& rate_allocation, | 172 int32_t FakeEncoder::SetRateAllocation(const BitrateAllocation& rate_allocation, |
137 uint32_t framerate) { | 173 uint32_t framerate) { |
| 174 rtc::CritScope cs(&crit_sect_); |
138 target_bitrate_ = rate_allocation; | 175 target_bitrate_ = rate_allocation; |
139 return 0; | 176 return 0; |
140 } | 177 } |
141 | 178 |
142 const char* FakeEncoder::kImplementationName = "fake_encoder"; | 179 const char* FakeEncoder::kImplementationName = "fake_encoder"; |
143 const char* FakeEncoder::ImplementationName() const { | 180 const char* FakeEncoder::ImplementationName() const { |
144 return kImplementationName; | 181 return kImplementationName; |
145 } | 182 } |
146 | 183 |
147 FakeH264Encoder::FakeH264Encoder(Clock* clock) | 184 FakeH264Encoder::FakeH264Encoder(Clock* clock) |
148 : FakeEncoder(clock), callback_(NULL), idr_counter_(0) { | 185 : FakeEncoder(clock), callback_(nullptr), idr_counter_(0) { |
149 FakeEncoder::RegisterEncodeCompleteCallback(this); | 186 FakeEncoder::RegisterEncodeCompleteCallback(this); |
150 } | 187 } |
151 | 188 |
152 int32_t FakeH264Encoder::RegisterEncodeCompleteCallback( | 189 int32_t FakeH264Encoder::RegisterEncodeCompleteCallback( |
153 EncodedImageCallback* callback) { | 190 EncodedImageCallback* callback) { |
| 191 rtc::CritScope cs(&local_crit_sect_); |
154 callback_ = callback; | 192 callback_ = callback; |
155 return 0; | 193 return 0; |
156 } | 194 } |
157 | 195 |
158 EncodedImageCallback::Result FakeH264Encoder::OnEncodedImage( | 196 EncodedImageCallback::Result FakeH264Encoder::OnEncodedImage( |
159 const EncodedImage& encoded_image, | 197 const EncodedImage& encoded_image, |
160 const CodecSpecificInfo* codec_specific_info, | 198 const CodecSpecificInfo* codec_specific_info, |
161 const RTPFragmentationHeader* fragments) { | 199 const RTPFragmentationHeader* fragments) { |
162 const size_t kSpsSize = 8; | 200 const size_t kSpsSize = 8; |
163 const size_t kPpsSize = 11; | 201 const size_t kPpsSize = 11; |
164 const int kIdrFrequency = 10; | 202 const int kIdrFrequency = 10; |
| 203 EncodedImageCallback* callback; |
| 204 int current_idr_counter; |
| 205 { |
| 206 rtc::CritScope cs(&local_crit_sect_); |
| 207 callback = callback_; |
| 208 current_idr_counter = idr_counter_; |
| 209 ++idr_counter_; |
| 210 } |
165 RTPFragmentationHeader fragmentation; | 211 RTPFragmentationHeader fragmentation; |
166 if (idr_counter_++ % kIdrFrequency == 0 && | 212 if (current_idr_counter % kIdrFrequency == 0 && |
167 encoded_image._length > kSpsSize + kPpsSize + 1) { | 213 encoded_image._length > kSpsSize + kPpsSize + 1) { |
168 const size_t kNumSlices = 3; | 214 const size_t kNumSlices = 3; |
169 fragmentation.VerifyAndAllocateFragmentationHeader(kNumSlices); | 215 fragmentation.VerifyAndAllocateFragmentationHeader(kNumSlices); |
170 fragmentation.fragmentationOffset[0] = 0; | 216 fragmentation.fragmentationOffset[0] = 0; |
171 fragmentation.fragmentationLength[0] = kSpsSize; | 217 fragmentation.fragmentationLength[0] = kSpsSize; |
172 fragmentation.fragmentationOffset[1] = kSpsSize; | 218 fragmentation.fragmentationOffset[1] = kSpsSize; |
173 fragmentation.fragmentationLength[1] = kPpsSize; | 219 fragmentation.fragmentationLength[1] = kPpsSize; |
174 fragmentation.fragmentationOffset[2] = kSpsSize + kPpsSize; | 220 fragmentation.fragmentationOffset[2] = kSpsSize + kPpsSize; |
175 fragmentation.fragmentationLength[2] = | 221 fragmentation.fragmentationLength[2] = |
176 encoded_image._length - (kSpsSize + kPpsSize); | 222 encoded_image._length - (kSpsSize + kPpsSize); |
(...skipping 19 matching lines...) Expand all Loading... |
196 encoded_image._buffer[i] = value++; | 242 encoded_image._buffer[i] = value++; |
197 } else { | 243 } else { |
198 ++fragment_counter; | 244 ++fragment_counter; |
199 } | 245 } |
200 } | 246 } |
201 CodecSpecificInfo specifics; | 247 CodecSpecificInfo specifics; |
202 memset(&specifics, 0, sizeof(specifics)); | 248 memset(&specifics, 0, sizeof(specifics)); |
203 specifics.codecType = kVideoCodecH264; | 249 specifics.codecType = kVideoCodecH264; |
204 specifics.codecSpecific.H264.packetization_mode = | 250 specifics.codecSpecific.H264.packetization_mode = |
205 H264PacketizationMode::NonInterleaved; | 251 H264PacketizationMode::NonInterleaved; |
206 return callback_->OnEncodedImage(encoded_image, &specifics, &fragmentation); | 252 RTC_DCHECK(callback); |
| 253 return callback->OnEncodedImage(encoded_image, &specifics, &fragmentation); |
207 } | 254 } |
208 | 255 |
209 DelayedEncoder::DelayedEncoder(Clock* clock, int delay_ms) | 256 DelayedEncoder::DelayedEncoder(Clock* clock, int delay_ms) |
210 : test::FakeEncoder(clock), | 257 : test::FakeEncoder(clock), |
211 delay_ms_(delay_ms) {} | 258 delay_ms_(delay_ms) {} |
212 | 259 |
213 void DelayedEncoder::SetDelay(int delay_ms) { | 260 void DelayedEncoder::SetDelay(int delay_ms) { |
214 rtc::CritScope lock(&lock_); | 261 rtc::CritScope cs(&local_crit_sect_); |
215 delay_ms_ = delay_ms; | 262 delay_ms_ = delay_ms; |
216 } | 263 } |
217 | 264 |
218 int32_t DelayedEncoder::Encode(const VideoFrame& input_image, | 265 int32_t DelayedEncoder::Encode(const VideoFrame& input_image, |
219 const CodecSpecificInfo* codec_specific_info, | 266 const CodecSpecificInfo* codec_specific_info, |
220 const std::vector<FrameType>* frame_types) { | 267 const std::vector<FrameType>* frame_types) { |
221 int delay_ms = 0; | 268 int delay_ms = 0; |
222 { | 269 { |
223 rtc::CritScope lock(&lock_); | 270 rtc::CritScope cs(&local_crit_sect_); |
224 delay_ms = delay_ms_; | 271 delay_ms = delay_ms_; |
225 } | 272 } |
226 SleepMs(delay_ms); | 273 SleepMs(delay_ms); |
227 return FakeEncoder::Encode(input_image, codec_specific_info, frame_types); | 274 return FakeEncoder::Encode(input_image, codec_specific_info, frame_types); |
228 } | 275 } |
229 | 276 |
230 MultiThreadedFakeH264Encoder::MultiThreadedFakeH264Encoder(Clock* clock) | 277 MultithreadedFakeH264Encoder::MultithreadedFakeH264Encoder(Clock* clock) |
231 : test::FakeH264Encoder(clock), | 278 : test::FakeH264Encoder(clock), |
232 current_queue_(0), | 279 current_queue_(0), |
233 queue1_("Queue 1"), | 280 queue1_("Queue 1"), |
234 queue2_("Queue 2") {} | 281 queue2_("Queue 2") {} |
235 | 282 |
236 MultiThreadedFakeH264Encoder::~MultiThreadedFakeH264Encoder() = default; | 283 MultithreadedFakeH264Encoder::~MultithreadedFakeH264Encoder() = default; |
237 | 284 |
238 class MultiThreadedFakeH264Encoder::EncodeTask : public rtc::QueuedTask { | 285 class MultithreadedFakeH264Encoder::EncodeTask : public rtc::QueuedTask { |
239 public: | 286 public: |
240 EncodeTask(MultiThreadedFakeH264Encoder* encoder, | 287 EncodeTask(MultithreadedFakeH264Encoder* encoder, |
241 const VideoFrame& input_image, | 288 const VideoFrame& input_image, |
242 const CodecSpecificInfo* codec_specific_info, | 289 const CodecSpecificInfo* codec_specific_info, |
243 const std::vector<FrameType>* frame_types) | 290 const std::vector<FrameType>* frame_types) |
244 : encoder_(encoder), | 291 : encoder_(encoder), |
245 input_image_(input_image), | 292 input_image_(input_image), |
246 codec_specific_info_(), | 293 codec_specific_info_(), |
247 frame_types_(*frame_types) { | 294 frame_types_(*frame_types) { |
248 if (codec_specific_info) | 295 if (codec_specific_info) |
249 codec_specific_info_ = *codec_specific_info; | 296 codec_specific_info_ = *codec_specific_info; |
250 } | 297 } |
251 | 298 |
252 private: | 299 private: |
253 bool Run() override { | 300 bool Run() override { |
254 encoder_->EncodeCallback(input_image_, &codec_specific_info_, | 301 encoder_->EncodeCallback(input_image_, &codec_specific_info_, |
255 &frame_types_); | 302 &frame_types_); |
256 return true; | 303 return true; |
257 } | 304 } |
258 | 305 |
259 MultiThreadedFakeH264Encoder* const encoder_; | 306 MultithreadedFakeH264Encoder* const encoder_; |
260 VideoFrame input_image_; | 307 VideoFrame input_image_; |
261 CodecSpecificInfo codec_specific_info_; | 308 CodecSpecificInfo codec_specific_info_; |
262 std::vector<FrameType> frame_types_; | 309 std::vector<FrameType> frame_types_; |
263 }; | 310 }; |
264 | 311 |
265 int32_t MultiThreadedFakeH264Encoder::Encode( | 312 int32_t MultithreadedFakeH264Encoder::Encode( |
266 const VideoFrame& input_image, | 313 const VideoFrame& input_image, |
267 const CodecSpecificInfo* codec_specific_info, | 314 const CodecSpecificInfo* codec_specific_info, |
268 const std::vector<FrameType>* frame_types) { | 315 const std::vector<FrameType>* frame_types) { |
269 int current_queue = rtc::AtomicOps::Increment(¤t_queue_); | 316 int current_queue = rtc::AtomicOps::Increment(¤t_queue_); |
270 rtc::TaskQueue& queue = (current_queue % 2 == 0) ? queue1_ : queue2_; | 317 rtc::TaskQueue& queue = (current_queue % 2 == 0) ? queue1_ : queue2_; |
271 | 318 |
272 queue.PostTask(std::unique_ptr<rtc::QueuedTask>( | 319 queue.PostTask(std::unique_ptr<rtc::QueuedTask>( |
273 new EncodeTask(this, input_image, codec_specific_info, frame_types))); | 320 new EncodeTask(this, input_image, codec_specific_info, frame_types))); |
274 | 321 |
275 return 0; | 322 return 0; |
276 } | 323 } |
277 | 324 |
278 int32_t MultiThreadedFakeH264Encoder::EncodeCallback( | 325 int32_t MultithreadedFakeH264Encoder::EncodeCallback( |
279 const VideoFrame& input_image, | 326 const VideoFrame& input_image, |
280 const CodecSpecificInfo* codec_specific_info, | 327 const CodecSpecificInfo* codec_specific_info, |
281 const std::vector<FrameType>* frame_types) { | 328 const std::vector<FrameType>* frame_types) { |
282 return FakeH264Encoder::Encode(input_image, codec_specific_info, frame_types); | 329 return FakeH264Encoder::Encode(input_image, codec_specific_info, frame_types); |
283 } | 330 } |
284 | 331 |
285 } // namespace test | 332 } // namespace test |
286 } // namespace webrtc | 333 } // namespace webrtc |
OLD | NEW |