pbos@webrtc.org | 26d1210 | 2013-05-29 13:41:03 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. |
| 3 | * |
| 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 |
| 6 | * tree. An additional intellectual property rights grant can be found |
| 7 | * in the file PATENTS. All contributing project authors may |
| 8 | * be found in the AUTHORS file in the root of the source tree. |
| 9 | */ |
| 10 | |
pbos@webrtc.org | 16e03b7 | 2013-10-28 16:32:01 | [diff] [blame] | 11 | #include "webrtc/test/frame_generator_capturer.h" |
pbos@webrtc.org | 26d1210 | 2013-05-29 13:41:03 | [diff] [blame] | 12 | |
Peter Boström | f2f8283 | 2015-05-01 11:00:41 | [diff] [blame] | 13 | #include "webrtc/base/criticalsection.h" |
pbos | 12411ef | 2015-11-23 22:47:56 | [diff] [blame] | 14 | #include "webrtc/base/platform_thread.h" |
Henrik Kjellander | 98f5351 | 2015-10-28 17:17:40 | [diff] [blame] | 15 | #include "webrtc/system_wrappers/include/clock.h" |
| 16 | #include "webrtc/system_wrappers/include/event_wrapper.h" |
| 17 | #include "webrtc/system_wrappers/include/sleep.h" |
pbos | 12411ef | 2015-11-23 22:47:56 | [diff] [blame] | 18 | #include "webrtc/test/frame_generator.h" |
pbos@webrtc.org | 16e03b7 | 2013-10-28 16:32:01 | [diff] [blame] | 19 | #include "webrtc/video_send_stream.h" |
pbos@webrtc.org | 26d1210 | 2013-05-29 13:41:03 | [diff] [blame] | 20 | |
| 21 | namespace webrtc { |
| 22 | namespace test { |
| 23 | |
perkj | a49cbd3 | 2016-09-16 14:53:41 | [diff] [blame] | 24 | FrameGeneratorCapturer* FrameGeneratorCapturer::Create(size_t width, |
Peter Boström | 4b91bd0 | 2015-06-26 04:58:16 | [diff] [blame] | 25 | size_t height, |
| 26 | int target_fps, |
| 27 | Clock* clock) { |
andresp@webrtc.org | ab65495 | 2013-09-19 12:14:03 | [diff] [blame] | 28 | FrameGeneratorCapturer* capturer = new FrameGeneratorCapturer( |
perkj | a49cbd3 | 2016-09-16 14:53:41 | [diff] [blame] | 29 | clock, FrameGenerator::CreateChromaGenerator(width, height), target_fps); |
pbos@webrtc.org | 26d1210 | 2013-05-29 13:41:03 | [diff] [blame] | 30 | if (!capturer->Init()) { |
| 31 | delete capturer; |
| 32 | return NULL; |
| 33 | } |
| 34 | |
| 35 | return capturer; |
| 36 | } |
| 37 | |
andresp@webrtc.org | ab65495 | 2013-09-19 12:14:03 | [diff] [blame] | 38 | FrameGeneratorCapturer* FrameGeneratorCapturer::CreateFromYuvFile( |
sprang@webrtc.org | 131bea8 | 2015-02-18 12:46:06 | [diff] [blame] | 39 | const std::string& file_name, |
andresp@webrtc.org | ab65495 | 2013-09-19 12:14:03 | [diff] [blame] | 40 | size_t width, |
| 41 | size_t height, |
| 42 | int target_fps, |
| 43 | Clock* clock) { |
| 44 | FrameGeneratorCapturer* capturer = new FrameGeneratorCapturer( |
perkj | a49cbd3 | 2016-09-16 14:53:41 | [diff] [blame] | 45 | clock, FrameGenerator::CreateFromYuvFile( |
| 46 | std::vector<std::string>(1, file_name), width, height, 1), |
andresp@webrtc.org | ab65495 | 2013-09-19 12:14:03 | [diff] [blame] | 47 | target_fps); |
| 48 | if (!capturer->Init()) { |
| 49 | delete capturer; |
| 50 | return NULL; |
| 51 | } |
| 52 | |
| 53 | return capturer; |
| 54 | } |
| 55 | |
| 56 | FrameGeneratorCapturer::FrameGeneratorCapturer(Clock* clock, |
andresp@webrtc.org | ab65495 | 2013-09-19 12:14:03 | [diff] [blame] | 57 | FrameGenerator* frame_generator, |
| 58 | int target_fps) |
perkj | a49cbd3 | 2016-09-16 14:53:41 | [diff] [blame] | 59 | : clock_(clock), |
pbos@webrtc.org | 26d1210 | 2013-05-29 13:41:03 | [diff] [blame] | 60 | sending_(false), |
perkj | a49cbd3 | 2016-09-16 14:53:41 | [diff] [blame] | 61 | sink_(nullptr), |
Peter Boström | 64c0366 | 2015-04-08 09:24:19 | [diff] [blame] | 62 | tick_(EventTimerWrapper::Create()), |
Peter Boström | 8c38e8b | 2015-11-26 16:45:47 | [diff] [blame] | 63 | thread_(FrameGeneratorCapturer::Run, this, "FrameGeneratorCapturer"), |
pbos@webrtc.org | 26d1210 | 2013-05-29 13:41:03 | [diff] [blame] | 64 | frame_generator_(frame_generator), |
wu@webrtc.org | cd70119 | 2014-04-24 22:10:24 | [diff] [blame] | 65 | target_fps_(target_fps), |
| 66 | first_frame_capture_time_(-1) { |
perkj | a49cbd3 | 2016-09-16 14:53:41 | [diff] [blame] | 67 | RTC_DCHECK(frame_generator); |
| 68 | RTC_DCHECK_GT(target_fps, 0); |
pbos@webrtc.org | 26d1210 | 2013-05-29 13:41:03 | [diff] [blame] | 69 | } |
| 70 | |
| 71 | FrameGeneratorCapturer::~FrameGeneratorCapturer() { |
| 72 | Stop(); |
| 73 | |
Peter Boström | 8c38e8b | 2015-11-26 16:45:47 | [diff] [blame] | 74 | thread_.Stop(); |
pbos@webrtc.org | 26d1210 | 2013-05-29 13:41:03 | [diff] [blame] | 75 | } |
| 76 | |
Per | ba7dc72 | 2016-04-19 13:01:23 | [diff] [blame] | 77 | void FrameGeneratorCapturer::SetFakeRotation(VideoRotation rotation) { |
| 78 | rtc::CritScope cs(&lock_); |
| 79 | fake_rotation_ = rotation; |
| 80 | } |
| 81 | |
pbos@webrtc.org | 26d1210 | 2013-05-29 13:41:03 | [diff] [blame] | 82 | bool FrameGeneratorCapturer::Init() { |
pbos@webrtc.org | 9401524 | 2013-10-16 11:05:37 | [diff] [blame] | 83 | // This check is added because frame_generator_ might be file based and should |
| 84 | // not crash because a file moved. |
| 85 | if (frame_generator_.get() == NULL) |
| 86 | return false; |
| 87 | |
pbos@webrtc.org | af8d5af | 2013-07-09 08:02:33 | [diff] [blame] | 88 | if (!tick_->StartTimer(true, 1000 / target_fps_)) |
| 89 | return false; |
Peter Boström | 8c38e8b | 2015-11-26 16:45:47 | [diff] [blame] | 90 | thread_.Start(); |
| 91 | thread_.SetPriority(rtc::kHighPriority); |
pbos@webrtc.org | 26d1210 | 2013-05-29 13:41:03 | [diff] [blame] | 92 | return true; |
| 93 | } |
| 94 | |
| 95 | bool FrameGeneratorCapturer::Run(void* obj) { |
| 96 | static_cast<FrameGeneratorCapturer*>(obj)->InsertFrame(); |
| 97 | return true; |
| 98 | } |
| 99 | |
| 100 | void FrameGeneratorCapturer::InsertFrame() { |
pbos@webrtc.org | 26d1210 | 2013-05-29 13:41:03 | [diff] [blame] | 101 | { |
Peter Boström | f2f8283 | 2015-05-01 11:00:41 | [diff] [blame] | 102 | rtc::CritScope cs(&lock_); |
andresp@webrtc.org | ab65495 | 2013-09-19 12:14:03 | [diff] [blame] | 103 | if (sending_) { |
Miguel Casas-Sanchez | 4765070 | 2015-05-30 00:21:40 | [diff] [blame] | 104 | VideoFrame* frame = frame_generator_->NextFrame(); |
perkj@webrtc.org | af612d5 | 2015-03-18 09:51:05 | [diff] [blame] | 105 | frame->set_ntp_time_ms(clock_->CurrentNtpInMilliseconds()); |
Per | ba7dc72 | 2016-04-19 13:01:23 | [diff] [blame] | 106 | frame->set_rotation(fake_rotation_); |
wu@webrtc.org | cd70119 | 2014-04-24 22:10:24 | [diff] [blame] | 107 | if (first_frame_capture_time_ == -1) { |
perkj@webrtc.org | af612d5 | 2015-03-18 09:51:05 | [diff] [blame] | 108 | first_frame_capture_time_ = frame->ntp_time_ms(); |
wu@webrtc.org | cd70119 | 2014-04-24 22:10:24 | [diff] [blame] | 109 | } |
perkj | a49cbd3 | 2016-09-16 14:53:41 | [diff] [blame] | 110 | if (sink_) |
| 111 | sink_->OnFrame(*frame); |
andresp@webrtc.org | ab65495 | 2013-09-19 12:14:03 | [diff] [blame] | 112 | } |
pbos@webrtc.org | 26d1210 | 2013-05-29 13:41:03 | [diff] [blame] | 113 | } |
pbos@webrtc.org | af8d5af | 2013-07-09 08:02:33 | [diff] [blame] | 114 | tick_->Wait(WEBRTC_EVENT_INFINITE); |
pbos@webrtc.org | 26d1210 | 2013-05-29 13:41:03 | [diff] [blame] | 115 | } |
| 116 | |
| 117 | void FrameGeneratorCapturer::Start() { |
Peter Boström | f2f8283 | 2015-05-01 11:00:41 | [diff] [blame] | 118 | rtc::CritScope cs(&lock_); |
pbos@webrtc.org | 26d1210 | 2013-05-29 13:41:03 | [diff] [blame] | 119 | sending_ = true; |
| 120 | } |
| 121 | |
| 122 | void FrameGeneratorCapturer::Stop() { |
Peter Boström | f2f8283 | 2015-05-01 11:00:41 | [diff] [blame] | 123 | rtc::CritScope cs(&lock_); |
pbos@webrtc.org | 26d1210 | 2013-05-29 13:41:03 | [diff] [blame] | 124 | sending_ = false; |
| 125 | } |
sprang | 867fb52 | 2015-08-03 11:38:41 | [diff] [blame] | 126 | |
perkj | fa10b55 | 2016-10-03 06:45:26 | [diff] [blame] | 127 | void FrameGeneratorCapturer::ChangeResolution(size_t width, size_t height) { |
| 128 | rtc::CritScope cs(&lock_); |
| 129 | frame_generator_->ChangeResolution(width, height); |
| 130 | } |
| 131 | |
perkj | a49cbd3 | 2016-09-16 14:53:41 | [diff] [blame] | 132 | void FrameGeneratorCapturer::AddOrUpdateSink( |
| 133 | rtc::VideoSinkInterface<VideoFrame>* sink, |
| 134 | const rtc::VideoSinkWants& wants) { |
| 135 | rtc::CritScope cs(&lock_); |
| 136 | RTC_CHECK(!sink_); |
| 137 | sink_ = sink; |
| 138 | } |
| 139 | |
| 140 | void FrameGeneratorCapturer::RemoveSink( |
| 141 | rtc::VideoSinkInterface<VideoFrame>* sink) { |
| 142 | rtc::CritScope cs(&lock_); |
| 143 | RTC_CHECK(sink_ == sink); |
| 144 | sink_ = nullptr; |
| 145 | } |
| 146 | |
sprang | 867fb52 | 2015-08-03 11:38:41 | [diff] [blame] | 147 | void FrameGeneratorCapturer::ForceFrame() { |
| 148 | tick_->Set(); |
| 149 | } |
pbos@webrtc.org | 26d1210 | 2013-05-29 13:41:03 | [diff] [blame] | 150 | } // test |
| 151 | } // webrtc |