diff options
author | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-17 23:05:15 +0000 |
---|---|---|
committer | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-17 23:05:15 +0000 |
commit | 5ddaa0ac4c4d01677f469e65a02ff584d3035de2 (patch) | |
tree | a69cd3af68055724bae9ee9d4ddcac69bed8c666 /remoting/protocol/rtp_video_reader_unittest.cc | |
parent | ee97fb0629b6dc336f9c7d69e8595dd9637b336c (diff) | |
download | chromium_src-5ddaa0ac4c4d01677f469e65a02ff584d3035de2.zip chromium_src-5ddaa0ac4c4d01677f469e65a02ff584d3035de2.tar.gz chromium_src-5ddaa0ac4c4d01677f469e65a02ff584d3035de2.tar.bz2 |
Unittests for RTP packetizer and depacketizer.
BUG=None
TEST=Unittests
Review URL: http://codereview.chromium.org/4946001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@66536 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/protocol/rtp_video_reader_unittest.cc')
-rw-r--r-- | remoting/protocol/rtp_video_reader_unittest.cc | 348 |
1 files changed, 348 insertions, 0 deletions
diff --git a/remoting/protocol/rtp_video_reader_unittest.cc b/remoting/protocol/rtp_video_reader_unittest.cc new file mode 100644 index 0000000..81a8e17 --- /dev/null +++ b/remoting/protocol/rtp_video_reader_unittest.cc @@ -0,0 +1,348 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <vector> + +#include "base/message_loop.h" +#include "base/string_number_conversions.h" +#include "net/base/io_buffer.h" +#include "remoting/proto/video.pb.h" +#include "remoting/protocol/fake_session.h" +#include "remoting/protocol/rtp_utils.h" +#include "remoting/protocol/rtp_video_reader.h" +#include "testing/gtest/include/gtest/gtest.h" + +using net::IOBuffer; +using std::vector; + +namespace remoting { +namespace protocol { + +class RtpVideoReaderTest : public testing::Test, + public VideoStub { + public: + virtual void ProcessVideoPacket(const VideoPacket* video_packet, + Task* done) { + received_packets_.push_back(VideoPacket()); + received_packets_.back() = *video_packet; + done->Run(); + delete done; + } + + protected: + struct FragmentInfo { + int sequence_number; + int timestamp; + bool first; + bool last; + Vp8Descriptor::FragmentationInfo fragmentation_info; + int start; + int end; + }; + + struct ExpectedPacket { + int timestamp; + int flags; + int start; + int end; + }; + + virtual void SetUp() { + Reset(); + InitData(100); + } + + void Reset() { + session_ = new FakeSession(); + reader_.reset(new RtpVideoReader()); + reader_->Init(session_, this); + received_packets_.clear(); + } + + void InitData(int size) { + data_.resize(size); + for (int i = 0; i < size; ++i) { + data_[i] = static_cast<char>(i); + } + } + + bool CompareData(const CompoundBuffer& buffer, char* data, int size) { + scoped_refptr<IOBuffer> buffer_data = buffer.ToIOBufferWithSize(); + return buffer.total_bytes() == size && + memcmp(buffer_data->data(), data, size) == 0; + } + + void SplitAndSend(const FragmentInfo fragments[], int count) { + for (int i = 0; i < count; ++i) { + RtpPacket* packet = new RtpPacket(); + + packet->mutable_header()->sequence_number = fragments[i].sequence_number; + packet->mutable_header()->marker = fragments[i].last; + packet->mutable_header()->timestamp = fragments[i].timestamp; + + packet->mutable_vp8_descriptor()->frame_beginning = fragments[i].first; + packet->mutable_vp8_descriptor()->fragmentation_info = + fragments[i].fragmentation_info; + packet->mutable_payload()->AppendCopyOf( + &*data_.begin() + fragments[i].start, + fragments[i].end - fragments[i].start); + reader_->OnRtpPacket(packet); + } + } + + void CheckResults(const ExpectedPacket expected[], int count) { + ASSERT_EQ(count, static_cast<int>(received_packets_.size())); + for (int i = 0; i < count; ++i) { + SCOPED_TRACE("Packet " + base::IntToString(i)); + + int expected_size = expected[i].end - expected[i].start; + EXPECT_EQ(expected_size, + static_cast<int>(received_packets_[i].data().size())); + EXPECT_EQ(0, memcmp(&*received_packets_[i].data().data(), + &*data_.begin() + expected[i].start, expected_size)); + EXPECT_EQ(expected[i].flags, received_packets_[i].flags()); + EXPECT_EQ(expected[i].timestamp, received_packets_[i].timestamp()); + } + } + + scoped_refptr<FakeSession> session_; + scoped_ptr<RtpVideoReader> reader_; + + MessageLoop message_loop_; + vector<char> data_; + vector<VideoPacket> received_packets_; +}; + +// One non-fragmented packet marked as first. +TEST_F(RtpVideoReaderTest, NotFragmented_FirstPacket) { + FragmentInfo fragments[] = { + { 300, 123, true, false, Vp8Descriptor::NOT_FRAGMENTED, 0, 100 }, + }; + SplitAndSend(fragments, arraysize(fragments)); + + ExpectedPacket expected[] = { + { 123, VideoPacket::FIRST_PACKET, 0, 100 }, + }; + CheckResults(expected, arraysize(expected)); +} + +// One non-fragmented packet marked as last. +TEST_F(RtpVideoReaderTest, NotFragmented_LastPacket) { + FragmentInfo fragments[] = { + { 3000, 123, false, true, Vp8Descriptor::NOT_FRAGMENTED, 0, 100 }, + }; + SplitAndSend(fragments, arraysize(fragments)); + + ExpectedPacket expected[] = { + { 123, VideoPacket::LAST_PACKET, 0, 100 }, + }; + CheckResults(expected, arraysize(expected)); +} + +// Duplicated non-fragmented packet. Must be processed only once. +TEST_F(RtpVideoReaderTest, NotFragmented_Duplicate) { + FragmentInfo fragments[] = { + { 300, 123, true, false, Vp8Descriptor::NOT_FRAGMENTED, 0, 100 }, + { 300, 123, true, false, Vp8Descriptor::NOT_FRAGMENTED, 0, 100 }, + }; + SplitAndSend(fragments, arraysize(fragments)); + + ExpectedPacket expected[] = { + { 123, VideoPacket::FIRST_PACKET, 0, 100 }, + }; + CheckResults(expected, arraysize(expected)); +} + +// First packet split into two fragments. +TEST_F(RtpVideoReaderTest, TwoFragments_FirstPacket) { + FragmentInfo fragments[] = { + { 300, 321, true, false, Vp8Descriptor::FIRST_FRAGMENT, 0, 50 }, + { 301, 321, false, false, Vp8Descriptor::LAST_FRAGMENT, 50, 100 }, + }; + SplitAndSend(fragments, arraysize(fragments)); + + ExpectedPacket expected[] = { + { 321, VideoPacket::FIRST_PACKET, 0, 100 }, + }; + CheckResults(expected, arraysize(expected)); +} + +// Last packet split into two fragments. +TEST_F(RtpVideoReaderTest, TwoFragments_LastPacket) { + FragmentInfo fragments[] = { + { 3000, 400, false, false, Vp8Descriptor::FIRST_FRAGMENT, 0, 50 }, + { 3001, 400, false, true, Vp8Descriptor::LAST_FRAGMENT, 50, 100 }, + }; + SplitAndSend(fragments, arraysize(fragments)); + + ExpectedPacket expected[] = { + { 400, VideoPacket::LAST_PACKET, 0, 100 }, + }; + CheckResults(expected, arraysize(expected)); +} + +// Duplicated second fragment. +TEST_F(RtpVideoReaderTest, TwoFragments_WithDuplicate) { + FragmentInfo fragments[] = { + { 3000, 400, false, false, Vp8Descriptor::FIRST_FRAGMENT, 0, 50 }, + { 3001, 400, false, true, Vp8Descriptor::LAST_FRAGMENT, 50, 100 }, + { 3001, 400, false, true, Vp8Descriptor::LAST_FRAGMENT, 50, 100 }, + }; + SplitAndSend(fragments, arraysize(fragments)); + + ExpectedPacket expected[] = { + { 400, VideoPacket::LAST_PACKET, 0, 100 }, + }; + CheckResults(expected, arraysize(expected)); +} + +// Packet split into three fragments. +TEST_F(RtpVideoReaderTest, ThreeFragments_Ordered) { + FragmentInfo fragments[] = { + { 300, 400, true, false, Vp8Descriptor::FIRST_FRAGMENT, 0, 50 }, + { 301, 400, false, false, Vp8Descriptor::MIDDLE_FRAGMENT, 50, 90 }, + { 302, 400, false, false, Vp8Descriptor::LAST_FRAGMENT, 90, 100 }, + }; + SplitAndSend(fragments, arraysize(fragments)); + + ExpectedPacket expected[] = { + { 400, VideoPacket::FIRST_PACKET, 0, 100 }, + }; + CheckResults(expected, arraysize(expected)); +} + +// Packet split into three fragments received in reverse order. +TEST_F(RtpVideoReaderTest, ThreeFragments_ReverseOrder) { + FragmentInfo fragments[] = { + { 302, 400, false, false, Vp8Descriptor::LAST_FRAGMENT, 90, 100 }, + { 301, 400, false, false, Vp8Descriptor::MIDDLE_FRAGMENT, 50, 90 }, + { 300, 400, true, false, Vp8Descriptor::FIRST_FRAGMENT, 0, 50 }, + }; + SplitAndSend(fragments, arraysize(fragments)); + + ExpectedPacket expected[] = { + { 400, VideoPacket::FIRST_PACKET, 0, 100 }, + }; + CheckResults(expected, arraysize(expected)); +} + +// Two fragmented packets. +TEST_F(RtpVideoReaderTest, TwoPackets) { + FragmentInfo fragments[] = { + { 300, 100, true, false, Vp8Descriptor::FIRST_FRAGMENT, 0, 10 }, + { 301, 100, false, false, Vp8Descriptor::MIDDLE_FRAGMENT, 10, 20 }, + { 302, 100, false, false, Vp8Descriptor::LAST_FRAGMENT, 20, 40 }, + + { 303, 200, false, false, Vp8Descriptor::FIRST_FRAGMENT, 40, 70 }, + { 304, 200, false, true, Vp8Descriptor::LAST_FRAGMENT, 70, 100 }, + }; + SplitAndSend(fragments, arraysize(fragments)); + + ExpectedPacket expected[] = { + { 100, VideoPacket::FIRST_PACKET, 0, 40 }, + { 200, VideoPacket::LAST_PACKET, 40, 100 }, + }; + CheckResults(expected, arraysize(expected)); +} + +// Sequence of three packets, with one lost fragment lost in the second packet. +TEST_F(RtpVideoReaderTest, LostFragment) { + FragmentInfo fragments[] = { + { 300, 100, true, false, Vp8Descriptor::FIRST_FRAGMENT, 0, 10 }, + { 301, 100, false, false, Vp8Descriptor::MIDDLE_FRAGMENT, 10, 20 }, + { 302, 100, false, false, Vp8Descriptor::LAST_FRAGMENT, 20, 30 }, + + // Lost: { 303, 200, false, false, Vp8Descriptor::FIRST_FRAGMENT, 40, 50 }, + { 304, 200, false, true, Vp8Descriptor::LAST_FRAGMENT, 30, 40 }, + + { 305, 300, true, false, Vp8Descriptor::FIRST_FRAGMENT, 50, 70 }, + { 306, 300, false, true, Vp8Descriptor::LAST_FRAGMENT, 70, 100 }, + }; + SplitAndSend(fragments, arraysize(fragments)); + + ExpectedPacket expected[] = { + { 100, VideoPacket::FIRST_PACKET, 0, 30 }, + { 300, VideoPacket::FIRST_PACKET | VideoPacket::LAST_PACKET, 50, 100 }, + }; + CheckResults(expected, arraysize(expected)); +} + +// Sequence of four packets, with two lost fragments. +TEST_F(RtpVideoReaderTest, TwoLostFragments) { + // Fragments 303 and 306 should not be combined because they belong to + // different Vp8 partitions. + FragmentInfo fragments[] = { + { 300, 100, true, false, Vp8Descriptor::FIRST_FRAGMENT, 0, 10 }, + { 301, 100, false, false, Vp8Descriptor::MIDDLE_FRAGMENT, 10, 20 }, + { 302, 100, false, false, Vp8Descriptor::LAST_FRAGMENT, 20, 30 }, + + { 303, 200, false, false, Vp8Descriptor::FIRST_FRAGMENT, 40, 50 }, + // Lost: { 304, 200, false, true, Vp8Descriptor::LAST_FRAGMENT, 30, 40 }, + + // Lost: { 305, 300, true, false, Vp8Descriptor::FIRST_FRAGMENT, 50, 60 }, + { 306, 300, false, true, Vp8Descriptor::LAST_FRAGMENT, 60, 70 }, + + { 307, 400, true, false, Vp8Descriptor::FIRST_FRAGMENT, 70, 80 }, + { 308, 400, false, true, Vp8Descriptor::LAST_FRAGMENT, 80, 100 }, + }; + SplitAndSend(fragments, arraysize(fragments)); + + ExpectedPacket expected[] = { + { 100, VideoPacket::FIRST_PACKET, 0, 30 }, + { 400, VideoPacket::FIRST_PACKET | VideoPacket::LAST_PACKET, 70, 100 }, + }; + CheckResults(expected, arraysize(expected)); +} + +// Sequence number wrapping. +TEST_F(RtpVideoReaderTest, SequenceNumberWrapping) { + FragmentInfo fragments[] = { + { 65534, 400, true, false, Vp8Descriptor::FIRST_FRAGMENT, 0, 50 }, + { 65535, 400, false, false, Vp8Descriptor::MIDDLE_FRAGMENT, 50, 90 }, + { 0, 400, false, false, Vp8Descriptor::LAST_FRAGMENT, 90, 100 }, + }; + SplitAndSend(fragments, arraysize(fragments)); + + ExpectedPacket expected[] = { + { 400, VideoPacket::FIRST_PACKET, 0, 100 }, + }; + CheckResults(expected, arraysize(expected)); +} + +// Sequence number wrapping for fragments received out of order. +TEST_F(RtpVideoReaderTest, SequenceNumberWrappingReordered) { + FragmentInfo fragments[] = { + { 0, 400, false, false, Vp8Descriptor::LAST_FRAGMENT, 90, 100 }, + { 65534, 400, true, false, Vp8Descriptor::FIRST_FRAGMENT, 0, 50 }, + { 65535, 400, false, false, Vp8Descriptor::MIDDLE_FRAGMENT, 50, 90 }, + }; + SplitAndSend(fragments, arraysize(fragments)); + + ExpectedPacket expected[] = { + { 400, VideoPacket::FIRST_PACKET, 0, 100 }, + }; + CheckResults(expected, arraysize(expected)); +} + +// An old packet with invalid sequence number. +TEST_F(RtpVideoReaderTest, OldPacket) { + FragmentInfo fragments[] = { + { 32000, 123, true, true, Vp8Descriptor::NOT_FRAGMENTED, 0, 30 }, + + // Should be ignored. + { 10000, 532, true, true, Vp8Descriptor::NOT_FRAGMENTED, 30, 40 }, + + { 32001, 223, true, true, Vp8Descriptor::NOT_FRAGMENTED, 40, 50 }, + }; + SplitAndSend(fragments, arraysize(fragments)); + + ExpectedPacket expected[] = { + { 123, VideoPacket::FIRST_PACKET | VideoPacket::LAST_PACKET, 0, 30 }, + { 223, VideoPacket::FIRST_PACKET | VideoPacket::LAST_PACKET, 40, 50 }, + }; + CheckResults(expected, arraysize(expected)); +} + +} // namespace protocol +} // namespace remoting |