1c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org/* 2c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 3c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org * 4c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org * Use of this source code is governed by a BSD-style license 5c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org * that can be found in the LICENSE file in the root of the source 6c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org * tree. An additional intellectual property rights grant can be found 7c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org * in the file PATENTS. All contributing project authors may 8c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org */ 10c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org 1124e2089750e9e51228b82d6c7ebf4fa064c797bapbos@webrtc.org#include "webrtc/test/frame_generator_capturer.h" 12c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org 13c33d37ce205e22c0e090b0b285ed963686bf24dcpbos@webrtc.org#include "webrtc/test/frame_generator.h" 1428631e76cf7bcb40532069eecfe65f6290c05cd4andresp@webrtc.org#include "webrtc/system_wrappers/interface/clock.h" 15c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 162f02da89501237cefea455cf31a1553125f62ad7pbos@webrtc.org#include "webrtc/system_wrappers/interface/event_wrapper.h" 17c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org#include "webrtc/system_wrappers/interface/sleep.h" 18c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org#include "webrtc/system_wrappers/interface/thread_wrapper.h" 1924e2089750e9e51228b82d6c7ebf4fa064c797bapbos@webrtc.org#include "webrtc/video_send_stream.h" 20c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org 21c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.orgnamespace webrtc { 22c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.orgnamespace test { 23c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org 24c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.orgFrameGeneratorCapturer* FrameGeneratorCapturer::Create( 25c1797061756f40b9b1f3f3e82fc040ce18ecd43cpbos@webrtc.org VideoSendStreamInput* input, 2628631e76cf7bcb40532069eecfe65f6290c05cd4andresp@webrtc.org size_t width, 2728631e76cf7bcb40532069eecfe65f6290c05cd4andresp@webrtc.org size_t height, 2828631e76cf7bcb40532069eecfe65f6290c05cd4andresp@webrtc.org int target_fps, 2928631e76cf7bcb40532069eecfe65f6290c05cd4andresp@webrtc.org Clock* clock) { 3028631e76cf7bcb40532069eecfe65f6290c05cd4andresp@webrtc.org FrameGeneratorCapturer* capturer = new FrameGeneratorCapturer( 31e2c52d725d7af76fc84e6bd1443c4bd7632c7331pbos@webrtc.org clock, input, FrameGenerator::Create(width, height), target_fps); 32c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org if (!capturer->Init()) { 33c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org delete capturer; 34c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org return NULL; 35c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org } 36c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org 37c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org return capturer; 38c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org} 39c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org 4028631e76cf7bcb40532069eecfe65f6290c05cd4andresp@webrtc.orgFrameGeneratorCapturer* FrameGeneratorCapturer::CreateFromYuvFile( 41c1797061756f40b9b1f3f3e82fc040ce18ecd43cpbos@webrtc.org VideoSendStreamInput* input, 4228631e76cf7bcb40532069eecfe65f6290c05cd4andresp@webrtc.org const char* file_name, 4328631e76cf7bcb40532069eecfe65f6290c05cd4andresp@webrtc.org size_t width, 4428631e76cf7bcb40532069eecfe65f6290c05cd4andresp@webrtc.org size_t height, 4528631e76cf7bcb40532069eecfe65f6290c05cd4andresp@webrtc.org int target_fps, 4628631e76cf7bcb40532069eecfe65f6290c05cd4andresp@webrtc.org Clock* clock) { 4728631e76cf7bcb40532069eecfe65f6290c05cd4andresp@webrtc.org FrameGeneratorCapturer* capturer = new FrameGeneratorCapturer( 4828631e76cf7bcb40532069eecfe65f6290c05cd4andresp@webrtc.org clock, 4928631e76cf7bcb40532069eecfe65f6290c05cd4andresp@webrtc.org input, 5028631e76cf7bcb40532069eecfe65f6290c05cd4andresp@webrtc.org FrameGenerator::CreateFromYuvFile(file_name, width, height), 5128631e76cf7bcb40532069eecfe65f6290c05cd4andresp@webrtc.org target_fps); 5228631e76cf7bcb40532069eecfe65f6290c05cd4andresp@webrtc.org if (!capturer->Init()) { 5328631e76cf7bcb40532069eecfe65f6290c05cd4andresp@webrtc.org delete capturer; 5428631e76cf7bcb40532069eecfe65f6290c05cd4andresp@webrtc.org return NULL; 5528631e76cf7bcb40532069eecfe65f6290c05cd4andresp@webrtc.org } 5628631e76cf7bcb40532069eecfe65f6290c05cd4andresp@webrtc.org 5728631e76cf7bcb40532069eecfe65f6290c05cd4andresp@webrtc.org return capturer; 5828631e76cf7bcb40532069eecfe65f6290c05cd4andresp@webrtc.org} 5928631e76cf7bcb40532069eecfe65f6290c05cd4andresp@webrtc.org 6028631e76cf7bcb40532069eecfe65f6290c05cd4andresp@webrtc.orgFrameGeneratorCapturer::FrameGeneratorCapturer(Clock* clock, 6128631e76cf7bcb40532069eecfe65f6290c05cd4andresp@webrtc.org VideoSendStreamInput* input, 6228631e76cf7bcb40532069eecfe65f6290c05cd4andresp@webrtc.org FrameGenerator* frame_generator, 6328631e76cf7bcb40532069eecfe65f6290c05cd4andresp@webrtc.org int target_fps) 64c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org : VideoCapturer(input), 6528631e76cf7bcb40532069eecfe65f6290c05cd4andresp@webrtc.org clock_(clock), 66c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org sending_(false), 672f02da89501237cefea455cf31a1553125f62ad7pbos@webrtc.org tick_(EventWrapper::Create()), 68c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org lock_(CriticalSectionWrapper::CreateCriticalSection()), 69c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org frame_generator_(frame_generator), 70093fc0b0b0b9ca4fe56a32e17c9c418382e802f0wu@webrtc.org target_fps_(target_fps), 71093fc0b0b0b9ca4fe56a32e17c9c418382e802f0wu@webrtc.org first_frame_capture_time_(-1) { 72c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org assert(input != NULL); 73c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org assert(frame_generator != NULL); 74c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org assert(target_fps > 0); 75c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org} 76c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org 77c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.orgFrameGeneratorCapturer::~FrameGeneratorCapturer() { 78c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org Stop(); 79c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org 802f02da89501237cefea455cf31a1553125f62ad7pbos@webrtc.org if (thread_.get() != NULL) 812f02da89501237cefea455cf31a1553125f62ad7pbos@webrtc.org thread_->Stop(); 82c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org} 83c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org 84c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.orgbool FrameGeneratorCapturer::Init() { 85a24c3560787e59d93663a960ee48d36ec86f21d2pbos@webrtc.org // This check is added because frame_generator_ might be file based and should 86a24c3560787e59d93663a960ee48d36ec86f21d2pbos@webrtc.org // not crash because a file moved. 87a24c3560787e59d93663a960ee48d36ec86f21d2pbos@webrtc.org if (frame_generator_.get() == NULL) 88a24c3560787e59d93663a960ee48d36ec86f21d2pbos@webrtc.org return false; 89a24c3560787e59d93663a960ee48d36ec86f21d2pbos@webrtc.org 902f02da89501237cefea455cf31a1553125f62ad7pbos@webrtc.org if (!tick_->StartTimer(true, 1000 / target_fps_)) 912f02da89501237cefea455cf31a1553125f62ad7pbos@webrtc.org return false; 922f02da89501237cefea455cf31a1553125f62ad7pbos@webrtc.org thread_.reset(ThreadWrapper::CreateThread(FrameGeneratorCapturer::Run, 932f02da89501237cefea455cf31a1553125f62ad7pbos@webrtc.org this, 942f02da89501237cefea455cf31a1553125f62ad7pbos@webrtc.org webrtc::kHighPriority, 952f02da89501237cefea455cf31a1553125f62ad7pbos@webrtc.org "FrameGeneratorCapturer")); 962f02da89501237cefea455cf31a1553125f62ad7pbos@webrtc.org if (thread_.get() == NULL) 97c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org return false; 98c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org unsigned int thread_id; 99c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org if (!thread_->Start(thread_id)) { 1002f02da89501237cefea455cf31a1553125f62ad7pbos@webrtc.org thread_.reset(); 101c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org return false; 102c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org } 103c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org return true; 104c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org} 105c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org 106c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.orgbool FrameGeneratorCapturer::Run(void* obj) { 107c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org static_cast<FrameGeneratorCapturer*>(obj)->InsertFrame(); 108c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org return true; 109c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org} 110c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org 111c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.orgvoid FrameGeneratorCapturer::InsertFrame() { 112c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org { 1132f02da89501237cefea455cf31a1553125f62ad7pbos@webrtc.org CriticalSectionScoped cs(lock_.get()); 11428631e76cf7bcb40532069eecfe65f6290c05cd4andresp@webrtc.org if (sending_) { 115c33d37ce205e22c0e090b0b285ed963686bf24dcpbos@webrtc.org I420VideoFrame* frame = frame_generator_->NextFrame(); 116c33d37ce205e22c0e090b0b285ed963686bf24dcpbos@webrtc.org frame->set_render_time_ms(clock_->CurrentNtpInMilliseconds()); 117093fc0b0b0b9ca4fe56a32e17c9c418382e802f0wu@webrtc.org if (first_frame_capture_time_ == -1) { 118093fc0b0b0b9ca4fe56a32e17c9c418382e802f0wu@webrtc.org first_frame_capture_time_ = frame->render_time_ms(); 119093fc0b0b0b9ca4fe56a32e17c9c418382e802f0wu@webrtc.org } 120c33d37ce205e22c0e090b0b285ed963686bf24dcpbos@webrtc.org input_->SwapFrame(frame); 12128631e76cf7bcb40532069eecfe65f6290c05cd4andresp@webrtc.org } 122c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org } 1232f02da89501237cefea455cf31a1553125f62ad7pbos@webrtc.org tick_->Wait(WEBRTC_EVENT_INFINITE); 124c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org} 125c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org 126c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.orgvoid FrameGeneratorCapturer::Start() { 1272f02da89501237cefea455cf31a1553125f62ad7pbos@webrtc.org CriticalSectionScoped cs(lock_.get()); 128c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org sending_ = true; 129c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org} 130c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org 131c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.orgvoid FrameGeneratorCapturer::Stop() { 1322f02da89501237cefea455cf31a1553125f62ad7pbos@webrtc.org CriticalSectionScoped cs(lock_.get()); 133c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org sending_ = false; 134c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org} 135c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org} // test 136c1506a215f1376938c91459abeb1cd05201df278pbos@webrtc.org} // webrtc 137