blob: e04961dd211c7f7fa41e9d73d83965c56437c47a [file] [log] [blame]
pbos@webrtc.org26d12102013-05-29 13:41:03 +00001/*
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
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000011#include "webrtc/test/frame_generator_capturer.h"
pbos@webrtc.org26d12102013-05-29 13:41:03 +000012
andresp@webrtc.orgab654952013-09-19 12:14:03 +000013#include "webrtc/common_video/test/frame_generator.h"
14#include "webrtc/system_wrappers/interface/clock.h"
pbos@webrtc.org26d12102013-05-29 13:41:03 +000015#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000016#include "webrtc/system_wrappers/interface/event_wrapper.h"
pbos@webrtc.org26d12102013-05-29 13:41:03 +000017#include "webrtc/system_wrappers/interface/sleep.h"
18#include "webrtc/system_wrappers/interface/thread_wrapper.h"
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000019#include "webrtc/video_send_stream.h"
pbos@webrtc.org26d12102013-05-29 13:41:03 +000020
21namespace webrtc {
22namespace test {
23
24FrameGeneratorCapturer* FrameGeneratorCapturer::Create(
pbos@webrtc.org74fa4892013-08-23 09:19:30 +000025 VideoSendStreamInput* input,
andresp@webrtc.orgab654952013-09-19 12:14:03 +000026 size_t width,
27 size_t height,
28 int target_fps,
29 Clock* clock) {
30 FrameGeneratorCapturer* capturer = new FrameGeneratorCapturer(
pbos@webrtc.org266c7b32013-10-15 09:15:47 +000031 clock, input, FrameGenerator::Create(width, height), target_fps);
pbos@webrtc.org26d12102013-05-29 13:41:03 +000032 if (!capturer->Init()) {
33 delete capturer;
34 return NULL;
35 }
36
37 return capturer;
38}
39
andresp@webrtc.orgab654952013-09-19 12:14:03 +000040FrameGeneratorCapturer* FrameGeneratorCapturer::CreateFromYuvFile(
pbos@webrtc.org74fa4892013-08-23 09:19:30 +000041 VideoSendStreamInput* input,
andresp@webrtc.orgab654952013-09-19 12:14:03 +000042 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
60FrameGeneratorCapturer::FrameGeneratorCapturer(Clock* clock,
61 VideoSendStreamInput* input,
62 FrameGenerator* frame_generator,
63 int target_fps)
pbos@webrtc.org26d12102013-05-29 13:41:03 +000064 : VideoCapturer(input),
andresp@webrtc.orgab654952013-09-19 12:14:03 +000065 clock_(clock),
pbos@webrtc.org26d12102013-05-29 13:41:03 +000066 sending_(false),
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000067 tick_(EventWrapper::Create()),
pbos@webrtc.org26d12102013-05-29 13:41:03 +000068 lock_(CriticalSectionWrapper::CreateCriticalSection()),
pbos@webrtc.org26d12102013-05-29 13:41:03 +000069 frame_generator_(frame_generator),
70 target_fps_(target_fps) {
71 assert(input != NULL);
72 assert(frame_generator != NULL);
73 assert(target_fps > 0);
74}
75
76FrameGeneratorCapturer::~FrameGeneratorCapturer() {
77 Stop();
78
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000079 if (thread_.get() != NULL)
80 thread_->Stop();
pbos@webrtc.org26d12102013-05-29 13:41:03 +000081}
82
83bool FrameGeneratorCapturer::Init() {
pbos@webrtc.org94015242013-10-16 11:05:37 +000084 // 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
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000089 if (!tick_->StartTimer(true, 1000 / target_fps_))
90 return false;
91 thread_.reset(ThreadWrapper::CreateThread(FrameGeneratorCapturer::Run,
92 this,
93 webrtc::kHighPriority,
94 "FrameGeneratorCapturer"));
95 if (thread_.get() == NULL)
pbos@webrtc.org26d12102013-05-29 13:41:03 +000096 return false;
97 unsigned int thread_id;
98 if (!thread_->Start(thread_id)) {
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000099 thread_.reset();
pbos@webrtc.org26d12102013-05-29 13:41:03 +0000100 return false;
101 }
102 return true;
103}
104
105bool FrameGeneratorCapturer::Run(void* obj) {
106 static_cast<FrameGeneratorCapturer*>(obj)->InsertFrame();
107 return true;
108}
109
110void FrameGeneratorCapturer::InsertFrame() {
pbos@webrtc.org26d12102013-05-29 13:41:03 +0000111 {
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000112 CriticalSectionScoped cs(lock_.get());
andresp@webrtc.orgab654952013-09-19 12:14:03 +0000113 if (sending_) {
114 int64_t time_before = clock_->CurrentNtpInMilliseconds();
115 I420VideoFrame& frame = frame_generator_->NextFrame();
116 frame.set_render_time_ms(time_before);
117 int64_t time_after = clock_->CurrentNtpInMilliseconds();
118 input_->PutFrame(frame, static_cast<uint32_t>(time_after - time_before));
119 }
pbos@webrtc.org26d12102013-05-29 13:41:03 +0000120 }
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000121 tick_->Wait(WEBRTC_EVENT_INFINITE);
pbos@webrtc.org26d12102013-05-29 13:41:03 +0000122}
123
124void FrameGeneratorCapturer::Start() {
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000125 CriticalSectionScoped cs(lock_.get());
pbos@webrtc.org26d12102013-05-29 13:41:03 +0000126 sending_ = true;
127}
128
129void FrameGeneratorCapturer::Stop() {
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000130 CriticalSectionScoped cs(lock_.get());
pbos@webrtc.org26d12102013-05-29 13:41:03 +0000131 sending_ = false;
132}
133} // test
134} // webrtc