OLD | NEW |
| (Empty) |
1 /* | |
2 * libjingle | |
3 * Copyright 2004 Google Inc. | |
4 * | |
5 * Redistribution and use in source and binary forms, with or without | |
6 * modification, are permitted provided that the following conditions are met: | |
7 * | |
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. | |
15 * | |
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. | |
26 */ | |
27 | |
28 #ifndef TALK_MEDIA_BASE_FAKEVIDEOCAPTURER_H_ | |
29 #define TALK_MEDIA_BASE_FAKEVIDEOCAPTURER_H_ | |
30 | |
31 #include <string.h> | |
32 | |
33 #include <vector> | |
34 | |
35 #include "talk/media/base/videocapturer.h" | |
36 #include "talk/media/base/videocommon.h" | |
37 #include "talk/media/base/videoframe.h" | |
38 #include "webrtc/base/timeutils.h" | |
39 #ifdef HAVE_WEBRTC_VIDEO | |
40 #include "talk/media/webrtc/webrtcvideoframefactory.h" | |
41 #endif | |
42 | |
43 namespace cricket { | |
44 | |
45 // Fake video capturer that allows the test to manually pump in frames. | |
46 class FakeVideoCapturer : public cricket::VideoCapturer { | |
47 public: | |
48 FakeVideoCapturer() | |
49 : running_(false), | |
50 initial_unix_timestamp_(time(NULL) * rtc::kNumNanosecsPerSec), | |
51 next_timestamp_(rtc::kNumNanosecsPerMillisec), | |
52 is_screencast_(false), | |
53 rotation_(webrtc::kVideoRotation_0) { | |
54 #ifdef HAVE_WEBRTC_VIDEO | |
55 set_frame_factory(new cricket::WebRtcVideoFrameFactory()); | |
56 #endif | |
57 // Default supported formats. Use ResetSupportedFormats to over write. | |
58 std::vector<cricket::VideoFormat> formats; | |
59 formats.push_back(cricket::VideoFormat(1280, 720, | |
60 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420)); | |
61 formats.push_back(cricket::VideoFormat(640, 480, | |
62 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420)); | |
63 formats.push_back(cricket::VideoFormat(320, 240, | |
64 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420)); | |
65 formats.push_back(cricket::VideoFormat(160, 120, | |
66 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420)); | |
67 formats.push_back(cricket::VideoFormat(1280, 720, | |
68 cricket::VideoFormat::FpsToInterval(60), cricket::FOURCC_I420)); | |
69 ResetSupportedFormats(formats); | |
70 } | |
71 ~FakeVideoCapturer() { | |
72 SignalDestroyed(this); | |
73 } | |
74 | |
75 void ResetSupportedFormats(const std::vector<cricket::VideoFormat>& formats) { | |
76 SetSupportedFormats(formats); | |
77 } | |
78 bool CaptureFrame() { | |
79 if (!GetCaptureFormat()) { | |
80 return false; | |
81 } | |
82 return CaptureCustomFrame(GetCaptureFormat()->width, | |
83 GetCaptureFormat()->height, | |
84 GetCaptureFormat()->interval, | |
85 GetCaptureFormat()->fourcc); | |
86 } | |
87 bool CaptureCustomFrame(int width, int height, uint32_t fourcc) { | |
88 // default to 30fps | |
89 return CaptureCustomFrame(width, height, 33333333, fourcc); | |
90 } | |
91 bool CaptureCustomFrame(int width, | |
92 int height, | |
93 int64_t timestamp_interval, | |
94 uint32_t fourcc) { | |
95 if (!running_) { | |
96 return false; | |
97 } | |
98 // Currently, |fourcc| is always I420 or ARGB. | |
99 // TODO(fbarchard): Extend SizeOf to take fourcc. | |
100 uint32_t size = 0u; | |
101 if (fourcc == cricket::FOURCC_ARGB) { | |
102 size = width * 4 * height; | |
103 } else if (fourcc == cricket::FOURCC_I420) { | |
104 size = static_cast<uint32_t>(cricket::VideoFrame::SizeOf(width, height)); | |
105 } else { | |
106 return false; // Unsupported FOURCC. | |
107 } | |
108 if (size == 0u) { | |
109 return false; // Width and/or Height were zero. | |
110 } | |
111 | |
112 cricket::CapturedFrame frame; | |
113 frame.width = width; | |
114 frame.height = height; | |
115 frame.fourcc = fourcc; | |
116 frame.data_size = size; | |
117 frame.time_stamp = initial_unix_timestamp_ + next_timestamp_; | |
118 next_timestamp_ += timestamp_interval; | |
119 | |
120 rtc::scoped_ptr<char[]> data(new char[size]); | |
121 frame.data = data.get(); | |
122 // Copy something non-zero into the buffer so Validate wont complain that | |
123 // the frame is all duplicate. | |
124 memset(frame.data, 1, size / 2); | |
125 memset(reinterpret_cast<uint8_t*>(frame.data) + (size / 2), 2, | |
126 size - (size / 2)); | |
127 memcpy(frame.data, reinterpret_cast<const uint8_t*>(&fourcc), 4); | |
128 frame.rotation = rotation_; | |
129 // TODO(zhurunz): SignalFrameCaptured carry returned value to be able to | |
130 // capture results from downstream. | |
131 SignalFrameCaptured(this, &frame); | |
132 return true; | |
133 } | |
134 | |
135 void SignalCapturedFrame(cricket::CapturedFrame* frame) { | |
136 SignalFrameCaptured(this, frame); | |
137 } | |
138 | |
139 sigslot::signal1<FakeVideoCapturer*> SignalDestroyed; | |
140 | |
141 virtual cricket::CaptureState Start(const cricket::VideoFormat& format) { | |
142 cricket::VideoFormat supported; | |
143 if (GetBestCaptureFormat(format, &supported)) { | |
144 SetCaptureFormat(&supported); | |
145 } | |
146 running_ = true; | |
147 SetCaptureState(cricket::CS_RUNNING); | |
148 return cricket::CS_RUNNING; | |
149 } | |
150 virtual void Stop() { | |
151 running_ = false; | |
152 SetCaptureFormat(NULL); | |
153 SetCaptureState(cricket::CS_STOPPED); | |
154 } | |
155 virtual bool IsRunning() { return running_; } | |
156 void SetScreencast(bool is_screencast) { | |
157 is_screencast_ = is_screencast; | |
158 } | |
159 virtual bool IsScreencast() const { return is_screencast_; } | |
160 bool GetPreferredFourccs(std::vector<uint32_t>* fourccs) { | |
161 fourccs->push_back(cricket::FOURCC_I420); | |
162 fourccs->push_back(cricket::FOURCC_MJPG); | |
163 return true; | |
164 } | |
165 | |
166 void SetRotation(webrtc::VideoRotation rotation) { | |
167 rotation_ = rotation; | |
168 } | |
169 | |
170 webrtc::VideoRotation GetRotation() { return rotation_; } | |
171 | |
172 private: | |
173 bool running_; | |
174 int64_t initial_unix_timestamp_; | |
175 int64_t next_timestamp_; | |
176 bool is_screencast_; | |
177 webrtc::VideoRotation rotation_; | |
178 }; | |
179 | |
180 } // namespace cricket | |
181 | |
182 #endif // TALK_MEDIA_BASE_FAKEVIDEOCAPTURER_H_ | |
OLD | NEW |