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/test/frame_generator.h"
     14 #include "webrtc/system_wrappers/interface/clock.h"
     15 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
     16 #include "webrtc/system_wrappers/interface/event_wrapper.h"
     17 #include "webrtc/system_wrappers/interface/sleep.h"
     18 #include "webrtc/system_wrappers/interface/thread_wrapper.h"
     19 #include "webrtc/video_send_stream.h"
     20 
     21 namespace webrtc {
     22 namespace test {
     23 
     24 FrameGeneratorCapturer* FrameGeneratorCapturer::Create(
     25     VideoSendStreamInput* input,
     26     size_t width,
     27     size_t height,
     28     int target_fps,
     29     Clock* clock) {
     30   FrameGeneratorCapturer* capturer = new FrameGeneratorCapturer(
     31       clock, input, FrameGenerator::Create(width, height), target_fps);
     32   if (!capturer->Init()) {
     33     delete capturer;
     34     return NULL;
     35   }
     36 
     37   return capturer;
     38 }
     39 
     40 FrameGeneratorCapturer* FrameGeneratorCapturer::CreateFromYuvFile(
     41     VideoSendStreamInput* input,
     42     const char* file_name,
     43     size_t width,
     44     size_t height,
     45     int target_fps,
     46     Clock* clock) {
     47   FrameGeneratorCapturer* capturer = new FrameGeneratorCapturer(
     48       clock,
     49       input,
     50       FrameGenerator::CreateFromYuvFile(file_name, width, height),
     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                                                VideoSendStreamInput* input,
     62                                                FrameGenerator* frame_generator,
     63                                                int target_fps)
     64     : VideoCapturer(input),
     65       clock_(clock),
     66       sending_(false),
     67       tick_(EventWrapper::Create()),
     68       lock_(CriticalSectionWrapper::CreateCriticalSection()),
     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   if (thread_.get() != NULL)
     81     thread_->Stop();
     82 }
     83 
     84 bool FrameGeneratorCapturer::Init() {
     85   // This check is added because frame_generator_ might be file based and should
     86   // not crash because a file moved.
     87   if (frame_generator_.get() == NULL)
     88     return false;
     89 
     90   if (!tick_->StartTimer(true, 1000 / target_fps_))
     91     return false;
     92   thread_.reset(ThreadWrapper::CreateThread(FrameGeneratorCapturer::Run,
     93                                             this,
     94                                             webrtc::kHighPriority,
     95                                             "FrameGeneratorCapturer"));
     96   if (thread_.get() == NULL)
     97     return false;
     98   unsigned int thread_id;
     99   if (!thread_->Start(thread_id)) {
    100     thread_.reset();
    101     return false;
    102   }
    103   return true;
    104 }
    105 
    106 bool FrameGeneratorCapturer::Run(void* obj) {
    107   static_cast<FrameGeneratorCapturer*>(obj)->InsertFrame();
    108   return true;
    109 }
    110 
    111 void FrameGeneratorCapturer::InsertFrame() {
    112   {
    113     CriticalSectionScoped cs(lock_.get());
    114     if (sending_) {
    115       I420VideoFrame* frame = frame_generator_->NextFrame();
    116       frame->set_render_time_ms(clock_->CurrentNtpInMilliseconds());
    117       if (first_frame_capture_time_ == -1) {
    118         first_frame_capture_time_ = frame->render_time_ms();
    119       }
    120       input_->SwapFrame(frame);
    121     }
    122   }
    123   tick_->Wait(WEBRTC_EVENT_INFINITE);
    124 }
    125 
    126 void FrameGeneratorCapturer::Start() {
    127   CriticalSectionScoped cs(lock_.get());
    128   sending_ = true;
    129 }
    130 
    131 void FrameGeneratorCapturer::Stop() {
    132   CriticalSectionScoped cs(lock_.get());
    133   sending_ = false;
    134 }
    135 }  // test
    136 }  // webrtc
    137