diff options
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(); |