Home | History | Annotate | Download | only in test
      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