summaryrefslogtreecommitdiffstats
path: root/remoting/protocol/rtp_video_reader_unittest.cc
diff options
context:
space:
mode:
authorsergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-17 23:05:15 +0000
committersergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-17 23:05:15 +0000
commit5ddaa0ac4c4d01677f469e65a02ff584d3035de2 (patch)
treea69cd3af68055724bae9ee9d4ddcac69bed8c666 /remoting/protocol/rtp_video_reader_unittest.cc
parentee97fb0629b6dc336f9c7d69e8595dd9637b336c (diff)
downloadchromium_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.cc348
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