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_TESTUTILS_H_ | |
29 #define TALK_MEDIA_BASE_TESTUTILS_H_ | |
30 | |
31 #include <string> | |
32 #include <vector> | |
33 | |
34 #include "libyuv/compare.h" | |
35 #include "talk/media/base/mediachannel.h" | |
36 #include "talk/media/base/videocapturer.h" | |
37 #include "talk/media/base/videocommon.h" | |
38 #include "webrtc/base/arraysize.h" | |
39 #include "webrtc/base/basictypes.h" | |
40 #include "webrtc/base/sigslot.h" | |
41 #include "webrtc/base/window.h" | |
42 | |
43 namespace rtc { | |
44 class ByteBuffer; | |
45 class StreamInterface; | |
46 } | |
47 | |
48 namespace cricket { | |
49 | |
50 // Returns size of 420 image with rounding on chroma for odd sizes. | |
51 #define I420_SIZE(w, h) (w * h + (((w + 1) / 2) * ((h + 1) / 2)) * 2) | |
52 // Returns size of ARGB image. | |
53 #define ARGB_SIZE(w, h) (w * h * 4) | |
54 | |
55 template <class T> inline std::vector<T> MakeVector(const T a[], size_t s) { | |
56 return std::vector<T>(a, a + s); | |
57 } | |
58 #define MAKE_VECTOR(a) cricket::MakeVector(a, arraysize(a)) | |
59 | |
60 struct RtpDumpPacket; | |
61 class RtpDumpWriter; | |
62 class VideoFrame; | |
63 | |
64 struct RawRtpPacket { | |
65 void WriteToByteBuffer(uint32_t in_ssrc, rtc::ByteBuffer* buf) const; | |
66 bool ReadFromByteBuffer(rtc::ByteBuffer* buf); | |
67 // Check if this packet is the same as the specified packet except the | |
68 // sequence number and timestamp, which should be the same as the specified | |
69 // parameters. | |
70 bool SameExceptSeqNumTimestampSsrc(const RawRtpPacket& packet, | |
71 uint16_t seq, | |
72 uint32_t ts, | |
73 uint32_t ssc) const; | |
74 int size() const { return 28; } | |
75 | |
76 uint8_t ver_to_cc; | |
77 uint8_t m_to_pt; | |
78 uint16_t sequence_number; | |
79 uint32_t timestamp; | |
80 uint32_t ssrc; | |
81 char payload[16]; | |
82 }; | |
83 | |
84 struct RawRtcpPacket { | |
85 void WriteToByteBuffer(rtc::ByteBuffer* buf) const; | |
86 bool ReadFromByteBuffer(rtc::ByteBuffer* buf); | |
87 bool EqualsTo(const RawRtcpPacket& packet) const; | |
88 | |
89 uint8_t ver_to_count; | |
90 uint8_t type; | |
91 uint16_t length; | |
92 char payload[16]; | |
93 }; | |
94 | |
95 class RtpTestUtility { | |
96 public: | |
97 static size_t GetTestPacketCount(); | |
98 | |
99 // Write the first count number of kTestRawRtcpPackets or kTestRawRtpPackets, | |
100 // depending on the flag rtcp. If it is RTP, use the specified SSRC. Return | |
101 // true if successful. | |
102 static bool WriteTestPackets(size_t count, | |
103 bool rtcp, | |
104 uint32_t rtp_ssrc, | |
105 RtpDumpWriter* writer); | |
106 | |
107 // Loop read the first count number of packets from the specified stream. | |
108 // Verify the elapsed time of the dump packets increase monotonically. If the | |
109 // stream is a RTP stream, verify the RTP sequence number, timestamp, and | |
110 // payload. If the stream is a RTCP stream, verify the RTCP header and | |
111 // payload. | |
112 static bool VerifyTestPacketsFromStream(size_t count, | |
113 rtc::StreamInterface* stream, | |
114 uint32_t ssrc); | |
115 | |
116 // Verify the dump packet is the same as the raw RTP packet. | |
117 static bool VerifyPacket(const RtpDumpPacket* dump, | |
118 const RawRtpPacket* raw, | |
119 bool header_only); | |
120 | |
121 static const uint32_t kDefaultSsrc = 1; | |
122 static const uint32_t kRtpTimestampIncrease = 90; | |
123 static const uint32_t kDefaultTimeIncrease = 30; | |
124 static const uint32_t kElapsedTimeInterval = 10; | |
125 static const RawRtpPacket kTestRawRtpPackets[]; | |
126 static const RawRtcpPacket kTestRawRtcpPackets[]; | |
127 | |
128 private: | |
129 RtpTestUtility() {} | |
130 }; | |
131 | |
132 // Test helper for testing VideoCapturer implementations. | |
133 class VideoCapturerListener : public sigslot::has_slots<> { | |
134 public: | |
135 explicit VideoCapturerListener(VideoCapturer* cap); | |
136 | |
137 CaptureState last_capture_state() const { return last_capture_state_; } | |
138 int frame_count() const { return frame_count_; } | |
139 uint32_t frame_fourcc() const { return frame_fourcc_; } | |
140 int frame_width() const { return frame_width_; } | |
141 int frame_height() const { return frame_height_; } | |
142 uint32_t frame_size() const { return frame_size_; } | |
143 bool resolution_changed() const { return resolution_changed_; } | |
144 | |
145 void OnStateChange(VideoCapturer* capturer, CaptureState state); | |
146 void OnFrameCaptured(VideoCapturer* capturer, const CapturedFrame* frame); | |
147 | |
148 private: | |
149 CaptureState last_capture_state_; | |
150 int frame_count_; | |
151 uint32_t frame_fourcc_; | |
152 int frame_width_; | |
153 int frame_height_; | |
154 uint32_t frame_size_; | |
155 bool resolution_changed_; | |
156 }; | |
157 | |
158 class ScreencastEventCatcher : public sigslot::has_slots<> { | |
159 public: | |
160 ScreencastEventCatcher() : ssrc_(0), ev_(rtc::WE_RESIZE) { } | |
161 uint32_t ssrc() const { return ssrc_; } | |
162 rtc::WindowEvent event() const { return ev_; } | |
163 void OnEvent(uint32_t ssrc, rtc::WindowEvent ev) { | |
164 ssrc_ = ssrc; | |
165 ev_ = ev; | |
166 } | |
167 private: | |
168 uint32_t ssrc_; | |
169 rtc::WindowEvent ev_; | |
170 }; | |
171 | |
172 class VideoMediaErrorCatcher : public sigslot::has_slots<> { | |
173 public: | |
174 VideoMediaErrorCatcher() : ssrc_(0), error_(VideoMediaChannel::ERROR_NONE) { } | |
175 uint32_t ssrc() const { return ssrc_; } | |
176 VideoMediaChannel::Error error() const { return error_; } | |
177 void OnError(uint32_t ssrc, VideoMediaChannel::Error error) { | |
178 ssrc_ = ssrc; | |
179 error_ = error; | |
180 } | |
181 private: | |
182 uint32_t ssrc_; | |
183 VideoMediaChannel::Error error_; | |
184 }; | |
185 | |
186 // Returns the absolute path to a file in the testdata/ directory. | |
187 std::string GetTestFilePath(const std::string& filename); | |
188 | |
189 // PSNR formula: psnr = 10 * log10 (Peak Signal^2 / mse) | |
190 // sse is set to a small number for identical frames or sse == 0 | |
191 static inline double ComputePSNR(double sse, double count) { | |
192 return libyuv::SumSquareErrorToPsnr(static_cast<uint64_t>(sse), | |
193 static_cast<uint64_t>(count)); | |
194 } | |
195 | |
196 static inline double ComputeSumSquareError(const uint8_t* org, | |
197 const uint8_t* rec, | |
198 int size) { | |
199 return static_cast<double>(libyuv::ComputeSumSquareError(org, rec, size)); | |
200 } | |
201 | |
202 // Loads the image with the specified prefix and size into |out|. | |
203 bool LoadPlanarYuvTestImage(const std::string& prefix, | |
204 int width, | |
205 int height, | |
206 uint8_t* out); | |
207 | |
208 // Dumps the YUV image out to a file, for visual inspection. | |
209 // PYUV tool can be used to view dump files. | |
210 void DumpPlanarYuvTestImage(const std::string& prefix, | |
211 const uint8_t* img, | |
212 int w, | |
213 int h); | |
214 | |
215 // Dumps the ARGB image out to a file, for visual inspection. | |
216 // ffplay tool can be used to view dump files. | |
217 void DumpPlanarArgbTestImage(const std::string& prefix, | |
218 const uint8_t* img, | |
219 int w, | |
220 int h); | |
221 | |
222 // Compare two I420 frames. | |
223 bool VideoFrameEqual(const VideoFrame* frame0, const VideoFrame* frame1); | |
224 | |
225 // Checks whether |codecs| contains |codec|; checks using Codec::Matches(). | |
226 template <class C> | |
227 bool ContainsMatchingCodec(const std::vector<C>& codecs, const C& codec) { | |
228 typename std::vector<C>::const_iterator it; | |
229 for (it = codecs.begin(); it != codecs.end(); ++it) { | |
230 if (it->Matches(codec)) { | |
231 return true; | |
232 } | |
233 } | |
234 return false; | |
235 } | |
236 | |
237 // Create Simulcast StreamParams with given |ssrcs| and |cname|. | |
238 cricket::StreamParams CreateSimStreamParams(const std::string& cname, | |
239 const std::vector<uint32_t>& ssrcs); | |
240 // Create Simulcast stream with given |ssrcs| and |rtx_ssrcs|. | |
241 // The number of |rtx_ssrcs| must match number of |ssrcs|. | |
242 cricket::StreamParams CreateSimWithRtxStreamParams( | |
243 const std::string& cname, | |
244 const std::vector<uint32_t>& ssrcs, | |
245 const std::vector<uint32_t>& rtx_ssrcs); | |
246 | |
247 } // namespace cricket | |
248 | |
249 #endif // TALK_MEDIA_BASE_TESTUTILS_H_ | |
OLD | NEW |