| 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" |
| 11 | 11 |
| 12 #include <math.h> | 12 #include <math.h> |
| 13 #include <stdio.h> | 13 #include <stdio.h> |
| 14 #include <string.h> | 14 #include <string.h> |
| 15 | 15 |
| 16 #include <memory> | 16 #include <memory> |
| 17 | 17 |
| 18 #include "webrtc/api/video/i420_buffer.h" | 18 #include "webrtc/api/video/i420_buffer.h" |
| 19 #include "webrtc/base/checks.h" | 19 #include "webrtc/base/checks.h" |
| 20 #include "webrtc/base/keep_ref_until_done.h" | 20 #include "webrtc/base/keep_ref_until_done.h" |
| 21 #include "webrtc/base/random.h" |
| 21 #include "webrtc/common_video/include/video_frame_buffer.h" | 22 #include "webrtc/common_video/include/video_frame_buffer.h" |
| 22 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" | 23 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" |
| 23 #include "webrtc/system_wrappers/include/clock.h" | 24 #include "webrtc/system_wrappers/include/clock.h" |
| 24 #include "webrtc/test/frame_utils.h" | 25 #include "webrtc/test/frame_utils.h" |
| 25 | 26 |
| 26 namespace webrtc { | 27 namespace webrtc { |
| 27 namespace test { | 28 namespace test { |
| 28 namespace { | 29 namespace { |
| 29 | 30 |
| 30 class ChromaGenerator : public FrameGenerator { | 31 // SquareGenerator is a FrameGenerator that draws 10 randomly sized and colored |
| 32 // squares. Between each new generated frame, the squares are moved slightly |
| 33 // towards the lower right corner. |
| 34 class SquareGenerator : public FrameGenerator { |
| 31 public: | 35 public: |
| 32 ChromaGenerator(size_t width, size_t height) : angle_(0.0) { | 36 SquareGenerator(int width, int height) { |
| 33 ChangeResolution(width, height); | 37 ChangeResolution(width, height); |
| 38 for (int i = 0; i < 10; ++i) { |
| 39 squares_.emplace_back(new Square(width, height, i + 1)); |
| 40 } |
| 34 } | 41 } |
| 35 | 42 |
| 36 void ChangeResolution(size_t width, size_t height) override { | 43 void ChangeResolution(size_t width, size_t height) override { |
| 37 rtc::CritScope lock(&crit_); | 44 rtc::CritScope lock(&crit_); |
| 38 width_ = width; | 45 width_ = static_cast<int>(width); |
| 39 height_ = height; | 46 height_ = static_cast<int>(height); |
| 40 RTC_CHECK(width_ > 0); | 47 RTC_CHECK(width_ > 0); |
| 41 RTC_CHECK(height_ > 0); | 48 RTC_CHECK(height_ > 0); |
| 42 half_width_ = (width_ + 1) / 2; | 49 half_width_ = (width_ + 1) / 2; |
| 43 y_size_ = width_ * height_; | 50 y_size_ = width_ * height_; |
| 44 uv_size_ = half_width_ * ((height_ + 1) / 2); | 51 uv_size_ = half_width_ * ((height_ + 1) / 2); |
| 45 } | 52 } |
| 46 | 53 |
| 47 VideoFrame* NextFrame() override { | 54 VideoFrame* NextFrame() override { |
| 48 rtc::CritScope lock(&crit_); | 55 rtc::CritScope lock(&crit_); |
| 49 angle_ += 30.0; | |
| 50 uint8_t u = fabs(sin(angle_)) * 0xFF; | |
| 51 uint8_t v = fabs(cos(angle_)) * 0xFF; | |
| 52 | 56 |
| 53 // Ensure stride == width. | 57 // Ensure stride == width. |
| 54 rtc::scoped_refptr<I420Buffer> buffer(I420Buffer::Create( | 58 rtc::scoped_refptr<I420Buffer> buffer( |
| 55 static_cast<int>(width_), static_cast<int>(height_), | 59 I420Buffer::Create(width_, height_, width_, half_width_, half_width_)); |
| 56 static_cast<int>(width_), static_cast<int>(half_width_), | 60 memset(buffer->MutableDataY(), 127, y_size_); |
| 57 static_cast<int>(half_width_))); | 61 memset(buffer->MutableDataU(), 127, uv_size_); |
| 62 memset(buffer->MutableDataV(), 127, uv_size_); |
| 58 | 63 |
| 59 memset(buffer->MutableDataY(), 0x80, y_size_); | 64 for (const auto& square : squares_) |
| 60 memset(buffer->MutableDataU(), u, uv_size_); | 65 square->Draw(buffer); |
| 61 memset(buffer->MutableDataV(), v, uv_size_); | |
| 62 | 66 |
| 63 frame_.reset(new VideoFrame(buffer, 0, 0, webrtc::kVideoRotation_0)); | 67 frame_.reset(new VideoFrame(buffer, 0, 0, webrtc::kVideoRotation_0)); |
| 64 return frame_.get(); | 68 return frame_.get(); |
| 65 } | 69 } |
| 66 | 70 |
| 67 private: | 71 private: |
| 72 class Square { |
| 73 public: |
| 74 Square(int width, int height, int seed) |
| 75 : random_generator_(seed), |
| 76 x_(random_generator_.Rand(0, width)), |
| 77 y_(random_generator_.Rand(0, height)), |
| 78 length_(random_generator_.Rand(1, width > 4 ? width / 4 : 1)), |
| 79 yuv_y_(random_generator_.Rand(0, 255)), |
| 80 yuv_u_(random_generator_.Rand(0, 255)), |
| 81 yuv_v_(random_generator_.Rand(0, 255)) {} |
| 82 |
| 83 void Draw(const rtc::scoped_refptr<I420Buffer>& buffer) { |
| 84 x_ = (x_ + random_generator_.Rand(0, 4)) % (buffer->width() - length_); |
| 85 y_ = (y_ + random_generator_.Rand(0, 4)) % (buffer->height() - length_); |
| 86 for (int x = x_; x < x_ + length_; ++x) { |
| 87 for (int y = y_; y < y_ + length_; ++y) { |
| 88 uint8_t* pos_y = (buffer->MutableDataY() + x + y * buffer->StrideY()); |
| 89 *pos_y = yuv_y_; |
| 90 uint8_t* pos_u = |
| 91 (buffer->MutableDataU() + x / 2 + y / 2 * buffer->StrideU()); |
| 92 *pos_u = yuv_u_; |
| 93 uint8_t* pos_v = |
| 94 (buffer->MutableDataV() + x / 2 + y / 2 * buffer->StrideV()); |
| 95 *pos_v = yuv_v_; |
| 96 } |
| 97 } |
| 98 } |
| 99 |
| 100 private: |
| 101 Random random_generator_; |
| 102 int x_; |
| 103 int y_; |
| 104 const int length_; |
| 105 const uint8_t yuv_y_; |
| 106 const uint8_t yuv_u_; |
| 107 const uint8_t yuv_v_; |
| 108 }; |
| 109 |
| 68 rtc::CriticalSection crit_; | 110 rtc::CriticalSection crit_; |
| 69 double angle_ GUARDED_BY(&crit_); | 111 int width_ GUARDED_BY(&crit_); |
| 70 size_t width_ GUARDED_BY(&crit_); | 112 int height_ GUARDED_BY(&crit_); |
| 71 size_t height_ GUARDED_BY(&crit_); | 113 int half_width_ GUARDED_BY(&crit_); |
| 72 size_t half_width_ GUARDED_BY(&crit_); | |
| 73 size_t y_size_ GUARDED_BY(&crit_); | 114 size_t y_size_ GUARDED_BY(&crit_); |
| 74 size_t uv_size_ GUARDED_BY(&crit_); | 115 size_t uv_size_ GUARDED_BY(&crit_); |
| 116 std::vector<std::unique_ptr<Square>> squares_ GUARDED_BY(&crit_); |
| 75 std::unique_ptr<VideoFrame> frame_ GUARDED_BY(&crit_); | 117 std::unique_ptr<VideoFrame> frame_ GUARDED_BY(&crit_); |
| 76 }; | 118 }; |
| 77 | 119 |
| 78 class YuvFileGenerator : public FrameGenerator { | 120 class YuvFileGenerator : public FrameGenerator { |
| 79 public: | 121 public: |
| 80 YuvFileGenerator(std::vector<FILE*> files, | 122 YuvFileGenerator(std::vector<FILE*> files, |
| 81 size_t width, | 123 size_t width, |
| 82 size_t height, | 124 size_t height, |
| 83 int frame_repeat_count) | 125 int frame_repeat_count) |
| 84 : file_index_(0), | 126 : file_index_(0), |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 rtc::VideoSinkWants FrameForwarder::sink_wants() const { | 315 rtc::VideoSinkWants FrameForwarder::sink_wants() const { |
| 274 rtc::CritScope lock(&crit_); | 316 rtc::CritScope lock(&crit_); |
| 275 return sink_wants_; | 317 return sink_wants_; |
| 276 } | 318 } |
| 277 | 319 |
| 278 bool FrameForwarder::has_sinks() const { | 320 bool FrameForwarder::has_sinks() const { |
| 279 rtc::CritScope lock(&crit_); | 321 rtc::CritScope lock(&crit_); |
| 280 return sink_ != nullptr; | 322 return sink_ != nullptr; |
| 281 } | 323 } |
| 282 | 324 |
| 283 FrameGenerator* FrameGenerator::CreateChromaGenerator(size_t width, | 325 std::unique_ptr<FrameGenerator> FrameGenerator::CreateSquareGenerator( |
| 284 size_t height) { | 326 int width, |
| 285 return new ChromaGenerator(width, height); | 327 int height) { |
| 328 return std::unique_ptr<FrameGenerator>(new SquareGenerator(width, height)); |
| 286 } | 329 } |
| 287 | 330 |
| 288 FrameGenerator* FrameGenerator::CreateFromYuvFile( | 331 std::unique_ptr<FrameGenerator> FrameGenerator::CreateFromYuvFile( |
| 289 std::vector<std::string> filenames, | 332 std::vector<std::string> filenames, |
| 290 size_t width, | 333 size_t width, |
| 291 size_t height, | 334 size_t height, |
| 292 int frame_repeat_count) { | 335 int frame_repeat_count) { |
| 293 RTC_DCHECK(!filenames.empty()); | 336 RTC_DCHECK(!filenames.empty()); |
| 294 std::vector<FILE*> files; | 337 std::vector<FILE*> files; |
| 295 for (const std::string& filename : filenames) { | 338 for (const std::string& filename : filenames) { |
| 296 FILE* file = fopen(filename.c_str(), "rb"); | 339 FILE* file = fopen(filename.c_str(), "rb"); |
| 297 RTC_DCHECK(file != nullptr); | 340 RTC_DCHECK(file != nullptr); |
| 298 files.push_back(file); | 341 files.push_back(file); |
| 299 } | 342 } |
| 300 | 343 |
| 301 return new YuvFileGenerator(files, width, height, frame_repeat_count); | 344 return std::unique_ptr<FrameGenerator>( |
| 345 new YuvFileGenerator(files, width, height, frame_repeat_count)); |
| 302 } | 346 } |
| 303 | 347 |
| 304 FrameGenerator* FrameGenerator::CreateScrollingInputFromYuvFiles( | 348 std::unique_ptr<FrameGenerator> |
| 349 FrameGenerator::CreateScrollingInputFromYuvFiles( |
| 305 Clock* clock, | 350 Clock* clock, |
| 306 std::vector<std::string> filenames, | 351 std::vector<std::string> filenames, |
| 307 size_t source_width, | 352 size_t source_width, |
| 308 size_t source_height, | 353 size_t source_height, |
| 309 size_t target_width, | 354 size_t target_width, |
| 310 size_t target_height, | 355 size_t target_height, |
| 311 int64_t scroll_time_ms, | 356 int64_t scroll_time_ms, |
| 312 int64_t pause_time_ms) { | 357 int64_t pause_time_ms) { |
| 313 RTC_DCHECK(!filenames.empty()); | 358 RTC_DCHECK(!filenames.empty()); |
| 314 std::vector<FILE*> files; | 359 std::vector<FILE*> files; |
| 315 for (const std::string& filename : filenames) { | 360 for (const std::string& filename : filenames) { |
| 316 FILE* file = fopen(filename.c_str(), "rb"); | 361 FILE* file = fopen(filename.c_str(), "rb"); |
| 317 RTC_DCHECK(file != nullptr); | 362 RTC_DCHECK(file != nullptr); |
| 318 files.push_back(file); | 363 files.push_back(file); |
| 319 } | 364 } |
| 320 | 365 |
| 321 return new ScrollingImageFrameGenerator( | 366 return std::unique_ptr<FrameGenerator>(new ScrollingImageFrameGenerator( |
| 322 clock, files, source_width, source_height, target_width, target_height, | 367 clock, files, source_width, source_height, target_width, target_height, |
| 323 scroll_time_ms, pause_time_ms); | 368 scroll_time_ms, pause_time_ms)); |
| 324 } | 369 } |
| 325 | 370 |
| 326 } // namespace test | 371 } // namespace test |
| 327 } // namespace webrtc | 372 } // namespace webrtc |
| OLD | NEW |