| /* |
| * libjingle |
| * Copyright 2004 Google Inc. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are met: |
| * |
| * 1. Redistributions of source code must retain the above copyright notice, |
| * this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright notice, |
| * this list of conditions and the following disclaimer in the documentation |
| * and/or other materials provided with the distribution. |
| * 3. The name of the author may not be used to endorse or promote products |
| * derived from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
| * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO |
| * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; |
| * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
| * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
| * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
| * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #ifndef TALK_SESSION_PHONE_TESTUTILS_H_ |
| #define TALK_SESSION_PHONE_TESTUTILS_H_ |
| |
| #include <string> |
| #include <vector> |
| |
| #include "talk/base/basictypes.h" |
| #include "talk/base/sigslot.h" |
| #include "talk/base/window.h" |
| #include "talk/session/phone/mediachannel.h" |
| #include "talk/session/phone/videocommon.h" |
| #include "talk/session/phone/videocapturer.h" |
| |
| namespace talk_base { |
| class ByteBuffer; |
| class StreamInterface; |
| } |
| |
| namespace cricket { |
| |
| // Returns size of 420 image with rounding on chroma for odd sizes. |
| #define I420_SIZE(w, h) (w * h + (((w + 1) / 2) * ((h + 1) / 2)) * 2) |
| // Returns size of ARGB image. |
| #define ARGB_SIZE(w, h) (w * h * 4) |
| |
| template <class T> inline std::vector<T> MakeVector(const T a[], size_t s) { |
| return std::vector<T>(a, a + s); |
| } |
| #define MAKE_VECTOR(a) cricket::MakeVector(a, ARRAY_SIZE(a)) |
| |
| struct RtpDumpPacket; |
| class RtpDumpWriter; |
| class VideoFrame; |
| |
| struct RawRtpPacket { |
| void WriteToByteBuffer(uint32 in_ssrc, talk_base::ByteBuffer* buf) const; |
| bool ReadFromByteBuffer(talk_base::ByteBuffer* buf); |
| // Check if this packet is the same as the specified packet except the |
| // sequence number and timestamp, which should be the same as the specified |
| // parameters. |
| bool SameExceptSeqNumTimestampSsrc( |
| const RawRtpPacket& packet, uint16 seq, uint32 ts, uint32 ssc) const; |
| int size() const { return 28; } |
| |
| uint8 ver_to_cc; |
| uint8 m_to_pt; |
| uint16 sequence_number; |
| uint32 timestamp; |
| uint32 ssrc; |
| char payload[16]; |
| }; |
| |
| struct RawRtcpPacket { |
| void WriteToByteBuffer(talk_base::ByteBuffer* buf) const; |
| bool ReadFromByteBuffer(talk_base::ByteBuffer* buf); |
| bool EqualsTo(const RawRtcpPacket& packet) const; |
| |
| uint8 ver_to_count; |
| uint8 type; |
| uint16 length; |
| char payload[16]; |
| }; |
| |
| class RtpTestUtility { |
| public: |
| static size_t GetTestPacketCount(); |
| |
| // Write the first count number of kTestRawRtcpPackets or kTestRawRtpPackets, |
| // depending on the flag rtcp. If it is RTP, use the specified SSRC. Return |
| // true if successful. |
| static bool WriteTestPackets( |
| size_t count, bool rtcp, uint32 rtp_ssrc, RtpDumpWriter* writer); |
| |
| // Loop read the first count number of packets from the specified stream. |
| // Verify the elapsed time of the dump packets increase monotonically. If the |
| // stream is a RTP stream, verify the RTP sequence number, timestamp, and |
| // payload. If the stream is a RTCP stream, verify the RTCP header and |
| // payload. |
| static bool VerifyTestPacketsFromStream( |
| size_t count, talk_base::StreamInterface* stream, uint32 ssrc); |
| |
| // Verify the dump packet is the same as the raw RTP packet. |
| static bool VerifyPacket(const RtpDumpPacket* dump, |
| const RawRtpPacket* raw, |
| bool header_only); |
| |
| static const uint32 kDefaultSsrc = 1; |
| static const uint32 kRtpTimestampIncrease = 90; |
| static const uint32 kDefaultTimeIncrease = 30; |
| static const uint32 kElapsedTimeInterval = 10; |
| static const RawRtpPacket kTestRawRtpPackets[]; |
| static const RawRtcpPacket kTestRawRtcpPackets[]; |
| |
| private: |
| RtpTestUtility() {} |
| }; |
| |
| // Test helper for testing VideoCapturer implementations. |
| class VideoCapturerListener : public sigslot::has_slots<> { |
| public: |
| explicit VideoCapturerListener(VideoCapturer* cap); |
| |
| CaptureResult start_result() const { return start_result_; } |
| int frame_count() const { return frame_count_; } |
| uint32 frame_fourcc() const { return frame_fourcc_; } |
| int frame_width() const { return frame_width_; } |
| int frame_height() const { return frame_height_; } |
| uint32 frame_size() const { return frame_size_; } |
| bool resolution_changed() const { return resolution_changed_; } |
| |
| void OnStartResult(VideoCapturer* capturer, CaptureResult result); |
| void OnFrameCaptured(VideoCapturer* capturer, const CapturedFrame* frame); |
| void OnCaptureEvent(VideoCapturer* capturer, CaptureEvent ev); |
| |
| private: |
| CaptureResult start_result_; |
| int frame_count_; |
| uint32 frame_fourcc_; |
| int frame_width_; |
| int frame_height_; |
| uint32 frame_size_; |
| bool resolution_changed_; |
| }; |
| |
| class ScreencastEventCatcher : public sigslot::has_slots<> { |
| public: |
| ScreencastEventCatcher() : ssrc_(0), ev_(talk_base::WE_RESIZE) { } |
| uint32 ssrc() const { return ssrc_; } |
| talk_base::WindowEvent event() const { return ev_; } |
| void OnEvent(uint32 ssrc, talk_base::WindowEvent ev) { |
| ssrc_ = ssrc; |
| ev_ = ev; |
| } |
| private: |
| uint32 ssrc_; |
| talk_base::WindowEvent ev_; |
| }; |
| |
| class VideoMediaErrorCatcher : public sigslot::has_slots<> { |
| public: |
| VideoMediaErrorCatcher() : ssrc_(0), error_(VideoMediaChannel::ERROR_NONE) { } |
| uint32 ssrc() const { return ssrc_; } |
| VideoMediaChannel::Error error() const { return error_; } |
| void OnError(uint32 ssrc, VideoMediaChannel::Error error) { |
| ssrc_ = ssrc; |
| error_ = error; |
| } |
| private: |
| uint32 ssrc_; |
| VideoMediaChannel::Error error_; |
| }; |
| |
| // Returns the absolute path to a file in the testdata/ directory. |
| std::string GetTestFilePath(const std::string& filename); |
| |
| // PSNR formula: psnr = 10 * log10 (Peak Signal^2 / mse) |
| // sse is set to a small number for identical frames or sse == 0 |
| double ComputePSNR(double sse, double size); |
| |
| double ComputeSumSquareError(const uint8 *org, const uint8 *rec, |
| int size); |
| |
| // Loads the image with the specified prefix and size into |out|. |
| bool LoadPlanarYuvTestImage(const std::string& prefix, |
| int width, int height, uint8* out); |
| |
| // Dumps the YUV image out to a file, for visual inspection. |
| // PYUV tool can be used to view dump files. |
| void DumpPlanarYuvTestImage(const std::string& prefix, const uint8* img, |
| int w, int h); |
| |
| // Dumps the ARGB image out to a file, for visual inspection. |
| // ffplay tool can be used to view dump files. |
| void DumpPlanarArgbTestImage(const std::string& prefix, const uint8* img, |
| int w, int h); |
| |
| // Compare two I420 frames. |
| bool VideoFrameEqual(const VideoFrame* frame0, const VideoFrame* frame1); |
| |
| } // namespace cricket |
| |
| #endif // TALK_SESSION_PHONE_TESTUTILS_H_ |