1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Use of this source code is governed by a BSD-style license 5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * that can be found in the LICENSE file in the root of the source 6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * tree. An additional intellectual property rights grant can be found 7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * in the file PATENTS. All contributing project authors may 8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 10281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/test/libvietest/include/vie_file_capture_device.h" 11b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <assert.h> 13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 14281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/common_types.h" 15281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/modules/interface/module_common_types.h" 16281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 17281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/system_wrappers/interface/event_wrapper.h" 18281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/system_wrappers/interface/tick_util.h" 19281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/include/vie_capture.h" 20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// This class ensures we are not exceeding the max FPS. 22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass FramePacemaker { 23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public: 24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org explicit FramePacemaker(uint32_t max_fps) 25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org : time_per_frame_ms_(1000 / max_fps) { 26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org frame_start_ = webrtc::TickTime::MillisecondTimestamp(); 27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void SleepIfNecessary(webrtc::EventWrapper* sleeper) { 30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint64_t now = webrtc::TickTime::MillisecondTimestamp(); 31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (now - frame_start_ < time_per_frame_ms_) { 32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sleeper->Wait(time_per_frame_ms_ - (now - frame_start_)); 33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org private: 37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint64_t frame_start_; 38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint64_t time_per_frame_ms_; 39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}; 40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgViEFileCaptureDevice::ViEFileCaptureDevice( 42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org webrtc::ViEExternalCapture* input_sink) 43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org : input_sink_(input_sink), 44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org input_file_(NULL) { 45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mutex_ = webrtc::CriticalSectionWrapper::CreateCriticalSection(); 46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgViEFileCaptureDevice::~ViEFileCaptureDevice() { 49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete mutex_; 50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool ViEFileCaptureDevice::OpenI420File(const std::string& path, 53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int width, 54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int height) { 55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org webrtc::CriticalSectionScoped cs(mutex_); 56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(input_file_ == NULL); 57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 583f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org input_file_ = fopen(path.c_str(), "rb"); 59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (input_file_ == NULL) { 60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return false; 61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org frame_length_ = 3 * width * height / 2; 64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org width_ = width; 65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org height_ = height; 66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return true; 67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid ViEFileCaptureDevice::ReadFileFor(uint64_t time_slice_ms, 70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint32_t max_fps) { 71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org webrtc::CriticalSectionScoped cs(mutex_); 72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(input_file_ != NULL); 73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org unsigned char* frame_buffer = new unsigned char[frame_length_]; 75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org webrtc::EventWrapper* sleeper = webrtc::EventWrapper::Create(); 77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint64_t start_time_ms = webrtc::TickTime::MillisecondTimestamp(); 79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint64_t elapsed_ms = 0; 80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org while (elapsed_ms < time_slice_ms) { 82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org FramePacemaker pacemaker(max_fps); 833f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org int read = fread(frame_buffer, 1, frame_length_, input_file_); 84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 853f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org if (feof(input_file_)) { 863f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org rewind(input_file_); 87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org input_sink_->IncomingFrame(frame_buffer, read, width_, height_, 89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org webrtc::kVideoI420, 90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org webrtc::TickTime::MillisecondTimestamp()); 91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pacemaker.SleepIfNecessary(sleeper); 93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org elapsed_ms = webrtc::TickTime::MillisecondTimestamp() - start_time_ms; 94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete sleeper; 97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete[] frame_buffer; 98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid ViEFileCaptureDevice::CloseFile() { 101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org webrtc::CriticalSectionScoped cs(mutex_); 102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(input_file_ != NULL); 103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1043f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org fclose(input_file_); 105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 106