summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormiu@chromium.org <miu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-25 03:33:44 +0000
committermiu@chromium.org <miu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-25 03:33:44 +0000
commitafd51ef55d60f5c9ad3c29e94f9703053438302c (patch)
treedbe88e090f3ae89c80d87ccce4ce920584ea6a87
parentadcdcdd019fcf6aab6ba4731aad7afbe6a50892e (diff)
downloadchromium_src-afd51ef55d60f5c9ad3c29e94f9703053438302c.zip
chromium_src-afd51ef55d60f5c9ad3c29e94f9703053438302c.tar.gz
chromium_src-afd51ef55d60f5c9ad3c29e94f9703053438302c.tar.bz2
[Cast] Clean-up RtpCastHeader and RtpParser, removing the last WebRTC dependency.
Removed use of a WebRTC struct to hold the RTP-specific header values, and only include those struct members needed by Cast in RtpCastHeader. Also: 1. Cleaned up RtpParser, and fixed bugs relating to 8-->32 bit frame_id and reference_frame_id expansion. 2. Moved call to OnReceivedPayloadData() out of RtpParser::ParsePacket() and into RtpReceiver. 3. Massaged unit tests around RtpCastHeader changes. 4. Coding style violations fixed where code was touched. Testing: All cast_unittests pass. Also, manually casted from Chrome to cast_receiver_app to confirm everything works. BUG=347391 Review URL: https://codereview.chromium.org/250363002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@266120 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--media/cast/DEPS1
-rw-r--r--media/cast/README3
-rw-r--r--media/cast/audio_receiver/audio_receiver.cc8
-rw-r--r--media/cast/audio_receiver/audio_receiver_unittest.cc16
-rw-r--r--media/cast/cast.gyp5
-rw-r--r--media/cast/cast_testing.gypi3
-rw-r--r--media/cast/framer/cast_message_builder_unittest.cc82
-rw-r--r--media/cast/framer/frame_buffer.cc9
-rw-r--r--media/cast/framer/frame_buffer_unittest.cc10
-rw-r--r--media/cast/framer/frame_id_map.cc6
-rw-r--r--media/cast/framer/framer_unittest.cc30
-rw-r--r--media/cast/rtp_receiver/receiver_stats.cc4
-rw-r--r--media/cast/rtp_receiver/receiver_stats_unittest.cc41
-rw-r--r--media/cast/rtp_receiver/rtp_parser/rtp_parser.cc161
-rw-r--r--media/cast/rtp_receiver/rtp_parser/rtp_parser.h45
-rw-r--r--media/cast/rtp_receiver/rtp_parser/rtp_parser_unittest.cc223
-rw-r--r--media/cast/rtp_receiver/rtp_parser/test/rtp_packet_builder.cc19
-rw-r--r--media/cast/rtp_receiver/rtp_parser/test/rtp_packet_builder.h6
-rw-r--r--media/cast/rtp_receiver/rtp_receiver.cc35
-rw-r--r--media/cast/rtp_receiver/rtp_receiver.h11
-rw-r--r--media/cast/rtp_receiver/rtp_receiver_defines.cc25
-rw-r--r--media/cast/rtp_receiver/rtp_receiver_defines.h24
-rw-r--r--media/cast/test/end2end_unittest.cc113
-rw-r--r--media/cast/transport/cast_transport_defines.h2
-rw-r--r--media/cast/transport/rtp_sender/rtp_packetizer/test/rtp_header_parser.h2
-rw-r--r--media/cast/video_receiver/video_receiver.cc8
-rw-r--r--media/cast/video_receiver/video_receiver_unittest.cc16
27 files changed, 418 insertions, 490 deletions
diff --git a/media/cast/DEPS b/media/cast/DEPS
index 76d22b6..abee286 100644
--- a/media/cast/DEPS
+++ b/media/cast/DEPS
@@ -3,7 +3,6 @@ include_rules = [
"+media",
"+net",
"+third_party/libyuv",
- "+third_party/webrtc",
"+third_party/zlib",
"+ui/gfx",
]
diff --git a/media/cast/README b/media/cast/README
index 6972906..0930c1e 100644
--- a/media/cast/README
+++ b/media/cast/README
@@ -56,9 +56,6 @@ third_party/libvpx
third_party/opus
Provides audio encoder.
-third_party/webrtc
- Provides audio signal processing.
-
OWNERS
See OWNERS for ownership.
diff --git a/media/cast/audio_receiver/audio_receiver.cc b/media/cast/audio_receiver/audio_receiver.cc
index 5cb0802..94abdff 100644
--- a/media/cast/audio_receiver/audio_receiver.cc
+++ b/media/cast/audio_receiver/audio_receiver.cc
@@ -77,14 +77,14 @@ void AudioReceiver::OnReceivedPayloadData(const uint8* payload_data,
// TODO(pwestin): update this as video to refresh over time.
if (time_first_incoming_packet_.is_null()) {
InitializeTimers();
- first_incoming_rtp_timestamp_ = rtp_header.webrtc.header.timestamp;
+ first_incoming_rtp_timestamp_ = rtp_header.rtp_timestamp;
time_first_incoming_packet_ = now;
}
frame_id_to_rtp_timestamp_[rtp_header.frame_id & 0xff] =
- rtp_header.webrtc.header.timestamp;
+ rtp_header.rtp_timestamp;
cast_environment_->Logging()->InsertPacketEvent(
- now, kAudioPacketReceived, rtp_header.webrtc.header.timestamp,
+ now, kAudioPacketReceived, rtp_header.rtp_timestamp,
rtp_header.frame_id, rtp_header.packet_id, rtp_header.max_packet_id,
payload_size);
@@ -95,7 +95,7 @@ void AudioReceiver::OnReceivedPayloadData(const uint8* payload_data,
cast_environment_->Logging()->InsertPacketEvent(
now,
kDuplicateAudioPacketReceived,
- rtp_header.webrtc.header.timestamp,
+ rtp_header.rtp_timestamp,
rtp_header.frame_id,
rtp_header.packet_id,
rtp_header.max_packet_id,
diff --git a/media/cast/audio_receiver/audio_receiver_unittest.cc b/media/cast/audio_receiver/audio_receiver_unittest.cc
index c9f3eba..106c5979 100644
--- a/media/cast/audio_receiver/audio_receiver_unittest.cc
+++ b/media/cast/audio_receiver/audio_receiver_unittest.cc
@@ -92,9 +92,8 @@ class AudioReceiverTest : public ::testing::Test {
rtp_header_.frame_id = kFirstFrameId;
rtp_header_.packet_id = 0;
rtp_header_.max_packet_id = 0;
- rtp_header_.is_reference = false;
rtp_header_.reference_frame_id = 0;
- rtp_header_.webrtc.header.timestamp = 0;
+ rtp_header_.rtp_timestamp = 0;
}
void FeedOneFrameIntoReceiver() {
@@ -144,8 +143,7 @@ TEST_F(AudioReceiverTest, GetOnePacketEncodedFrame) {
ASSERT_TRUE(!frame_events.empty());
EXPECT_EQ(kAudioAckSent, frame_events.begin()->type);
EXPECT_EQ(rtp_header_.frame_id, frame_events.begin()->frame_id);
- EXPECT_EQ(rtp_header_.webrtc.header.timestamp,
- frame_events.begin()->rtp_timestamp);
+ EXPECT_EQ(rtp_header_.rtp_timestamp, frame_events.begin()->rtp_timestamp);
cast_environment_->Logging()->RemoveRawEventSubscriber(&event_subscriber);
}
@@ -175,7 +173,7 @@ TEST_F(AudioReceiverTest, MultiplePendingGetCalls) {
uint32 ntp_low;
ConvertTimeTicksToNtp(testing_clock_->NowTicks(), &ntp_high, &ntp_low);
rtcp_packet.AddSrWithNtp(audio_config_.feedback_ssrc, ntp_high, ntp_low,
- rtp_header_.webrtc.header.timestamp);
+ rtp_header_.rtp_timestamp);
testing_clock_->Advance(base::TimeDelta::FromMilliseconds(20));
@@ -191,9 +189,8 @@ TEST_F(AudioReceiverTest, MultiplePendingGetCalls) {
// and that the RTP timestamp represents a time in the future.
rtp_header_.is_key_frame = false;
rtp_header_.frame_id = kFirstFrameId + 2;
- rtp_header_.is_reference = true;
rtp_header_.reference_frame_id = 0;
- rtp_header_.webrtc.header.timestamp = 960;
+ rtp_header_.rtp_timestamp = 960;
fake_audio_client_.SetNextExpectedResult(
kFirstFrameId + 2,
testing_clock_->NowTicks() + base::TimeDelta::FromMilliseconds(100));
@@ -216,9 +213,8 @@ TEST_F(AudioReceiverTest, MultiplePendingGetCalls) {
// Receive Frame 3 and expect it to fulfill the third request immediately.
rtp_header_.frame_id = kFirstFrameId + 3;
- rtp_header_.is_reference = false;
- rtp_header_.reference_frame_id = 0;
- rtp_header_.webrtc.header.timestamp = 1280;
+ rtp_header_.reference_frame_id = rtp_header_.frame_id - 1;
+ rtp_header_.rtp_timestamp = 1280;
fake_audio_client_.SetNextExpectedResult(kFirstFrameId + 3,
testing_clock_->NowTicks());
FeedOneFrameIntoReceiver();
diff --git a/media/cast/cast.gyp b/media/cast/cast.gyp
index b50c5ee..d24b14e 100644
--- a/media/cast/cast.gyp
+++ b/media/cast/cast.gyp
@@ -79,9 +79,6 @@
'type': 'static_library',
'include_dirs': [
'<(DEPTH)/',
-# TODO(miu): Remove WebRTC dependency (RtpHeader), and then these two deps:
- '<(DEPTH)/third_party/',
- '<(DEPTH)/third_party/webrtc/',
],
'dependencies': [
'cast_base',
@@ -114,6 +111,8 @@
'rtp_receiver/receiver_stats.h',
'rtp_receiver/rtp_receiver.cc',
'rtp_receiver/rtp_receiver.h',
+ 'rtp_receiver/rtp_receiver_defines.cc',
+ 'rtp_receiver/rtp_receiver_defines.h',
'rtp_receiver/rtp_parser/rtp_parser.cc',
'rtp_receiver/rtp_parser/rtp_parser.h',
'video_receiver/video_decoder.h',
diff --git a/media/cast/cast_testing.gypi b/media/cast/cast_testing.gypi
index bcf6676..cd5e929 100644
--- a/media/cast/cast_testing.gypi
+++ b/media/cast/cast_testing.gypi
@@ -46,9 +46,6 @@
'type': '<(gtest_target_type)',
'include_dirs': [
'<(DEPTH)/',
-# TODO(miu): Remove WebRTC dependency (RtpHeader), and then these two deps:
- '<(DEPTH)/third_party/',
- '<(DEPTH)/third_party/webrtc/',
],
'dependencies': [
'cast_base',
diff --git a/media/cast/framer/cast_message_builder_unittest.cc b/media/cast/framer/cast_message_builder_unittest.cc
index 4c3e67bd..c84a28f 100644
--- a/media/cast/framer/cast_message_builder_unittest.cc
+++ b/media/cast/framer/cast_message_builder_unittest.cc
@@ -88,7 +88,7 @@ class CastMessageBuilderTest : public ::testing::Test {
kSsrc,
true,
0)) {
- rtp_header_.webrtc.header.ssrc = kSsrc;
+ rtp_header_.sender_ssrc = kSsrc;
rtp_header_.is_key_frame = false;
testing_clock_.Advance(
base::TimeDelta::FromMilliseconds(kStartMillisecond));
@@ -96,7 +96,10 @@ class CastMessageBuilderTest : public ::testing::Test {
virtual ~CastMessageBuilderTest() {}
- void SetFrameId(uint32 frame_id) { rtp_header_.frame_id = frame_id; }
+ void SetFrameIds(uint32 frame_id, uint32 reference_frame_id) {
+ rtp_header_.frame_id = frame_id;
+ rtp_header_.reference_frame_id = reference_frame_id;
+ }
void SetPacketId(uint16 packet_id) { rtp_header_.packet_id = packet_id; }
@@ -106,11 +109,6 @@ class CastMessageBuilderTest : public ::testing::Test {
void SetKeyFrame(bool is_key) { rtp_header_.is_key_frame = is_key; }
- void SetReferenceFrameId(uint32 reference_frame_id) {
- rtp_header_.is_reference = true;
- rtp_header_.reference_frame_id = reference_frame_id;
- }
-
void InsertPacket() {
PacketType packet_type = frame_id_map_.InsertPacket(rtp_header_);
if (packet_type == kNewPacketCompletingFrame) {
@@ -139,13 +137,13 @@ class CastMessageBuilderTest : public ::testing::Test {
};
TEST_F(CastMessageBuilderTest, StartWithAKeyFrame) {
- SetFrameId(3);
+ SetFrameIds(3, 2);
SetPacketId(0);
SetMaxPacketId(0);
InsertPacket();
// Should not trigger ack.
EXPECT_FALSE(feedback_.triggered());
- SetFrameId(5);
+ SetFrameIds(5, 5);
SetPacketId(0);
SetMaxPacketId(0);
SetKeyFrame(true);
@@ -159,7 +157,7 @@ TEST_F(CastMessageBuilderTest, StartWithAKeyFrame) {
}
TEST_F(CastMessageBuilderTest, OneFrameNackList) {
- SetFrameId(0);
+ SetFrameIds(0, 0);
SetPacketId(4);
SetMaxPacketId(10);
InsertPacket();
@@ -175,13 +173,13 @@ TEST_F(CastMessageBuilderTest, OneFrameNackList) {
}
TEST_F(CastMessageBuilderTest, CompleteFrameMissing) {
- SetFrameId(0);
+ SetFrameIds(0, 0);
SetPacketId(2);
SetMaxPacketId(5);
InsertPacket();
testing_clock_.Advance(
base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
- SetFrameId(2);
+ SetFrameIds(2, 1);
SetPacketId(2);
SetMaxPacketId(5);
InsertPacket();
@@ -190,14 +188,14 @@ TEST_F(CastMessageBuilderTest, CompleteFrameMissing) {
}
TEST_F(CastMessageBuilderTest, FastForwardAck) {
- SetFrameId(1);
+ SetFrameIds(1, 0);
SetPacketId(0);
SetMaxPacketId(0);
InsertPacket();
EXPECT_FALSE(feedback_.triggered());
testing_clock_.Advance(
base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
- SetFrameId(2);
+ SetFrameIds(2, 1);
SetPacketId(0);
SetMaxPacketId(0);
InsertPacket();
@@ -205,7 +203,7 @@ TEST_F(CastMessageBuilderTest, FastForwardAck) {
EXPECT_EQ(kStartFrameId, feedback_.last_frame_acked());
testing_clock_.Advance(
base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
- SetFrameId(0);
+ SetFrameIds(0, 0);
SetPacketId(0);
SetMaxPacketId(0);
SetKeyFrame(true);
@@ -215,21 +213,21 @@ TEST_F(CastMessageBuilderTest, FastForwardAck) {
}
TEST_F(CastMessageBuilderTest, RemoveOldFrames) {
- SetFrameId(1);
+ SetFrameIds(1, 0);
SetPacketId(0);
SetMaxPacketId(1);
InsertPacket();
EXPECT_FALSE(feedback_.triggered());
testing_clock_.Advance(
base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
- SetFrameId(2);
+ SetFrameIds(2, 1);
SetPacketId(0);
SetMaxPacketId(0);
InsertPacket();
EXPECT_TRUE(feedback_.triggered());
testing_clock_.Advance(
base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
- SetFrameId(3);
+ SetFrameIds(3, 2);
SetPacketId(0);
SetMaxPacketId(5);
InsertPacket();
@@ -237,7 +235,7 @@ TEST_F(CastMessageBuilderTest, RemoveOldFrames) {
EXPECT_EQ(kStartFrameId, feedback_.last_frame_acked());
testing_clock_.Advance(
base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
- SetFrameId(5);
+ SetFrameIds(5, 5);
SetPacketId(0);
SetMaxPacketId(0);
SetKeyFrame(true);
@@ -250,7 +248,7 @@ TEST_F(CastMessageBuilderTest, RemoveOldFrames) {
EXPECT_EQ(5u, feedback_.last_frame_acked());
testing_clock_.Advance(
base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
- SetFrameId(1);
+ SetFrameIds(1, 0);
SetPacketId(1);
SetMaxPacketId(1);
InsertPacket();
@@ -263,7 +261,7 @@ TEST_F(CastMessageBuilderTest, RemoveOldFrames) {
}
TEST_F(CastMessageBuilderTest, WrapFastForward) {
- SetFrameId(254);
+ SetFrameIds(254, 254);
SetPacketId(0);
SetMaxPacketId(1);
SetKeyFrame(true);
@@ -271,7 +269,7 @@ TEST_F(CastMessageBuilderTest, WrapFastForward) {
EXPECT_FALSE(feedback_.triggered());
testing_clock_.Advance(
base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
- SetFrameId(255);
+ SetFrameIds(255, 254);
SetPacketId(0);
SetMaxPacketId(0);
SetKeyFrame(false);
@@ -280,7 +278,7 @@ TEST_F(CastMessageBuilderTest, WrapFastForward) {
EXPECT_EQ(253u, feedback_.last_frame_acked());
testing_clock_.Advance(
base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
- SetFrameId(256);
+ SetFrameIds(256, 255);
SetPacketId(0);
SetMaxPacketId(0);
SetKeyFrame(false);
@@ -289,7 +287,7 @@ TEST_F(CastMessageBuilderTest, WrapFastForward) {
EXPECT_EQ(253u, feedback_.last_frame_acked());
testing_clock_.Advance(
base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
- SetFrameId(254);
+ SetFrameIds(254, 254);
SetPacketId(1);
SetMaxPacketId(1);
SetKeyFrame(true);
@@ -299,7 +297,7 @@ TEST_F(CastMessageBuilderTest, WrapFastForward) {
}
TEST_F(CastMessageBuilderTest, NackUntilMaxReceivedPacket) {
- SetFrameId(0);
+ SetFrameIds(0, 0);
SetPacketId(0);
SetMaxPacketId(20);
SetKeyFrame(true);
@@ -313,7 +311,7 @@ TEST_F(CastMessageBuilderTest, NackUntilMaxReceivedPacket) {
}
TEST_F(CastMessageBuilderTest, NackUntilMaxReceivedPacketNextFrame) {
- SetFrameId(0);
+ SetFrameIds(0, 0);
SetPacketId(0);
SetMaxPacketId(20);
SetKeyFrame(true);
@@ -326,7 +324,7 @@ TEST_F(CastMessageBuilderTest, NackUntilMaxReceivedPacketNextFrame) {
base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
EXPECT_TRUE(feedback_.triggered());
EXPECT_EQ(4u, feedback_.num_missing_packets(0));
- SetFrameId(1);
+ SetFrameIds(1, 0);
SetMaxPacketId(2);
SetPacketId(0);
SetKeyFrame(false);
@@ -338,7 +336,7 @@ TEST_F(CastMessageBuilderTest, NackUntilMaxReceivedPacketNextFrame) {
}
TEST_F(CastMessageBuilderTest, NackUntilMaxReceivedPacketNextKey) {
- SetFrameId(0);
+ SetFrameIds(0, 0);
SetPacketId(0);
SetMaxPacketId(20);
SetKeyFrame(true);
@@ -351,7 +349,7 @@ TEST_F(CastMessageBuilderTest, NackUntilMaxReceivedPacketNextKey) {
base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
EXPECT_TRUE(feedback_.triggered());
EXPECT_EQ(4u, feedback_.num_missing_packets(0));
- SetFrameId(1);
+ SetFrameIds(1, 1);
SetMaxPacketId(0);
SetPacketId(0);
SetKeyFrame(true);
@@ -375,7 +373,7 @@ TEST_F(CastMessageBuilderTest, Reset) {
}
TEST_F(CastMessageBuilderTest, DeltaAfterReset) {
- SetFrameId(0);
+ SetFrameIds(0, 0);
SetPacketId(0);
SetMaxPacketId(0);
SetKeyFrame(true);
@@ -385,7 +383,7 @@ TEST_F(CastMessageBuilderTest, DeltaAfterReset) {
testing_clock_.Advance(
base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
cast_msg_builder_->Reset();
- SetFrameId(1);
+ SetFrameIds(1, 0);
SetPacketId(0);
SetMaxPacketId(0);
SetKeyFrame(true);
@@ -393,7 +391,7 @@ TEST_F(CastMessageBuilderTest, DeltaAfterReset) {
}
TEST_F(CastMessageBuilderTest, BasicRps) {
- SetFrameId(0);
+ SetFrameIds(0, 0);
SetPacketId(0);
SetMaxPacketId(0);
SetKeyFrame(true);
@@ -402,9 +400,8 @@ TEST_F(CastMessageBuilderTest, BasicRps) {
base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
EXPECT_TRUE(feedback_.triggered());
EXPECT_EQ(0u, feedback_.last_frame_acked());
- SetFrameId(3);
+ SetFrameIds(3, 0);
SetKeyFrame(false);
- SetReferenceFrameId(0);
InsertPacket();
EXPECT_TRUE(feedback_.triggered());
EXPECT_EQ(0u, feedback_.last_frame_acked());
@@ -418,7 +415,7 @@ TEST_F(CastMessageBuilderTest, BasicRps) {
TEST_F(CastMessageBuilderTest, InOrderRps) {
// Create a pattern - skip to rps, and don't look back.
- SetFrameId(0);
+ SetFrameIds(0, 0);
SetPacketId(0);
SetMaxPacketId(0);
SetKeyFrame(true);
@@ -427,7 +424,7 @@ TEST_F(CastMessageBuilderTest, InOrderRps) {
base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
EXPECT_TRUE(feedback_.triggered());
EXPECT_EQ(0u, feedback_.last_frame_acked());
- SetFrameId(1);
+ SetFrameIds(1, 0);
SetPacketId(0);
SetMaxPacketId(1);
SetKeyFrame(false);
@@ -435,11 +432,10 @@ TEST_F(CastMessageBuilderTest, InOrderRps) {
testing_clock_.Advance(
base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
EXPECT_FALSE(feedback_.triggered());
- SetFrameId(3);
+ SetFrameIds(3, 0);
SetPacketId(0);
SetMaxPacketId(0);
SetKeyFrame(false);
- SetReferenceFrameId(0);
InsertPacket();
testing_clock_.Advance(
base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
@@ -450,7 +446,7 @@ TEST_F(CastMessageBuilderTest, InOrderRps) {
EXPECT_TRUE(feedback_.triggered());
EXPECT_EQ(3u, feedback_.last_frame_acked());
// Make an old frame complete - should not trigger an ack.
- SetFrameId(1);
+ SetFrameIds(1, 0);
SetPacketId(1);
SetMaxPacketId(1);
SetKeyFrame(false);
@@ -463,7 +459,7 @@ TEST_F(CastMessageBuilderTest, InOrderRps) {
TEST_F(CastMessageBuilderTest, SlowDownAck) {
SetDecoderSlowerThanMaxFrameRate(3);
- SetFrameId(0);
+ SetFrameIds(0, 0);
SetPacketId(0);
SetMaxPacketId(0);
SetKeyFrame(true);
@@ -476,7 +472,7 @@ TEST_F(CastMessageBuilderTest, SlowDownAck) {
for (frame_id = 1; frame_id < 3; ++frame_id) {
EXPECT_TRUE(feedback_.triggered());
EXPECT_EQ(frame_id - 1, feedback_.last_frame_acked());
- SetFrameId(frame_id);
+ SetFrameIds(frame_id, frame_id - 1);
InsertPacket();
testing_clock_.Advance(
base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
@@ -488,7 +484,7 @@ TEST_F(CastMessageBuilderTest, SlowDownAck) {
++expected_frame_id;
EXPECT_TRUE(feedback_.triggered());
EXPECT_EQ(expected_frame_id, feedback_.last_frame_acked());
- SetFrameId(frame_id);
+ SetFrameIds(frame_id, frame_id - 1);
InsertPacket();
testing_clock_.Advance(
base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
@@ -500,7 +496,7 @@ TEST_F(CastMessageBuilderTest, SlowDownAck) {
frame_id_map_.RemoveOldFrames(frame_id);
// We should now leave the slowdown ACK state.
++frame_id;
- SetFrameId(frame_id);
+ SetFrameIds(frame_id, frame_id - 1);
InsertPacket();
testing_clock_.Advance(
base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
diff --git a/media/cast/framer/frame_buffer.cc b/media/cast/framer/frame_buffer.cc
index 0c92047..2bfdeb5 100644
--- a/media/cast/framer/frame_buffer.cc
+++ b/media/cast/framer/frame_buffer.cc
@@ -28,13 +28,8 @@ void FrameBuffer::InsertPacket(const uint8* payload_data,
frame_id_ = rtp_header.frame_id;
max_packet_id_ = rtp_header.max_packet_id;
is_key_frame_ = rtp_header.is_key_frame;
- if (rtp_header.is_reference) {
- last_referenced_frame_id_ = rtp_header.reference_frame_id;
- } else {
- last_referenced_frame_id_ = rtp_header.frame_id - 1;
- }
-
- rtp_timestamp_ = rtp_header.webrtc.header.timestamp;
+ last_referenced_frame_id_ = rtp_header.reference_frame_id;
+ rtp_timestamp_ = rtp_header.rtp_timestamp;
}
// Is this the correct frame?
if (rtp_header.frame_id != frame_id_)
diff --git a/media/cast/framer/frame_buffer_unittest.cc b/media/cast/framer/frame_buffer_unittest.cc
index c5af17e..c00aa2b 100644
--- a/media/cast/framer/frame_buffer_unittest.cc
+++ b/media/cast/framer/frame_buffer_unittest.cc
@@ -12,13 +12,6 @@ class FrameBufferTest : public ::testing::Test {
protected:
FrameBufferTest() {
payload_.assign(kMaxIpPacketSize, 0);
- // Build a default one packet frame - populate webrtc header.
- rtp_header_.is_key_frame = false;
- rtp_header_.frame_id = 0;
- rtp_header_.packet_id = 0;
- rtp_header_.max_packet_id = 0;
- rtp_header_.is_reference = false;
- rtp_header_.reference_frame_id = 0;
}
virtual ~FrameBufferTest() {}
@@ -31,9 +24,10 @@ class FrameBufferTest : public ::testing::Test {
};
TEST_F(FrameBufferTest, OnePacketInsertSanity) {
- rtp_header_.webrtc.header.timestamp = 3000u;
+ rtp_header_.rtp_timestamp = 3000;
rtp_header_.is_key_frame = true;
rtp_header_.frame_id = 5;
+ rtp_header_.reference_frame_id = 5;
buffer_.InsertPacket(payload_.data(), payload_.size(), rtp_header_);
transport::EncodedVideoFrame frame;
EXPECT_TRUE(buffer_.GetEncodedVideoFrame(&frame));
diff --git a/media/cast/framer/frame_id_map.cc b/media/cast/framer/frame_id_map.cc
index 17871d5..f93fb85 100644
--- a/media/cast/framer/frame_id_map.cc
+++ b/media/cast/framer/frame_id_map.cc
@@ -62,11 +62,7 @@ FrameIdMap::~FrameIdMap() {}
PacketType FrameIdMap::InsertPacket(const RtpCastHeader& rtp_header) {
uint32 frame_id = rtp_header.frame_id;
uint32 reference_frame_id;
- if (rtp_header.is_reference) {
- reference_frame_id = rtp_header.reference_frame_id;
- } else {
- reference_frame_id = static_cast<uint32>(frame_id - 1);
- }
+ reference_frame_id = rtp_header.reference_frame_id;
if (rtp_header.is_key_frame && waiting_for_key_) {
last_released_frame_ = static_cast<uint32>(frame_id - 1);
diff --git a/media/cast/framer/framer_unittest.cc b/media/cast/framer/framer_unittest.cc
index d8c9b0d..06a340e 100644
--- a/media/cast/framer/framer_unittest.cc
+++ b/media/cast/framer/framer_unittest.cc
@@ -15,13 +15,6 @@ class FramerTest : public ::testing::Test {
FramerTest()
: mock_rtp_payload_feedback_(),
framer_(&testing_clock_, &mock_rtp_payload_feedback_, 0, true, 0) {
- // Build a default one packet frame - populate webrtc header.
- rtp_header_.is_key_frame = false;
- rtp_header_.frame_id = 0;
- rtp_header_.packet_id = 0;
- rtp_header_.max_packet_id = 0;
- rtp_header_.is_reference = false;
- rtp_header_.reference_frame_id = 0;
payload_.assign(kMaxIpPacketSize, 0);
EXPECT_CALL(mock_rtp_payload_feedback_, CastFeedback(testing::_))
@@ -57,6 +50,7 @@ TEST_F(FramerTest, AlwaysStartWithKey) {
EXPECT_TRUE(complete);
EXPECT_FALSE(framer_.GetEncodedVideoFrame(&frame, &next_frame));
rtp_header_.frame_id = 1;
+ rtp_header_.reference_frame_id = 1;
rtp_header_.is_key_frame = true;
complete = framer_.InsertPacket(
payload_.data(), payload_.size(), rtp_header_, &duplicate);
@@ -87,6 +81,7 @@ TEST_F(FramerTest, CompleteFrame) {
// Incomplete delta.
++rtp_header_.frame_id;
+ rtp_header_.reference_frame_id = rtp_header_.frame_id - 1;
rtp_header_.is_key_frame = false;
rtp_header_.max_packet_id = 2;
complete = framer_.InsertPacket(
@@ -96,6 +91,7 @@ TEST_F(FramerTest, CompleteFrame) {
// Complete delta - can't skip, as incomplete sequence.
++rtp_header_.frame_id;
+ rtp_header_.reference_frame_id = rtp_header_.frame_id - 1;
rtp_header_.max_packet_id = 0;
complete = framer_.InsertPacket(
payload_.data(), payload_.size(), rtp_header_, &duplicate);
@@ -149,6 +145,7 @@ TEST_F(FramerTest, DuplicatePackets) {
// Incomplete delta frame.
++rtp_header_.frame_id;
+ rtp_header_.reference_frame_id = rtp_header_.frame_id - 1;
rtp_header_.packet_id = 0;
rtp_header_.is_key_frame = false;
duplicate = true;
@@ -205,6 +202,7 @@ TEST_F(FramerTest, ContinuousSequence) {
// Complete - not continuous.
rtp_header_.frame_id = 2;
+ rtp_header_.reference_frame_id = rtp_header_.frame_id - 1;
rtp_header_.is_key_frame = false;
complete = framer_.InsertPacket(
payload_.data(), payload_.size(), rtp_header_, &duplicate);
@@ -220,7 +218,8 @@ TEST_F(FramerTest, Wrap) {
// Start with a complete key frame.
rtp_header_.is_key_frame = true;
- rtp_header_.frame_id = 255u;
+ rtp_header_.frame_id = 255;
+ rtp_header_.reference_frame_id = 255;
framer_.InsertPacket(
payload_.data(), payload_.size(), rtp_header_, &duplicate);
EXPECT_TRUE(framer_.GetEncodedVideoFrame(&frame, &next_frame));
@@ -263,11 +262,12 @@ TEST_F(FramerTest, RequireKeyAfterReset) {
// Start with a complete key frame.
rtp_header_.is_key_frame = false;
- rtp_header_.frame_id = 0u;
+ rtp_header_.frame_id = 0;
framer_.InsertPacket(
payload_.data(), payload_.size(), rtp_header_, &duplicate);
EXPECT_FALSE(framer_.GetEncodedVideoFrame(&frame, &next_frame));
rtp_header_.frame_id = 1;
+ rtp_header_.reference_frame_id = 1;
rtp_header_.is_key_frame = true;
framer_.InsertPacket(
payload_.data(), payload_.size(), rtp_header_, &duplicate);
@@ -289,9 +289,8 @@ TEST_F(FramerTest, BasicNonLastReferenceId) {
framer_.ReleaseFrame(frame.frame_id);
rtp_header_.is_key_frame = false;
- rtp_header_.is_reference = true;
rtp_header_.reference_frame_id = 0;
- rtp_header_.frame_id = 5u;
+ rtp_header_.frame_id = 5;
framer_.InsertPacket(
payload_.data(), payload_.size(), rtp_header_, &duplicate);
@@ -321,7 +320,6 @@ TEST_F(FramerTest, InOrderReferenceFrameSelection) {
payload_.data(), payload_.size(), rtp_header_, &duplicate);
rtp_header_.frame_id = 4;
rtp_header_.max_packet_id = 0;
- rtp_header_.is_reference = true;
rtp_header_.reference_frame_id = 0;
framer_.InsertPacket(
payload_.data(), payload_.size(), rtp_header_, &duplicate);
@@ -342,8 +340,8 @@ TEST_F(FramerTest, InOrderReferenceFrameSelection) {
framer_.InsertPacket(
payload_.data(), payload_.size(), rtp_header_, &duplicate);
EXPECT_FALSE(framer_.GetEncodedVideoFrame(&frame, &next_frame));
- rtp_header_.is_reference = false;
rtp_header_.frame_id = 5;
+ rtp_header_.reference_frame_id = rtp_header_.frame_id - 1;
rtp_header_.packet_id = 0;
rtp_header_.max_packet_id = 0;
framer_.InsertPacket(
@@ -361,6 +359,7 @@ TEST_F(FramerTest, AudioWrap) {
rtp_header_.is_key_frame = true;
rtp_header_.frame_id = 254;
+ rtp_header_.reference_frame_id = 254;
framer_.InsertPacket(
payload_.data(), payload_.size(), rtp_header_, &duplicate);
@@ -370,11 +369,13 @@ TEST_F(FramerTest, AudioWrap) {
framer_.ReleaseFrame(frame.frame_id);
rtp_header_.frame_id = 255;
+ rtp_header_.reference_frame_id = 255;
framer_.InsertPacket(
payload_.data(), payload_.size(), rtp_header_, &duplicate);
// Insert wrapped frame - should be continuous.
rtp_header_.frame_id = 256;
+ rtp_header_.reference_frame_id = 256;
framer_.InsertPacket(
payload_.data(), payload_.size(), rtp_header_, &duplicate);
@@ -398,6 +399,7 @@ TEST_F(FramerTest, AudioWrapWithMissingFrame) {
// Insert and get first packet.
rtp_header_.is_key_frame = true;
rtp_header_.frame_id = 253;
+ rtp_header_.reference_frame_id = 253;
framer_.InsertPacket(
payload_.data(), payload_.size(), rtp_header_, &duplicate);
EXPECT_TRUE(framer_.GetEncodedAudioFrame(&frame, &next_frame));
@@ -407,9 +409,11 @@ TEST_F(FramerTest, AudioWrapWithMissingFrame) {
// Insert third and fourth packets.
rtp_header_.frame_id = 255;
+ rtp_header_.reference_frame_id = 255;
framer_.InsertPacket(
payload_.data(), payload_.size(), rtp_header_, &duplicate);
rtp_header_.frame_id = 256;
+ rtp_header_.reference_frame_id = 256;
framer_.InsertPacket(
payload_.data(), payload_.size(), rtp_header_, &duplicate);
diff --git a/media/cast/rtp_receiver/receiver_stats.cc b/media/cast/rtp_receiver/receiver_stats.cc
index dd82991..7eff867 100644
--- a/media/cast/rtp_receiver/receiver_stats.cc
+++ b/media/cast/rtp_receiver/receiver_stats.cc
@@ -75,7 +75,7 @@ void ReceiverStats::GetStatistics(uint8* fraction_lost,
}
void ReceiverStats::UpdateStatistics(const RtpCastHeader& header) {
- uint16 new_seq_num = header.webrtc.header.sequenceNumber;
+ const uint16 new_seq_num = header.sequence_number;
if (interval_number_packets_ == 0) {
// First packet in the interval.
@@ -99,7 +99,7 @@ void ReceiverStats::UpdateStatistics(const RtpCastHeader& header) {
// Compute Jitter.
base::TimeTicks now = clock_->NowTicks();
base::TimeDelta delta_new_timestamp =
- base::TimeDelta::FromMilliseconds(header.webrtc.header.timestamp);
+ base::TimeDelta::FromMilliseconds(header.rtp_timestamp);
if (total_number_packets_ > 0) {
// Update jitter.
base::TimeDelta delta =
diff --git a/media/cast/rtp_receiver/receiver_stats_unittest.cc b/media/cast/rtp_receiver/receiver_stats_unittest.cc
index eb4b589..98059cd 100644
--- a/media/cast/rtp_receiver/receiver_stats_unittest.cc
+++ b/media/cast/rtp_receiver/receiver_stats_unittest.cc
@@ -21,7 +21,6 @@ class ReceiverStatsTest : public ::testing::Test {
protected:
ReceiverStatsTest()
: stats_(&testing_clock_),
- rtp_header_(),
fraction_lost_(0),
cumulative_lost_(0),
extended_high_sequence_number_(0),
@@ -30,8 +29,6 @@ class ReceiverStatsTest : public ::testing::Test {
base::TimeDelta::FromMilliseconds(kStartMillisecond));
start_time_ = testing_clock_.NowTicks();
delta_increments_ = base::TimeDelta::FromMilliseconds(kStdTimeIncrementMs);
- rtp_header_.webrtc.header.sequenceNumber = 0;
- rtp_header_.webrtc.header.timestamp = 0;
}
virtual ~ReceiverStatsTest() {}
@@ -75,9 +72,9 @@ TEST_F(ReceiverStatsTest, LossCount) {
if (i % 4)
stats_.UpdateStatistics(rtp_header_);
if (i % 3) {
- rtp_header_.webrtc.header.timestamp += 33 * 90;
+ rtp_header_.rtp_timestamp += 33 * 90;
}
- ++rtp_header_.webrtc.header.sequenceNumber;
+ ++rtp_header_.sequence_number;
testing_clock_.Advance(delta_increments_);
}
stats_.GetStatistics(&fraction_lost_,
@@ -87,18 +84,18 @@ TEST_F(ReceiverStatsTest, LossCount) {
EXPECT_EQ(63u, fraction_lost_);
EXPECT_EQ(74u, cumulative_lost_);
// Build extended sequence number.
- uint32 extended_seq_num = rtp_header_.webrtc.header.sequenceNumber - 1;
+ const uint32 extended_seq_num = rtp_header_.sequence_number - 1;
EXPECT_EQ(extended_seq_num, extended_high_sequence_number_);
}
TEST_F(ReceiverStatsTest, NoLossWrap) {
- rtp_header_.webrtc.header.sequenceNumber = 65500;
+ rtp_header_.sequence_number = 65500;
for (int i = 0; i < 300; ++i) {
stats_.UpdateStatistics(rtp_header_);
if (i % 3) {
- rtp_header_.webrtc.header.timestamp += 33 * 90;
+ rtp_header_.rtp_timestamp += 33 * 90;
}
- ++rtp_header_.webrtc.header.sequenceNumber;
+ ++rtp_header_.sequence_number;
testing_clock_.Advance(delta_increments_);
}
stats_.GetStatistics(&fraction_lost_,
@@ -108,21 +105,20 @@ TEST_F(ReceiverStatsTest, NoLossWrap) {
EXPECT_EQ(0u, fraction_lost_);
EXPECT_EQ(0u, cumulative_lost_);
// Build extended sequence number (one wrap cycle).
- uint32 extended_seq_num =
- (1 << 16) + rtp_header_.webrtc.header.sequenceNumber - 1;
+ const uint32 extended_seq_num = (1 << 16) + rtp_header_.sequence_number - 1;
EXPECT_EQ(extended_seq_num, extended_high_sequence_number_);
}
TEST_F(ReceiverStatsTest, LossCountWrap) {
- const uint32 start_sequence_number = 65500;
- rtp_header_.webrtc.header.sequenceNumber = start_sequence_number;
+ const uint32 kStartSequenceNumber = 65500;
+ rtp_header_.sequence_number = kStartSequenceNumber;
for (int i = 0; i < 300; ++i) {
if (i % 4)
stats_.UpdateStatistics(rtp_header_);
if (i % 3)
// Update timestamp.
- ++rtp_header_.webrtc.header.timestamp;
- ++rtp_header_.webrtc.header.sequenceNumber;
+ ++rtp_header_.rtp_timestamp;
+ ++rtp_header_.sequence_number;
testing_clock_.Advance(delta_increments_);
}
stats_.GetStatistics(&fraction_lost_,
@@ -132,16 +128,15 @@ TEST_F(ReceiverStatsTest, LossCountWrap) {
EXPECT_EQ(63u, fraction_lost_);
EXPECT_EQ(74u, cumulative_lost_);
// Build extended sequence number (one wrap cycle).
- uint32 extended_seq_num =
- (1 << 16) + rtp_header_.webrtc.header.sequenceNumber - 1;
+ const uint32 extended_seq_num = (1 << 16) + rtp_header_.sequence_number - 1;
EXPECT_EQ(extended_seq_num, extended_high_sequence_number_);
}
TEST_F(ReceiverStatsTest, BasicJitter) {
for (int i = 0; i < 300; ++i) {
stats_.UpdateStatistics(rtp_header_);
- ++rtp_header_.webrtc.header.sequenceNumber;
- rtp_header_.webrtc.header.timestamp += 33 * 90;
+ ++rtp_header_.sequence_number;
+ rtp_header_.rtp_timestamp += 33 * 90;
testing_clock_.Advance(delta_increments_);
}
stats_.GetStatistics(&fraction_lost_,
@@ -151,7 +146,7 @@ TEST_F(ReceiverStatsTest, BasicJitter) {
EXPECT_FALSE(fraction_lost_);
EXPECT_FALSE(cumulative_lost_);
// Build extended sequence number (one wrap cycle).
- uint32 extended_seq_num = rtp_header_.webrtc.header.sequenceNumber - 1;
+ const uint32 extended_seq_num = rtp_header_.sequence_number - 1;
EXPECT_EQ(extended_seq_num, extended_high_sequence_number_);
EXPECT_EQ(ExpectedJitter(kStdTimeIncrementMs, 300), jitter_);
}
@@ -160,8 +155,8 @@ TEST_F(ReceiverStatsTest, NonTrivialJitter) {
const int kAdditionalIncrement = 5;
for (int i = 0; i < 300; ++i) {
stats_.UpdateStatistics(rtp_header_);
- ++rtp_header_.webrtc.header.sequenceNumber;
- rtp_header_.webrtc.header.timestamp += 33 * 90;
+ ++rtp_header_.sequence_number;
+ rtp_header_.rtp_timestamp += 33 * 90;
base::TimeDelta additional_delta =
base::TimeDelta::FromMilliseconds(kAdditionalIncrement);
testing_clock_.Advance(delta_increments_ + additional_delta);
@@ -173,7 +168,7 @@ TEST_F(ReceiverStatsTest, NonTrivialJitter) {
EXPECT_FALSE(fraction_lost_);
EXPECT_FALSE(cumulative_lost_);
// Build extended sequence number (one wrap cycle).
- uint32 extended_seq_num = rtp_header_.webrtc.header.sequenceNumber - 1;
+ const uint32 extended_seq_num = rtp_header_.sequence_number - 1;
EXPECT_EQ(extended_seq_num, extended_high_sequence_number_);
EXPECT_EQ(ExpectedJitter(kStdTimeIncrementMs + kAdditionalIncrement, 300),
jitter_);
diff --git a/media/cast/rtp_receiver/rtp_parser/rtp_parser.cc b/media/cast/rtp_receiver/rtp_parser/rtp_parser.cc
index b0d27a2..d75696a 100644
--- a/media/cast/rtp_receiver/rtp_parser/rtp_parser.cc
+++ b/media/cast/rtp_receiver/rtp_parser/rtp_parser.cc
@@ -12,105 +12,106 @@
namespace media {
namespace cast {
-static const size_t kRtpCommonHeaderLength = 12;
-static const size_t kRtpCastHeaderLength = 7;
+static const size_t kRtpHeaderLength = 12;
+static const size_t kCastHeaderLength = 7;
+static const uint8 kRtpExtensionBitMask = 0x10;
+static const uint8 kRtpMarkerBitMask = 0x80;
static const uint8 kCastKeyFrameBitMask = 0x80;
static const uint8 kCastReferenceFrameIdBitMask = 0x40;
-RtpParser::RtpParser(const RtpParserConfig parser_config)
- : parser_config_(parser_config) {}
+RtpParser::RtpParser(uint32 expected_sender_ssrc, uint8 expected_payload_type)
+ : expected_sender_ssrc_(expected_sender_ssrc),
+ expected_payload_type_(expected_payload_type) {}
RtpParser::~RtpParser() {}
bool RtpParser::ParsePacket(const uint8* packet,
size_t length,
- RtpCastHeader* rtp_header) {
- if (length == 0)
+ RtpCastHeader* header,
+ const uint8** payload_data,
+ size_t* payload_size) {
+ DCHECK(packet);
+ DCHECK(header);
+ DCHECK(payload_data);
+ DCHECK(payload_size);
+
+ if (length < (kRtpHeaderLength + kCastHeaderLength))
return false;
- // Get RTP general header.
- if (!ParseCommon(packet, length, rtp_header))
- return false;
- if (rtp_header->webrtc.header.payloadType == parser_config_.payload_type &&
- rtp_header->webrtc.header.ssrc == parser_config_.ssrc) {
- return ParseCast(packet + kRtpCommonHeaderLength,
- length - kRtpCommonHeaderLength,
- rtp_header);
- }
- // Not a valid payload type / ssrc combination.
- return false;
-}
-bool RtpParser::ParseCommon(const uint8* packet,
- size_t length,
- RtpCastHeader* rtp_header) {
- if (length < kRtpCommonHeaderLength)
+ base::BigEndianReader reader(reinterpret_cast<const char*>(packet), length);
+
+ // Parse the RTP header. See
+ // http://en.wikipedia.org/wiki/Real-time_Transport_Protocol for an
+ // explanation of the standard RTP packet header.
+ uint8 bits;
+ if (!reader.ReadU8(&bits))
return false;
- uint8 version = packet[0] >> 6;
+ const uint8 version = bits >> 6;
if (version != 2)
return false;
- uint8 cc = packet[0] & 0x0f;
- bool marker = ((packet[1] & 0x80) != 0);
- int payload_type = packet[1] & 0x7f;
-
- uint16 sequence_number;
- uint32 rtp_timestamp, ssrc;
- base::BigEndianReader big_endian_reader(
- reinterpret_cast<const char*>(packet + 2), 10);
- big_endian_reader.ReadU16(&sequence_number);
- big_endian_reader.ReadU32(&rtp_timestamp);
- big_endian_reader.ReadU32(&ssrc);
-
- if (ssrc != parser_config_.ssrc)
+ if (bits & kRtpExtensionBitMask)
+ return false; // We lack the implementation to skip over an extension.
+ if (!reader.ReadU8(&bits))
return false;
-
- rtp_header->webrtc.header.markerBit = marker;
- rtp_header->webrtc.header.payloadType = payload_type;
- rtp_header->webrtc.header.sequenceNumber = sequence_number;
- rtp_header->webrtc.header.timestamp = rtp_timestamp;
- rtp_header->webrtc.header.ssrc = ssrc;
- rtp_header->webrtc.header.numCSRCs = cc;
-
- uint8 csrc_octs = cc * 4;
- rtp_header->webrtc.type.Audio.numEnergy = rtp_header->webrtc.header.numCSRCs;
- rtp_header->webrtc.header.headerLength = kRtpCommonHeaderLength + csrc_octs;
- rtp_header->webrtc.type.Audio.isCNG = false;
- rtp_header->webrtc.type.Audio.channel = parser_config_.audio_channels;
- // TODO(pwestin): look at x bit and skip data.
- return true;
-}
-
-bool RtpParser::ParseCast(const uint8* packet,
- size_t length,
- RtpCastHeader* rtp_header) {
- if (length < kRtpCastHeaderLength)
+ header->marker = !!(bits & kRtpMarkerBitMask);
+ header->payload_type = bits & ~kRtpMarkerBitMask;
+ if (header->payload_type != expected_payload_type_)
+ return false; // Punt: Unexpected payload type.
+ if (!reader.ReadU16(&header->sequence_number) ||
+ !reader.ReadU32(&header->rtp_timestamp) ||
+ !reader.ReadU32(&header->sender_ssrc)) {
return false;
-
- // Extract header.
- const uint8* data_ptr = packet;
- size_t data_length = length;
- rtp_header->is_key_frame = !!(data_ptr[0] & kCastKeyFrameBitMask);
- rtp_header->is_reference = !!(data_ptr[0] & kCastReferenceFrameIdBitMask);
- rtp_header->frame_id = frame_id_wrap_helper_.MapTo32bitsFrameId(data_ptr[1]);
-
- base::BigEndianReader big_endian_reader(
- reinterpret_cast<const char*>(data_ptr + 2), 4);
- big_endian_reader.ReadU16(&rtp_header->packet_id);
- big_endian_reader.ReadU16(&rtp_header->max_packet_id);
-
- if (rtp_header->is_reference) {
- rtp_header->reference_frame_id =
- reference_frame_id_wrap_helper_.MapTo32bitsFrameId(data_ptr[6]);
- data_ptr += kRtpCastHeaderLength;
- data_length -= kRtpCastHeaderLength;
- } else {
- data_ptr += kRtpCastHeaderLength - 1;
- data_length -= kRtpCastHeaderLength - 1;
}
+ if (header->sender_ssrc != expected_sender_ssrc_)
+ return false; // Punt: Sender's SSRC does not match the expected one.
- if (rtp_header->max_packet_id < rtp_header->packet_id)
+ // Parse the Cast header. Note that, from the RTP protocol's perspective, the
+ // Cast header is part of the payload (and not meant to be an extension
+ // header).
+ if (!reader.ReadU8(&bits))
+ return false;
+ header->is_key_frame = !!(bits & kCastKeyFrameBitMask);
+ const bool includes_specific_frame_reference =
+ !!(bits & kCastReferenceFrameIdBitMask);
+ uint8 truncated_frame_id;
+ if (!reader.ReadU8(&truncated_frame_id) ||
+ !reader.ReadU16(&header->packet_id) ||
+ !reader.ReadU16(&header->max_packet_id)) {
return false;
+ }
+ // Sanity-check: Do the packet ID values make sense w.r.t. each other?
+ if (header->max_packet_id < header->packet_id)
+ return false;
+ uint8 truncated_reference_frame_id;
+ if (!includes_specific_frame_reference) {
+ // By default, a key frame only references itself; and non-key frames
+ // reference their direct predecessor.
+ truncated_reference_frame_id = truncated_frame_id;
+ if (!header->is_key_frame)
+ --truncated_reference_frame_id;
+ } else if (!reader.ReadU8(&truncated_reference_frame_id)) {
+ return false;
+ }
+
+ // Only the lower 8 bits of the |frame_id| were serialized, so do some magic
+ // to restore the upper 24 bits.
+ //
+ // Note: The call to |frame_id_wrap_helper_| has side effects, so we must not
+ // call it until we know the entire deserialization will succeed.
+ header->frame_id =
+ frame_id_wrap_helper_.MapTo32bitsFrameId(truncated_frame_id);
+ // When the upper 24 bits are restored to |reference_frame_id|, make sure
+ // |reference_frame_id| will be strictly less than or equal to |frame_id|.
+ if (truncated_reference_frame_id <= truncated_frame_id)
+ header->reference_frame_id = header->frame_id & 0xffffff00;
+ else
+ header->reference_frame_id = (header->frame_id & 0xffffff00) - 0x00000100;
+ header->reference_frame_id |= truncated_reference_frame_id;
+
+ // All remaining data in the packet is the payload.
+ *payload_data = reinterpret_cast<const uint8*>(reader.ptr());
+ *payload_size = reader.remaining();
- OnReceivedPayloadData(data_ptr, data_length, *rtp_header);
return true;
}
diff --git a/media/cast/rtp_receiver/rtp_parser/rtp_parser.h b/media/cast/rtp_receiver/rtp_parser/rtp_parser.h
index 7e4c948..35118cf 100644
--- a/media/cast/rtp_receiver/rtp_parser/rtp_parser.h
+++ b/media/cast/rtp_receiver/rtp_parser/rtp_parser.h
@@ -11,43 +11,32 @@
namespace media {
namespace cast {
-struct RtpParserConfig {
- RtpParserConfig() {
- ssrc = 0;
- payload_type = 0;
- audio_channels = 0;
- }
-
- uint32 ssrc;
- int payload_type;
- transport::AudioCodec audio_codec;
- transport::VideoCodec video_codec;
- int audio_channels;
-};
-
+// TODO(miu): RtpParser and RtpPacketizer should be consolidated into a single
+// module that handles all RTP/Cast packet serialization and deserialization
+// throughout the media/cast library.
class RtpParser {
public:
- RtpParser(const RtpParserConfig parser_config);
+ RtpParser(uint32 expected_sender_ssrc, uint8 expected_payload_type);
virtual ~RtpParser();
+ // Parses the |packet|, expecting an RTP header along with a Cast header at
+ // the beginning of the the RTP payload. This method populates the structure
+ // pointed to by |rtp_header| and sets the |payload_data| pointer and
+ // |payload_size| to the memory region within |packet| containing the Cast
+ // payload data. Returns false if the data appears to be invalid, is not from
+ // the expected sender (as identified by the SSRC field), or is not the
+ // expected payload type.
bool ParsePacket(const uint8* packet,
size_t length,
- RtpCastHeader* rtp_header);
- protected:
- virtual void OnReceivedPayloadData(const uint8* payload_data,
- size_t payload_size,
- const RtpCastHeader& rtp_header) = 0;
- private:
- bool ParseCommon(const uint8* packet,
- size_t length,
- RtpCastHeader* rtp_header);
-
- bool ParseCast(const uint8* packet, size_t length, RtpCastHeader* rtp_header);
+ RtpCastHeader* rtp_header,
+ const uint8** payload_data,
+ size_t* payload_size);
- RtpParserConfig parser_config_;
+ private:
+ const uint32 expected_sender_ssrc_;
+ const uint8 expected_payload_type_;
transport::FrameIdWrapHelper frame_id_wrap_helper_;
- transport::FrameIdWrapHelper reference_frame_id_wrap_helper_;
DISALLOW_COPY_AND_ASSIGN(RtpParser);
};
diff --git a/media/cast/rtp_receiver/rtp_parser/rtp_parser_unittest.cc b/media/cast/rtp_receiver/rtp_parser/rtp_parser_unittest.cc
index 94e67c6..4e3560a9 100644
--- a/media/cast/rtp_receiver/rtp_parser/rtp_parser_unittest.cc
+++ b/media/cast/rtp_receiver/rtp_parser/rtp_parser_unittest.cc
@@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <gtest/gtest.h>
-
#include "base/memory/scoped_ptr.h"
+#include "base/rand_util.h"
#include "media/cast/rtp_receiver/rtp_parser/rtp_parser.h"
#include "media/cast/rtp_receiver/rtp_parser/test/rtp_packet_builder.h"
#include "media/cast/rtp_receiver/rtp_receiver.h"
#include "media/cast/rtp_receiver/rtp_receiver_defines.h"
+#include "testing/gtest/include/gtest/gtest.h"
namespace media {
namespace cast {
@@ -20,175 +20,178 @@ static const uint32 kTestTimestamp = 111111;
static const uint16 kTestSeqNum = 4321;
static const uint8 kRefFrameId = 17;
-class RtpTestParser : public RtpParser {
- public:
- RtpTestParser(const RtpParserConfig config) : RtpParser(config) {
- expected_header_.reset(new RtpCastHeader());
- }
-
- virtual ~RtpTestParser() {}
-
- void SetExpectedHeader(const RtpCastHeader& cast_header) {
- memcpy(expected_header_.get(), &cast_header, sizeof(RtpCastHeader));
- }
-
- virtual void OnReceivedPayloadData(const uint8* payloadData,
- size_t payloadSize,
- const RtpCastHeader& rtpHeader) OVERRIDE {
- VerifyCommonHeader(rtpHeader);
- VerifyCastHeader(rtpHeader);
- }
-
- void VerifyCommonHeader(const RtpCastHeader& parsed_header) {
- EXPECT_EQ(expected_header_->packet_id == expected_header_->max_packet_id,
- parsed_header.webrtc.header.markerBit);
- EXPECT_EQ(kTestPayloadType, parsed_header.webrtc.header.payloadType);
- EXPECT_EQ(kTestSsrc, parsed_header.webrtc.header.ssrc);
- EXPECT_EQ(0, parsed_header.webrtc.header.numCSRCs);
- }
-
- void VerifyCastHeader(const RtpCastHeader& parsed_header) {
- EXPECT_EQ(expected_header_->is_key_frame, parsed_header.is_key_frame);
- EXPECT_EQ(expected_header_->frame_id, parsed_header.frame_id);
- EXPECT_EQ(expected_header_->packet_id, parsed_header.packet_id);
- EXPECT_EQ(expected_header_->max_packet_id, parsed_header.max_packet_id);
- EXPECT_EQ(expected_header_->is_reference, parsed_header.is_reference);
- }
-
- private:
- scoped_ptr<RtpCastHeader> expected_header_;
-
- DISALLOW_COPY_AND_ASSIGN(RtpTestParser);
-};
-
class RtpParserTest : public ::testing::Test {
protected:
- RtpParserTest() {
- PopulateConfig();
- rtp_parser_.reset(new RtpTestParser(config_));
- cast_header_.is_reference = true;
- cast_header_.reference_frame_id = kRefFrameId;
+ RtpParserTest() : rtp_parser_(kTestSsrc, kTestPayloadType) {
packet_builder_.SetSsrc(kTestSsrc);
- packet_builder_.SetReferenceFrameId(kRefFrameId, true);
packet_builder_.SetSequenceNumber(kTestSeqNum);
packet_builder_.SetTimestamp(kTestTimestamp);
packet_builder_.SetPayloadType(kTestPayloadType);
packet_builder_.SetMarkerBit(true); // Only one packet.
+ cast_header_.sender_ssrc = kTestSsrc;
+ cast_header_.sequence_number = kTestSeqNum;
+ cast_header_.rtp_timestamp = kTestTimestamp;
+ cast_header_.payload_type = kTestPayloadType;
+ cast_header_.marker = true;
}
virtual ~RtpParserTest() {}
- void PopulateConfig() {
- config_.payload_type = kTestPayloadType;
- config_.ssrc = kTestSsrc;
+ void ExpectParsesPacket() {
+ RtpCastHeader parsed_header;
+ const uint8* payload = NULL;
+ size_t payload_size = -1;
+ EXPECT_TRUE(rtp_parser_.ParsePacket(
+ packet_, kPacketLength, &parsed_header, &payload, &payload_size));
+
+ EXPECT_EQ(cast_header_.marker, parsed_header.marker);
+ EXPECT_EQ(cast_header_.payload_type, parsed_header.payload_type);
+ EXPECT_EQ(cast_header_.sequence_number, parsed_header.sequence_number);
+ EXPECT_EQ(cast_header_.rtp_timestamp, parsed_header.rtp_timestamp);
+ EXPECT_EQ(cast_header_.sender_ssrc, parsed_header.sender_ssrc);
+
+ EXPECT_EQ(cast_header_.is_key_frame, parsed_header.is_key_frame);
+ EXPECT_EQ(cast_header_.frame_id, parsed_header.frame_id);
+ EXPECT_EQ(cast_header_.packet_id, parsed_header.packet_id);
+ EXPECT_EQ(cast_header_.max_packet_id, parsed_header.max_packet_id);
+ EXPECT_EQ(cast_header_.reference_frame_id,
+ parsed_header.reference_frame_id);
+
+ EXPECT_TRUE(!!payload);
+ EXPECT_NE(static_cast<size_t>(-1), payload_size);
+ }
+
+ void ExpectDoesNotParsePacket() {
+ RtpCastHeader parsed_header;
+ const uint8* payload = NULL;
+ size_t payload_size = -1;
+ EXPECT_FALSE(rtp_parser_.ParsePacket(
+ packet_, kPacketLength, &parsed_header, &payload, &payload_size));
}
RtpPacketBuilder packet_builder_;
- scoped_ptr<RtpTestParser> rtp_parser_;
- RtpParserConfig config_;
+ uint8 packet_[kPacketLength];
+ RtpParser rtp_parser_;
RtpCastHeader cast_header_;
};
TEST_F(RtpParserTest, ParseDefaultCastPacket) {
- // Build generic data packet.
- uint8 packet[kPacketLength];
- packet_builder_.BuildHeader(packet, kPacketLength);
- // Parse packet as is.
- RtpCastHeader rtp_header;
- rtp_parser_->SetExpectedHeader(cast_header_);
- EXPECT_TRUE(rtp_parser_->ParsePacket(packet, kPacketLength, &rtp_header));
+ packet_builder_.BuildHeader(packet_, kPacketLength);
+ ExpectParsesPacket();
}
TEST_F(RtpParserTest, ParseNonDefaultCastPacket) {
- // Build generic data packet.
- uint8 packet[kPacketLength];
packet_builder_.SetKeyFrame(true);
- packet_builder_.SetFrameId(10);
+ packet_builder_.SetFrameIds(10, 10);
packet_builder_.SetPacketId(5);
packet_builder_.SetMaxPacketId(15);
packet_builder_.SetMarkerBit(false);
- packet_builder_.BuildHeader(packet, kPacketLength);
+ packet_builder_.BuildHeader(packet_, kPacketLength);
cast_header_.is_key_frame = true;
cast_header_.frame_id = 10;
+ cast_header_.reference_frame_id = 10;
cast_header_.packet_id = 5;
cast_header_.max_packet_id = 15;
- rtp_parser_->SetExpectedHeader(cast_header_);
- // Parse packet as is.
- RtpCastHeader rtp_header;
- EXPECT_TRUE(rtp_parser_->ParsePacket(packet, kPacketLength, &rtp_header));
+ cast_header_.marker = false;
+ ExpectParsesPacket();
}
TEST_F(RtpParserTest, TooBigPacketId) {
- // Build generic data packet.
- uint8 packet[kPacketLength];
packet_builder_.SetKeyFrame(true);
- packet_builder_.SetFrameId(10);
+ packet_builder_.SetFrameIds(10, 10);
packet_builder_.SetPacketId(15);
packet_builder_.SetMaxPacketId(5);
- packet_builder_.BuildHeader(packet, kPacketLength);
- // Parse packet as is.
- RtpCastHeader rtp_header;
- EXPECT_FALSE(rtp_parser_->ParsePacket(packet, kPacketLength, &rtp_header));
+ packet_builder_.BuildHeader(packet_, kPacketLength);
+ cast_header_.is_key_frame = true;
+ cast_header_.frame_id = 10;
+ cast_header_.reference_frame_id = 10;
+ cast_header_.packet_id = 15;
+ cast_header_.max_packet_id = 5;
+ ExpectDoesNotParsePacket();
}
TEST_F(RtpParserTest, MaxPacketId) {
- // Build generic data packet.
- uint8 packet[kPacketLength];
packet_builder_.SetKeyFrame(true);
- packet_builder_.SetFrameId(10);
+ packet_builder_.SetFrameIds(10, 10);
packet_builder_.SetPacketId(65535);
packet_builder_.SetMaxPacketId(65535);
- packet_builder_.BuildHeader(packet, kPacketLength);
+ packet_builder_.BuildHeader(packet_, kPacketLength);
cast_header_.is_key_frame = true;
cast_header_.frame_id = 10;
+ cast_header_.reference_frame_id = 10;
cast_header_.packet_id = 65535;
cast_header_.max_packet_id = 65535;
- rtp_parser_->SetExpectedHeader(cast_header_);
- // Parse packet as is.
- RtpCastHeader rtp_header;
- EXPECT_TRUE(rtp_parser_->ParsePacket(packet, kPacketLength, &rtp_header));
+ ExpectParsesPacket();
}
TEST_F(RtpParserTest, InvalidPayloadType) {
- // Build generic data packet.
- uint8 packet[kPacketLength];
packet_builder_.SetKeyFrame(true);
- packet_builder_.SetFrameId(10);
+ packet_builder_.SetFrameIds(10, 10);
packet_builder_.SetPacketId(65535);
packet_builder_.SetMaxPacketId(65535);
packet_builder_.SetPayloadType(kTestPayloadType - 1);
- packet_builder_.BuildHeader(packet, kPacketLength);
- // Parse packet as is.
- RtpCastHeader rtp_header;
- EXPECT_FALSE(rtp_parser_->ParsePacket(packet, kPacketLength, &rtp_header));
+ packet_builder_.BuildHeader(packet_, kPacketLength);
+ cast_header_.is_key_frame = true;
+ cast_header_.frame_id = 10;
+ cast_header_.reference_frame_id = 10;
+ cast_header_.packet_id = 65535;
+ cast_header_.max_packet_id = 65535;
+ cast_header_.payload_type = kTestPayloadType - 1;
+ ExpectDoesNotParsePacket();
}
TEST_F(RtpParserTest, InvalidSsrc) {
- // Build generic data packet.
- uint8 packet[kPacketLength];
packet_builder_.SetKeyFrame(true);
- packet_builder_.SetFrameId(10);
+ packet_builder_.SetFrameIds(10, 10);
packet_builder_.SetPacketId(65535);
packet_builder_.SetMaxPacketId(65535);
packet_builder_.SetSsrc(kTestSsrc - 1);
- packet_builder_.BuildHeader(packet, kPacketLength);
- // Parse packet as is.
- RtpCastHeader rtp_header;
- EXPECT_FALSE(rtp_parser_->ParsePacket(packet, kPacketLength, &rtp_header));
+ packet_builder_.BuildHeader(packet_, kPacketLength);
+ cast_header_.is_key_frame = true;
+ cast_header_.frame_id = 10;
+ cast_header_.reference_frame_id = 10;
+ cast_header_.packet_id = 65535;
+ cast_header_.max_packet_id = 65535;
+ cast_header_.sender_ssrc = kTestSsrc - 1;
+ ExpectDoesNotParsePacket();
}
-TEST_F(RtpParserTest, ParseCastPacketWithoutReference) {
- cast_header_.is_reference = false;
- cast_header_.reference_frame_id = 0;
- packet_builder_.SetReferenceFrameId(kRefFrameId, false);
-
- // Build generic data packet.
- uint8 packet[kPacketLength];
- packet_builder_.BuildHeader(packet, kPacketLength);
- // Parse packet as is.
- RtpCastHeader rtp_header;
- rtp_parser_->SetExpectedHeader(cast_header_);
- EXPECT_TRUE(rtp_parser_->ParsePacket(packet, kPacketLength, &rtp_header));
+TEST_F(RtpParserTest, ParseCastPacketWithSpecificFrameReference) {
+ packet_builder_.SetFrameIds(kRefFrameId + 3, kRefFrameId);
+ packet_builder_.BuildHeader(packet_, kPacketLength);
+ cast_header_.frame_id = kRefFrameId + 3;
+ cast_header_.reference_frame_id = kRefFrameId;
+ ExpectParsesPacket();
+}
+
+TEST_F(RtpParserTest, ParseExpandingFrameIdTo32Bits) {
+ const uint32 kMaxFrameId = 1000;
+ packet_builder_.SetKeyFrame(true);
+ cast_header_.is_key_frame = true;
+ for (uint32 frame_id = 0; frame_id <= kMaxFrameId; ++frame_id) {
+ packet_builder_.SetFrameIds(frame_id, frame_id);
+ packet_builder_.BuildHeader(packet_, kPacketLength);
+ cast_header_.frame_id = frame_id;
+ cast_header_.reference_frame_id = frame_id;
+ ExpectParsesPacket();
+ }
+}
+
+TEST_F(RtpParserTest, ParseExpandingReferenceFrameIdTo32Bits) {
+ const uint32 kMaxFrameId = 1000;
+ const uint32 kMaxBackReferenceOffset = 10;
+ packet_builder_.SetKeyFrame(false);
+ cast_header_.is_key_frame = false;
+ for (uint32 frame_id = kMaxBackReferenceOffset;
+ frame_id <= kMaxFrameId; ++frame_id) {
+ const uint32 reference_frame_id =
+ frame_id - base::RandInt(1, kMaxBackReferenceOffset);
+ packet_builder_.SetFrameIds(frame_id, reference_frame_id);
+ packet_builder_.BuildHeader(packet_, kPacketLength);
+ cast_header_.frame_id = frame_id;
+ cast_header_.reference_frame_id = reference_frame_id;
+ ExpectParsesPacket();
+ }
}
} // namespace cast
diff --git a/media/cast/rtp_receiver/rtp_parser/test/rtp_packet_builder.cc b/media/cast/rtp_receiver/rtp_parser/test/rtp_packet_builder.cc
index e251511..b8ab3ba 100644
--- a/media/cast/rtp_receiver/rtp_parser/test/rtp_packet_builder.cc
+++ b/media/cast/rtp_receiver/rtp_parser/test/rtp_packet_builder.cc
@@ -20,7 +20,6 @@ RtpPacketBuilder::RtpPacketBuilder()
packet_id_(0),
max_packet_id_(0),
reference_frame_id_(0),
- is_reference_set_(false),
timestamp_(0),
sequence_number_(0),
marker_(false),
@@ -29,7 +28,10 @@ RtpPacketBuilder::RtpPacketBuilder()
void RtpPacketBuilder::SetKeyFrame(bool is_key) { is_key_ = is_key; }
-void RtpPacketBuilder::SetFrameId(uint32 frame_id) { frame_id_ = frame_id; }
+void RtpPacketBuilder::SetFrameIds(uint32 frame_id, uint32 reference_frame_id) {
+ frame_id_ = frame_id;
+ reference_frame_id_ = reference_frame_id;
+}
void RtpPacketBuilder::SetPacketId(uint16 packet_id) { packet_id_ = packet_id; }
@@ -37,12 +39,6 @@ void RtpPacketBuilder::SetMaxPacketId(uint16 max_packet_id) {
max_packet_id_ = max_packet_id;
}
-void RtpPacketBuilder::SetReferenceFrameId(uint32 reference_frame_id,
- bool is_set) {
- is_reference_set_ = is_set;
- if (is_set)
- reference_frame_id_ = reference_frame_id;
-}
void RtpPacketBuilder::SetTimestamp(uint32 timestamp) {
timestamp_ = timestamp;
}
@@ -71,12 +67,15 @@ void RtpPacketBuilder::BuildCastHeader(uint8* data, uint32 data_length) {
// Set the first 7 bytes to 0.
memset(data, 0, kCastRtpHeaderLength);
base::BigEndianWriter big_endian_writer(reinterpret_cast<char*>(data), 56);
+ const bool includes_specific_frame_reference =
+ (is_key_ && (reference_frame_id_ != frame_id_)) ||
+ (!is_key_ && (reference_frame_id_ != (frame_id_ - 1)));
big_endian_writer.WriteU8((is_key_ ? 0x80 : 0) |
- (is_reference_set_ ? 0x40 : 0));
+ (includes_specific_frame_reference ? 0x40 : 0));
big_endian_writer.WriteU8(frame_id_);
big_endian_writer.WriteU16(packet_id_);
big_endian_writer.WriteU16(max_packet_id_);
- if (is_reference_set_) {
+ if (includes_specific_frame_reference) {
big_endian_writer.WriteU8(reference_frame_id_);
}
}
diff --git a/media/cast/rtp_receiver/rtp_parser/test/rtp_packet_builder.h b/media/cast/rtp_receiver/rtp_parser/test/rtp_packet_builder.h
index ac14252..7337798 100644
--- a/media/cast/rtp_receiver/rtp_parser/test/rtp_packet_builder.h
+++ b/media/cast/rtp_receiver/rtp_parser/test/rtp_packet_builder.h
@@ -12,14 +12,15 @@
namespace media {
namespace cast {
+// TODO(miu): Consolidate with RtpPacketizer as a single Cast packet
+// serialization implementation.
class RtpPacketBuilder {
public:
RtpPacketBuilder();
void SetKeyFrame(bool is_key);
- void SetFrameId(uint32 frame_id);
+ void SetFrameIds(uint32 frame_id, uint32 reference_frame_id);
void SetPacketId(uint16 packet_id);
void SetMaxPacketId(uint16 max_packet_id);
- void SetReferenceFrameId(uint32 reference_frame_id, bool is_set);
void SetTimestamp(uint32 timestamp);
void SetSequenceNumber(uint16 sequence_number);
void SetMarkerBit(bool marker);
@@ -33,7 +34,6 @@ class RtpPacketBuilder {
uint16 packet_id_;
uint16 max_packet_id_;
uint32 reference_frame_id_;
- bool is_reference_set_;
uint32 timestamp_;
uint16 sequence_number_;
bool marker_;
diff --git a/media/cast/rtp_receiver/rtp_receiver.cc b/media/cast/rtp_receiver/rtp_receiver.cc
index f640261..2f95bf3 100644
--- a/media/cast/rtp_receiver/rtp_receiver.cc
+++ b/media/cast/rtp_receiver/rtp_receiver.cc
@@ -13,33 +13,15 @@
namespace media {
namespace cast {
-namespace {
-
-static RtpParserConfig GetRtpParserConfig(
- const AudioReceiverConfig* audio_config,
- const VideoReceiverConfig* video_config) {
- RtpParserConfig config;
- DCHECK(audio_config || video_config) << "Invalid argument";
- if (audio_config) {
- config.ssrc = audio_config->incoming_ssrc;
- config.payload_type = audio_config->rtp_payload_type;
- config.audio_codec = audio_config->codec;
- config.audio_channels = audio_config->channels;
- } else {
- config.ssrc = video_config->incoming_ssrc;
- config.payload_type = video_config->rtp_payload_type;
- config.video_codec = video_config->codec;
- }
- return config;
-}
-
-} // namespace
-
RtpReceiver::RtpReceiver(base::TickClock* clock,
const AudioReceiverConfig* audio_config,
const VideoReceiverConfig* video_config) :
- RtpParser(GetRtpParserConfig(audio_config, video_config)),
+ packet_parser_(audio_config ? audio_config->incoming_ssrc :
+ (video_config ? video_config->incoming_ssrc : 0),
+ audio_config ? audio_config->rtp_payload_type :
+ (video_config ? video_config->rtp_payload_type : 0)),
stats_(clock) {
+ DCHECK(audio_config || video_config);
}
RtpReceiver::~RtpReceiver() {}
@@ -57,9 +39,14 @@ uint32 RtpReceiver::GetSsrcOfSender(const uint8* rtcp_buffer, size_t length) {
bool RtpReceiver::ReceivedPacket(const uint8* packet, size_t length) {
RtpCastHeader rtp_header;
- if (!ParsePacket(packet, length, &rtp_header))
+ const uint8* payload_data;
+ size_t payload_size;
+ if (!packet_parser_.ParsePacket(
+ packet, length, &rtp_header, &payload_data, &payload_size)) {
return false;
+ }
+ OnReceivedPayloadData(payload_data, payload_size, rtp_header);
stats_.UpdateStatistics(rtp_header);
return true;
}
diff --git a/media/cast/rtp_receiver/rtp_receiver.h b/media/cast/rtp_receiver/rtp_receiver.h
index 421d124..9d5194c 100644
--- a/media/cast/rtp_receiver/rtp_receiver.h
+++ b/media/cast/rtp_receiver/rtp_receiver.h
@@ -17,7 +17,9 @@
namespace media {
namespace cast {
-class RtpReceiver : public RtpParser {
+// TODO(miu): This is a good candidate to contain common functionality that's
+// identical in both AudioReceiver and VideoReceiver.
+class RtpReceiver {
public:
RtpReceiver(base::TickClock* clock,
const AudioReceiverConfig* audio_config,
@@ -32,7 +34,14 @@ class RtpReceiver : public RtpParser {
return &stats_;
}
+ protected:
+ // Subclasses implement this to consume and process deserialized packets.
+ virtual void OnReceivedPayloadData(const uint8* payload_data,
+ size_t payload_size,
+ const RtpCastHeader& rtp_header) = 0;
+
private:
+ RtpParser packet_parser_;
ReceiverStats stats_;
DISALLOW_COPY_AND_ASSIGN(RtpReceiver);
diff --git a/media/cast/rtp_receiver/rtp_receiver_defines.cc b/media/cast/rtp_receiver/rtp_receiver_defines.cc
new file mode 100644
index 0000000..e42b2b7
--- /dev/null
+++ b/media/cast/rtp_receiver/rtp_receiver_defines.cc
@@ -0,0 +1,25 @@
+// Copyright 2014 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 "media/cast/rtp_receiver/rtp_receiver_defines.h"
+
+namespace media {
+namespace cast {
+
+RtpCastHeader::RtpCastHeader()
+ : marker(false),
+ payload_type(0),
+ sequence_number(0),
+ rtp_timestamp(0),
+ sender_ssrc(0),
+ is_key_frame(false),
+ frame_id(0),
+ packet_id(0),
+ max_packet_id(0),
+ reference_frame_id(0) {}
+
+RtpPayloadFeedback::~RtpPayloadFeedback() {}
+
+} // namespace cast
+} // namespace media
diff --git a/media/cast/rtp_receiver/rtp_receiver_defines.h b/media/cast/rtp_receiver/rtp_receiver_defines.h
index 112f172..d907436 100644
--- a/media/cast/rtp_receiver/rtp_receiver_defines.h
+++ b/media/cast/rtp_receiver/rtp_receiver_defines.h
@@ -8,27 +8,25 @@
#include "base/basictypes.h"
#include "media/cast/cast_config.h"
#include "media/cast/rtcp/rtcp_defines.h"
-#include "third_party/webrtc/modules/interface/module_common_types.h"
namespace media {
namespace cast {
struct RtpCastHeader {
- RtpCastHeader() {
- is_key_frame = false;
- frame_id = 0;
- packet_id = 0;
- max_packet_id = 0;
- is_reference = false;
- reference_frame_id = 0;
- }
- webrtc::WebRtcRTPHeader webrtc;
+ RtpCastHeader();
+
+ // Elements from RTP packet header.
+ bool marker;
+ uint8 payload_type;
+ uint16 sequence_number;
+ uint32 rtp_timestamp;
+ uint32 sender_ssrc;
+
+ // Elements from Cast header (at beginning of RTP payload).
bool is_key_frame;
uint32 frame_id;
uint16 packet_id;
uint16 max_packet_id;
- bool is_reference; // Set to true if the previous frame is not available,
- // and the reference frame id is available.
uint32 reference_frame_id;
};
@@ -37,7 +35,7 @@ class RtpPayloadFeedback {
virtual void CastFeedback(const RtcpCastMessage& cast_feedback) = 0;
protected:
- virtual ~RtpPayloadFeedback() {}
+ virtual ~RtpPayloadFeedback();
};
} // namespace cast
diff --git a/media/cast/test/end2end_unittest.cc b/media/cast/test/end2end_unittest.cc
index d8f27d0..d283cc9 100644
--- a/media/cast/test/end2end_unittest.cc
+++ b/media/cast/test/end2end_unittest.cc
@@ -54,8 +54,6 @@ static const int kVideoHdWidth = 1280;
static const int kVideoHdHeight = 720;
static const int kVideoQcifWidth = 176;
static const int kVideoQcifHeight = 144;
-static const int kCommonRtpHeaderLength = 12;
-static const uint8 kCastReferenceFrameIdBitReset = 0xDF; // Mask is 0x40.
// Since the video encoded and decoded an error will be introduced; when
// comparing individual pixels the error can be quite large; we allow a PSNR of
@@ -191,7 +189,6 @@ class LoopBackTransport : public transport::PacketSender {
explicit LoopBackTransport(scoped_refptr<CastEnvironment> cast_environment)
: send_packets_(true),
drop_packets_belonging_to_odd_frames_(false),
- reset_reference_frame_id_(false),
cast_environment_(cast_environment) {}
void SetPacketReceiver(
@@ -218,10 +215,6 @@ class LoopBackTransport : public transport::PacketSender {
}
scoped_ptr<Packet> packet_copy(new Packet(packet->data));
- if (reset_reference_frame_id_) {
- // Reset the is_reference bit in the cast header.
- (*packet_copy)[kCommonRtpHeaderLength] &= kCastReferenceFrameIdBitReset;
- }
packet_pipe_->Send(packet_copy.Pass());
return true;
}
@@ -232,8 +225,6 @@ class LoopBackTransport : public transport::PacketSender {
drop_packets_belonging_to_odd_frames_ = true;
}
- void AlwaysResetReferenceFrameId() { reset_reference_frame_id_ = true; }
-
void SetPacketPipe(scoped_ptr<test::PacketPipe> pipe) {
// Append the loopback pipe to the end.
pipe->AppendToPipe(packet_pipe_.Pass());
@@ -243,7 +234,6 @@ class LoopBackTransport : public transport::PacketSender {
private:
bool send_packets_;
bool drop_packets_belonging_to_odd_frames_;
- bool reset_reference_frame_id_;
scoped_refptr<CastEnvironment> cast_environment_;
scoped_ptr<test::PacketPipe> packet_pipe_;
};
@@ -989,38 +979,6 @@ TEST_F(End2EndTest, DISABLED_DropEveryOtherFrame3Buffers) {
EXPECT_EQ(i / 2, test_receiver_video_callback_->number_times_called());
}
-TEST_F(End2EndTest, ResetReferenceFrameId) {
- Configure(transport::kVp8, transport::kOpus, kDefaultAudioSamplingRate,
- false, 3);
- video_sender_config_.rtp_config.max_delay_ms = 67;
- video_receiver_config_.rtp_max_delay_ms = 67;
- Create();
- sender_to_receiver_.AlwaysResetReferenceFrameId();
-
- int frames_counter = 0;
- for (; frames_counter < 10; ++frames_counter) {
- const base::TimeTicks send_time = testing_clock_sender_->NowTicks();
- SendVideoFrame(frames_counter, send_time);
-
- test_receiver_video_callback_->AddExpectedResult(
- frames_counter,
- video_sender_config_.width,
- video_sender_config_.height,
- send_time,
- true);
-
- // GetRawVideoFrame will not return the frame until we are close to the
- // time in which we should render the frame.
- frame_receiver_->GetRawVideoFrame(
- base::Bind(&TestReceiverVideoCallback::CheckVideoFrame,
- test_receiver_video_callback_));
- RunTasks(kFrameTimerMs);
- }
- RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline.
- EXPECT_EQ(frames_counter,
- test_receiver_video_callback_->number_times_called());
-}
-
TEST_F(End2EndTest, CryptoVideo) {
Configure(transport::kVp8, transport::kPcm16, 32000, false, 1);
@@ -1260,46 +1218,39 @@ TEST_F(End2EndTest, AudioLogging) {
EXPECT_EQ(num_audio_frames_requested, received_count);
EXPECT_EQ(num_audio_frames_requested, encoded_count);
- std::map<RtpTimestamp, LoggingEventCounts>::iterator map_it =
- event_counter_for_frame.begin();
-
// Verify that each frame have the expected types of events logged.
- // TODO(imcheng): This only checks the first frame. This doesn't work
- // properly for all frames because:
- // 1. kAudioPlayoutDelay and kAudioFrameDecoded RTP timestamps aren't
- // exactly aligned with those of kAudioFrameReceived and kAudioFrameEncoded.
- // Note that these RTP timestamps are output from webrtc::AudioCodingModule
- // which are different from RTP timestamps that the cast library generates
- // during the encode step (and which are sent to receiver). The first frame
- // just happen to be aligned.
- // 2. Currently, kAudioFrameDecoded and kAudioPlayoutDelay are logged per
- // audio bus.
- // Both 1 and 2 may change since we are currently refactoring audio_decoder.
- // 3. There is no guarantee that exactly one kAudioAckSent is sent per frame.
- int total_event_count_for_frame = 0;
- for (int j = 0; j < kNumOfLoggingEvents; ++j)
- total_event_count_for_frame += map_it->second.counter[j];
-
- int expected_event_count_for_frame = 0;
-
- EXPECT_EQ(1, map_it->second.counter[kAudioFrameReceived]);
- expected_event_count_for_frame += map_it->second.counter[kAudioFrameReceived];
-
- EXPECT_EQ(1, map_it->second.counter[kAudioFrameEncoded]);
- expected_event_count_for_frame += map_it->second.counter[kAudioFrameEncoded];
-
- EXPECT_EQ(1, map_it->second.counter[kAudioPlayoutDelay]);
- expected_event_count_for_frame += map_it->second.counter[kAudioPlayoutDelay];
-
- EXPECT_EQ(1, map_it->second.counter[kAudioFrameDecoded]);
- expected_event_count_for_frame += map_it->second.counter[kAudioFrameDecoded];
-
- EXPECT_GT(map_it->second.counter[kAudioAckSent], 0);
- expected_event_count_for_frame += map_it->second.counter[kAudioAckSent];
-
- // Verify that there were no other events logged with respect to this frame.
- // (i.e. Total event count = expected event count)
- EXPECT_EQ(total_event_count_for_frame, expected_event_count_for_frame);
+ for (std::map<RtpTimestamp, LoggingEventCounts>::const_iterator map_it =
+ event_counter_for_frame.begin();
+ map_it != event_counter_for_frame.end(); ++map_it) {
+ int total_event_count_for_frame = 0;
+ for (int j = 0; j < kNumOfLoggingEvents; ++j)
+ total_event_count_for_frame += map_it->second.counter[j];
+
+ int expected_event_count_for_frame = 0;
+
+ EXPECT_EQ(1, map_it->second.counter[kAudioFrameReceived]);
+ expected_event_count_for_frame +=
+ map_it->second.counter[kAudioFrameReceived];
+
+ EXPECT_EQ(1, map_it->second.counter[kAudioFrameEncoded]);
+ expected_event_count_for_frame +=
+ map_it->second.counter[kAudioFrameEncoded];
+
+ EXPECT_EQ(1, map_it->second.counter[kAudioPlayoutDelay]);
+ expected_event_count_for_frame +=
+ map_it->second.counter[kAudioPlayoutDelay];
+
+ EXPECT_EQ(1, map_it->second.counter[kAudioFrameDecoded]);
+ expected_event_count_for_frame +=
+ map_it->second.counter[kAudioFrameDecoded];
+
+ EXPECT_GT(map_it->second.counter[kAudioAckSent], 0);
+ expected_event_count_for_frame += map_it->second.counter[kAudioAckSent];
+
+ // Verify that there were no other events logged with respect to this frame.
+ // (i.e. Total event count = expected event count)
+ EXPECT_EQ(total_event_count_for_frame, expected_event_count_for_frame);
+ }
}
TEST_F(End2EndTest, BasicFakeSoftwareVideo) {
diff --git a/media/cast/transport/cast_transport_defines.h b/media/cast/transport/cast_transport_defines.h
index 328b4bd..a34f7c5 100644
--- a/media/cast/transport/cast_transport_defines.h
+++ b/media/cast/transport/cast_transport_defines.h
@@ -93,6 +93,8 @@ typedef std::set<uint16> PacketIdSet;
// Each uint8 represents one cast frame.
typedef std::map<uint8, PacketIdSet> MissingFramesAndPacketsMap;
+// TODO(miu): UGLY IN-LINE DEFINITION IN HEADER FILE! Move to appropriate
+// location, separated into .h and .cc files.
class FrameIdWrapHelper {
public:
FrameIdWrapHelper()
diff --git a/media/cast/transport/rtp_sender/rtp_packetizer/test/rtp_header_parser.h b/media/cast/transport/rtp_sender/rtp_packetizer/test/rtp_header_parser.h
index 61db5c66..bb6e0fa 100644
--- a/media/cast/transport/rtp_sender/rtp_packetizer/test/rtp_header_parser.h
+++ b/media/cast/transport/rtp_sender/rtp_packetizer/test/rtp_header_parser.h
@@ -13,6 +13,7 @@ namespace media {
namespace cast {
namespace transport {
+// TODO(miu): Kill this and use RtpCastHeader instead.
struct RtpCastTestHeader {
RtpCastTestHeader();
~RtpCastTestHeader();
@@ -36,6 +37,7 @@ struct RtpCastTestHeader {
int header_length;
};
+// TODO(miu): Kill this and use RtpParser instead.
class RtpHeaderParser {
public:
RtpHeaderParser(const uint8* rtpData, size_t rtpDataLength);
diff --git a/media/cast/video_receiver/video_receiver.cc b/media/cast/video_receiver/video_receiver.cc
index 10ca3fc6..677475f 100644
--- a/media/cast/video_receiver/video_receiver.cc
+++ b/media/cast/video_receiver/video_receiver.cc
@@ -315,7 +315,7 @@ void VideoReceiver::OnReceivedPayloadData(const uint8* payload_data,
base::TimeDelta::FromMilliseconds(kMinTimeBetweenOffsetUpdatesMs)) {
if (time_incoming_packet_.is_null())
InitializeTimers();
- incoming_rtp_timestamp_ = rtp_header.webrtc.header.timestamp;
+ incoming_rtp_timestamp_ = rtp_header.rtp_timestamp;
// The following incoming packet info is used for syncing sender and
// receiver clock. Use only the first packet of every frame to obtain a
// minimal value.
@@ -326,11 +326,11 @@ void VideoReceiver::OnReceivedPayloadData(const uint8* payload_data,
}
frame_id_to_rtp_timestamp_[rtp_header.frame_id & 0xff] =
- rtp_header.webrtc.header.timestamp;
+ rtp_header.rtp_timestamp;
cast_environment_->Logging()->InsertPacketEvent(
now,
kVideoPacketReceived,
- rtp_header.webrtc.header.timestamp,
+ rtp_header.rtp_timestamp,
rtp_header.frame_id,
rtp_header.packet_id,
rtp_header.max_packet_id,
@@ -343,7 +343,7 @@ void VideoReceiver::OnReceivedPayloadData(const uint8* payload_data,
cast_environment_->Logging()->InsertPacketEvent(
now,
kDuplicateVideoPacketReceived,
- rtp_header.webrtc.header.timestamp,
+ rtp_header.rtp_timestamp,
rtp_header.frame_id,
rtp_header.packet_id,
rtp_header.max_packet_id,
diff --git a/media/cast/video_receiver/video_receiver_unittest.cc b/media/cast/video_receiver/video_receiver_unittest.cc
index 4fe834c..a13b630 100644
--- a/media/cast/video_receiver/video_receiver_unittest.cc
+++ b/media/cast/video_receiver/video_receiver_unittest.cc
@@ -91,11 +91,9 @@ class VideoReceiverTest : public ::testing::Test {
// Always start with a key frame.
rtp_header_.is_key_frame = true;
rtp_header_.frame_id = kFirstFrameId;
+ rtp_header_.reference_frame_id = rtp_header_.frame_id;
rtp_header_.packet_id = 0;
rtp_header_.max_packet_id = 0;
- rtp_header_.is_reference = false;
- rtp_header_.reference_frame_id = 0;
- rtp_header_.webrtc.header.timestamp = 0;
}
void FeedOneFrameIntoReceiver() {
@@ -148,8 +146,7 @@ TEST_F(VideoReceiverTest, GetOnePacketEncodedFrame) {
ASSERT_TRUE(!frame_events.empty());
EXPECT_EQ(kVideoAckSent, frame_events.begin()->type);
EXPECT_EQ(rtp_header_.frame_id, frame_events.begin()->frame_id);
- EXPECT_EQ(rtp_header_.webrtc.header.timestamp,
- frame_events.begin()->rtp_timestamp);
+ EXPECT_EQ(rtp_header_.rtp_timestamp, frame_events.begin()->rtp_timestamp);
cast_environment_->Logging()->RemoveRawEventSubscriber(&event_subscriber);
}
@@ -187,9 +184,8 @@ TEST_F(VideoReceiverTest, MultiplePendingGetCalls) {
// and that the RTP timestamp represents a time in the future.
rtp_header_.is_key_frame = false;
rtp_header_.frame_id = kFirstFrameId + 2;
- rtp_header_.is_reference = true;
rtp_header_.reference_frame_id = 0;
- rtp_header_.webrtc.header.timestamp +=
+ rtp_header_.rtp_timestamp +=
config_.rtp_max_delay_ms * kVideoFrequency / 1000;
fake_video_client_.SetNextExpectedResult(
kFirstFrameId + 2,
@@ -216,10 +212,8 @@ TEST_F(VideoReceiverTest, MultiplePendingGetCalls) {
// Receive Frame 3 and expect it to fulfill the third request immediately.
rtp_header_.frame_id = kFirstFrameId + 3;
- rtp_header_.is_reference = false;
- rtp_header_.reference_frame_id = 0;
- rtp_header_.webrtc.header.timestamp +=
- kVideoFrequency / config_.max_frame_rate;
+ rtp_header_.reference_frame_id = rtp_header_.frame_id - 1;
+ rtp_header_.rtp_timestamp += kVideoFrequency / config_.max_frame_rate;
fake_video_client_.SetNextExpectedResult(kFirstFrameId + 3,
testing_clock_->NowTicks());
FeedOneFrameIntoReceiver();