3
* Copyright 2011, Google Inc.
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions are met:
8
* 1. Redistributions of source code must retain the above copyright notice,
9
* this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright notice,
11
* this list of conditions and the following disclaimer in the documentation
12
* and/or other materials provided with the distribution.
13
* 3. The name of the author may not be used to endorse or promote products
14
* derived from this software without specific prior written permission.
16
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
#include "talk/app/webrtc/test/fakevideocapturemodule.h"
30
#include "talk/app/webrtc/test/fileframesource.h"
31
#include "talk/app/webrtc/test/i420framesource.h"
32
#include "talk/app/webrtc/test/staticframesource.h"
33
#include "talk/base/refcount.h"
34
#include "talk/base/stream.h"
35
#include "talk/base/thread.h"
37
#ifdef WEBRTC_RELATIVE_PATH
38
#include "modules/video_capture/main/interface/video_capture_defines.h"
39
#include "modules/video_capture/main/interface/video_capture_factory.h"
41
#include "third_party/webrtc/files/include/video_capture_defines.h"
42
#include "third_party/webrtc/files/include/video_capture_factory.h"
45
static const int kStartFrameRate = 30;
46
static const int kStartWidth = 352;
47
static const int kStartHeight = 288;
48
static const uint32 kStartTimeStamp = 2000;
50
FakeVideoCaptureModule::FakeVideoCaptureModule(talk_base::Thread* camera_thread)
51
: frame_source_(NULL),
52
camera_thread_(camera_thread),
55
capture_started_(false),
58
time_per_frame_ms_(0),
63
FakeVideoCaptureModule::~FakeVideoCaptureModule() {
65
// The memory associated with video_capture_ is owned by impl_.
68
FakeVideoCaptureModule*
69
FakeVideoCaptureModule::Create(talk_base::Thread* camera_thread) {
70
talk_base::RefCountedObject<FakeVideoCaptureModule>* capture_module =
71
new talk_base::RefCountedObject<FakeVideoCaptureModule>(camera_thread);
72
if (!capture_module->Init(new StaticFrameSource())) {
73
delete capture_module;
76
return capture_module;
79
FakeVideoCaptureModule*
80
FakeVideoCaptureModule::Create(talk_base::Thread* camera_thread,
81
const std::string& file_name) {
82
talk_base::RefCountedObject<FakeVideoCaptureModule>* capture_module =
83
new talk_base::RefCountedObject<FakeVideoCaptureModule>(camera_thread);
84
if (!capture_module->Init(FileFrameSource::Create(file_name))) {
85
delete capture_module;
88
return capture_module;
91
void FakeVideoCaptureModule::StartCapturing() {
92
camera_thread_->Clear(this);
93
// Only one post, no need to add any data to post.
94
camera_thread_->Post(this);
97
void FakeVideoCaptureModule::StopCapturing() {
98
camera_thread_->Clear(this);
101
bool FakeVideoCaptureModule::RegisterFrameSource(
102
I420FrameSource* frame_source) {
103
if (frame_source == NULL) {
106
frame_source_ = frame_source;
107
frame_source_->SetFrameSize(width_, height_);
111
// TODO: deal with the rounding error.
112
bool FakeVideoCaptureModule::SetFrameRate(int fps) {
117
time_per_frame_ms_ = 1000 / fps;
121
void FakeVideoCaptureModule::SetSize(int width, int height) {
124
image_.reset(new uint8[GetI420FrameLengthInBytes()]);
125
if (frame_source_ != NULL) {
126
frame_source_->SetFrameSize(width_, height_);
130
bool FakeVideoCaptureModule::Init(I420FrameSource* frame_source) {
131
if (!RegisterFrameSource(frame_source)) {
134
SetSize(kStartWidth, kStartHeight);
135
impl_ = webrtc::VideoCaptureFactory::Create(0, // id
137
if (impl_.get() == NULL) {
140
if (video_capture_ == NULL) {
143
if (!SetFrameRate(kStartFrameRate)) {
149
// TODO: handle time wrapparound.
150
void FakeVideoCaptureModule::GenerateNewFrame() {
152
next_frame_time_ = talk_base::Time();
156
if (frame_source_->GetFrame(image_.get(), &read)) {
157
ASSERT(read == GetI420FrameLengthInBytes());
159
webrtc::VideoCaptureCapability capability;
160
capability.width = width_;
161
capability.height = height_;
162
capability.rawType = webrtc::kVideoI420;
163
video_capture_->IncomingFrame(image_.get(), GetI420FrameLengthInBytes(),
164
capability, GetTimestamp());
170
next_frame_time_ += time_per_frame_ms_;
171
const uint32 current_time = talk_base::Time();
172
const uint32 wait_time = (next_frame_time_ > current_time) ?
173
next_frame_time_ - current_time : 0;
174
camera_thread_->PostDelayed(wait_time, this);
177
size_t FakeVideoCaptureModule::GetI420FrameLengthInBytes() {
178
return webrtc_testing::GetI420FrameLengthInBytes(width_, height_);
181
// TODO: handle timestamp wrapparound.
182
uint32 FakeVideoCaptureModule::GetTimestamp() {
183
return kStartTimeStamp + sent_frames_ * time_per_frame_ms_;