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 11 #include "webrtc/test/frame_generator_capturer.h" 12 13 #include "webrtc/base/criticalsection.h" 14 #include "webrtc/base/platform_thread.h" 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" 18 #include "webrtc/test/frame_generator.h" 19 #include "webrtc/video_send_stream.h" 20 21 namespace webrtc { 22 namespace test { 23 24 FrameGeneratorCapturer* FrameGeneratorCapturer::Create(VideoCaptureInput* input, 25 size_t width, 26 size_t height, 27 int target_fps, 28 Clock* clock) { 29 FrameGeneratorCapturer* capturer = new FrameGeneratorCapturer( 30 clock, input, FrameGenerator::CreateChromaGenerator(width, height), 31 target_fps); 32 if (!capturer->Init()) { 33 delete capturer; 34 return NULL; 35 } 36 37 return capturer; 38 } 39 40 FrameGeneratorCapturer* FrameGeneratorCapturer::CreateFromYuvFile( 41 VideoCaptureInput* input, 42 const std::string& file_name, 43 size_t width, 44 size_t height, 45 int target_fps, 46 Clock* clock) { 47 FrameGeneratorCapturer* capturer = new FrameGeneratorCapturer( 48 clock, input, 49 FrameGenerator::CreateFromYuvFile(std::vector<std::string>(1, file_name), 50 width, height, 1), 51 target_fps); 52 if (!capturer->Init()) { 53 delete capturer; 54 return NULL; 55 } 56 57 return capturer; 58 } 59 60 FrameGeneratorCapturer::FrameGeneratorCapturer(Clock* clock, 61 VideoCaptureInput* input, 62 FrameGenerator* frame_generator, 63 int target_fps) 64 : VideoCapturer(input), 65 clock_(clock), 66 sending_(false), 67 tick_(EventTimerWrapper::Create()), 68 thread_(FrameGeneratorCapturer::Run, this, "FrameGeneratorCapturer"), 69 frame_generator_(frame_generator), 70 target_fps_(target_fps), 71 first_frame_capture_time_(-1) { 72 assert(input != NULL); 73 assert(frame_generator != NULL); 74 assert(target_fps > 0); 75 } 76 77 FrameGeneratorCapturer::~FrameGeneratorCapturer() { 78 Stop(); 79 80 thread_.Stop(); 81 } 82 83 bool FrameGeneratorCapturer::Init() { 84 // This check is added because frame_generator_ might be file based and should 85 // not crash because a file moved. 86 if (frame_generator_.get() == NULL) 87 return false; 88 89 if (!tick_->StartTimer(true, 1000 / target_fps_)) 90 return false; 91 thread_.Start(); 92 thread_.SetPriority(rtc::kHighPriority); 93 return true; 94 } 95 96 bool FrameGeneratorCapturer::Run(void* obj) { 97 static_cast<FrameGeneratorCapturer*>(obj)->InsertFrame(); 98 return true; 99 } 100 101 void FrameGeneratorCapturer::InsertFrame() { 102 { 103 rtc::CritScope cs(&lock_); 104 if (sending_) { 105 VideoFrame* frame = frame_generator_->NextFrame(); 106 frame->set_ntp_time_ms(clock_->CurrentNtpInMilliseconds()); 107 if (first_frame_capture_time_ == -1) { 108 first_frame_capture_time_ = frame->ntp_time_ms(); 109 } 110 input_->IncomingCapturedFrame(*frame); 111 } 112 } 113 tick_->Wait(WEBRTC_EVENT_INFINITE); 114 } 115 116 void FrameGeneratorCapturer::Start() { 117 rtc::CritScope cs(&lock_); 118 sending_ = true; 119 } 120 121 void FrameGeneratorCapturer::Stop() { 122 rtc::CritScope cs(&lock_); 123 sending_ = false; 124 } 125 126 void FrameGeneratorCapturer::ForceFrame() { 127 tick_->Set(); 128 } 129 } // test 130 } // webrtc 131