• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
Create(VideoCaptureInput * input,size_t width,size_t height,int target_fps,Clock * clock)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 
CreateFromYuvFile(VideoCaptureInput * input,const std::string & file_name,size_t width,size_t height,int target_fps,Clock * clock)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 
FrameGeneratorCapturer(Clock * clock,VideoCaptureInput * input,FrameGenerator * frame_generator,int target_fps)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 
~FrameGeneratorCapturer()77 FrameGeneratorCapturer::~FrameGeneratorCapturer() {
78   Stop();
79 
80   thread_.Stop();
81 }
82 
Init()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 
Run(void * obj)96 bool FrameGeneratorCapturer::Run(void* obj) {
97   static_cast<FrameGeneratorCapturer*>(obj)->InsertFrame();
98   return true;
99 }
100 
InsertFrame()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 
Start()116 void FrameGeneratorCapturer::Start() {
117   rtc::CritScope cs(&lock_);
118   sending_ = true;
119 }
120 
Stop()121 void FrameGeneratorCapturer::Stop() {
122   rtc::CritScope cs(&lock_);
123   sending_ = false;
124 }
125 
ForceFrame()126 void FrameGeneratorCapturer::ForceFrame() {
127   tick_->Set();
128 }
129 }  // test
130 }  // webrtc
131