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 #include "webrtc/test/frame_generator.h" | 10 #include "webrtc/test/frame_generator.h" |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 const size_t width_; | 174 const size_t width_; |
175 const size_t height_; | 175 const size_t height_; |
176 const size_t frame_size_; | 176 const size_t frame_size_; |
177 const std::unique_ptr<uint8_t[]> frame_buffer_; | 177 const std::unique_ptr<uint8_t[]> frame_buffer_; |
178 const int frame_display_count_; | 178 const int frame_display_count_; |
179 int current_display_count_; | 179 int current_display_count_; |
180 rtc::scoped_refptr<I420Buffer> last_read_buffer_; | 180 rtc::scoped_refptr<I420Buffer> last_read_buffer_; |
181 std::unique_ptr<VideoFrame> temp_frame_; | 181 std::unique_ptr<VideoFrame> temp_frame_; |
182 }; | 182 }; |
183 | 183 |
| 184 // SlideGenerator works similarly to YuvFileGenerator but it fills the frames |
| 185 // with randomly sized and colored squares instead of reading their content |
| 186 // from files. |
| 187 class SlideGenerator : public FrameGenerator { |
| 188 public: |
| 189 SlideGenerator(int width, int height, int frame_repeat_count) |
| 190 : width_(width), |
| 191 height_(height), |
| 192 frame_display_count_(frame_repeat_count), |
| 193 current_display_count_(0), |
| 194 random_generator_(1234) { |
| 195 RTC_DCHECK_GT(width, 0); |
| 196 RTC_DCHECK_GT(height, 0); |
| 197 RTC_DCHECK_GT(frame_repeat_count, 0); |
| 198 } |
| 199 |
| 200 VideoFrame* NextFrame() override { |
| 201 if (current_display_count_ == 0) |
| 202 GenerateNewFrame(); |
| 203 if (++current_display_count_ >= frame_display_count_) |
| 204 current_display_count_ = 0; |
| 205 |
| 206 frame_.reset( |
| 207 new VideoFrame(buffer_, 0, 0, webrtc::kVideoRotation_0)); |
| 208 return frame_.get(); |
| 209 } |
| 210 |
| 211 // Generates some randomly sized and colored squares scattered |
| 212 // over the frame. |
| 213 void GenerateNewFrame() { |
| 214 // The squares should have a varying order of magnitude in order |
| 215 // to simulate variation in the slides' complexity. |
| 216 const int kSquareNum = 1 << (4 + (random_generator_.Rand(0, 3) * 4)); |
| 217 |
| 218 buffer_ = I420Buffer::Create(width_, height_); |
| 219 memset(buffer_->MutableDataY(), 127, height_ * buffer_->StrideY()); |
| 220 memset(buffer_->MutableDataU(), 127, |
| 221 buffer_->ChromaHeight() * buffer_->StrideU()); |
| 222 memset(buffer_->MutableDataV(), 127, |
| 223 buffer_->ChromaHeight() * buffer_->StrideV()); |
| 224 |
| 225 for (int i = 0; i < kSquareNum; ++i) { |
| 226 int length = random_generator_.Rand(1, width_ > 4 ? width_ / 4 : 1); |
| 227 // Limit the length of later squares so that they don't overwrite the |
| 228 // previous ones too much. |
| 229 length = (length * (kSquareNum - i)) / kSquareNum; |
| 230 |
| 231 int x = random_generator_.Rand(0, width_ - length); |
| 232 int y = random_generator_.Rand(0, height_ - length); |
| 233 uint8_t yuv_y = random_generator_.Rand(0, 255); |
| 234 uint8_t yuv_u = random_generator_.Rand(0, 255); |
| 235 uint8_t yuv_v = random_generator_.Rand(0, 255); |
| 236 |
| 237 for (int yy = y; yy < y + length; ++yy) { |
| 238 uint8_t* pos_y = |
| 239 (buffer_->MutableDataY() + x + yy * buffer_->StrideY()); |
| 240 memset(pos_y, yuv_y, length); |
| 241 } |
| 242 for (int yy = y; yy < y + length; yy += 2) { |
| 243 uint8_t* pos_u = |
| 244 (buffer_->MutableDataU() + x / 2 + yy / 2 * buffer_->StrideU()); |
| 245 memset(pos_u, yuv_u, length / 2); |
| 246 uint8_t* pos_v = |
| 247 (buffer_->MutableDataV() + x / 2 + yy / 2 * buffer_->StrideV()); |
| 248 memset(pos_v, yuv_v, length / 2); |
| 249 } |
| 250 } |
| 251 } |
| 252 |
| 253 private: |
| 254 const int width_; |
| 255 const int height_; |
| 256 const int frame_display_count_; |
| 257 int current_display_count_; |
| 258 Random random_generator_; |
| 259 rtc::scoped_refptr<I420Buffer> buffer_; |
| 260 std::unique_ptr<VideoFrame> frame_; |
| 261 }; |
| 262 |
184 class ScrollingImageFrameGenerator : public FrameGenerator { | 263 class ScrollingImageFrameGenerator : public FrameGenerator { |
185 public: | 264 public: |
186 ScrollingImageFrameGenerator(Clock* clock, | 265 ScrollingImageFrameGenerator(Clock* clock, |
187 const std::vector<FILE*>& files, | 266 const std::vector<FILE*>& files, |
188 size_t source_width, | 267 size_t source_width, |
189 size_t source_height, | 268 size_t source_height, |
190 size_t target_width, | 269 size_t target_width, |
191 size_t target_height, | 270 size_t target_height, |
192 int64_t scroll_time_ms, | 271 int64_t scroll_time_ms, |
193 int64_t pause_time_ms) | 272 int64_t pause_time_ms) |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 rtc::CritScope lock(&crit_); | 393 rtc::CritScope lock(&crit_); |
315 return sink_ != nullptr; | 394 return sink_ != nullptr; |
316 } | 395 } |
317 | 396 |
318 std::unique_ptr<FrameGenerator> FrameGenerator::CreateSquareGenerator( | 397 std::unique_ptr<FrameGenerator> FrameGenerator::CreateSquareGenerator( |
319 int width, | 398 int width, |
320 int height) { | 399 int height) { |
321 return std::unique_ptr<FrameGenerator>(new SquareGenerator(width, height)); | 400 return std::unique_ptr<FrameGenerator>(new SquareGenerator(width, height)); |
322 } | 401 } |
323 | 402 |
| 403 std::unique_ptr<FrameGenerator> FrameGenerator::CreateSlideGenerator( |
| 404 int width, int height, int frame_repeat_count) { |
| 405 return std::unique_ptr<FrameGenerator>(new SlideGenerator( |
| 406 width, height, frame_repeat_count)); |
| 407 } |
| 408 |
324 std::unique_ptr<FrameGenerator> FrameGenerator::CreateFromYuvFile( | 409 std::unique_ptr<FrameGenerator> FrameGenerator::CreateFromYuvFile( |
325 std::vector<std::string> filenames, | 410 std::vector<std::string> filenames, |
326 size_t width, | 411 size_t width, |
327 size_t height, | 412 size_t height, |
328 int frame_repeat_count) { | 413 int frame_repeat_count) { |
329 RTC_DCHECK(!filenames.empty()); | 414 RTC_DCHECK(!filenames.empty()); |
330 std::vector<FILE*> files; | 415 std::vector<FILE*> files; |
331 for (const std::string& filename : filenames) { | 416 for (const std::string& filename : filenames) { |
332 FILE* file = fopen(filename.c_str(), "rb"); | 417 FILE* file = fopen(filename.c_str(), "rb"); |
333 RTC_DCHECK(file != nullptr); | 418 RTC_DCHECK(file != nullptr); |
(...skipping 22 matching lines...) Expand all Loading... |
356 files.push_back(file); | 441 files.push_back(file); |
357 } | 442 } |
358 | 443 |
359 return std::unique_ptr<FrameGenerator>(new ScrollingImageFrameGenerator( | 444 return std::unique_ptr<FrameGenerator>(new ScrollingImageFrameGenerator( |
360 clock, files, source_width, source_height, target_width, target_height, | 445 clock, files, source_width, source_height, target_width, target_height, |
361 scroll_time_ms, pause_time_ms)); | 446 scroll_time_ms, pause_time_ms)); |
362 } | 447 } |
363 | 448 |
364 } // namespace test | 449 } // namespace test |
365 } // namespace webrtc | 450 } // namespace webrtc |
OLD | NEW |