Add test to verify that padding only frames are passing through the RTP module.
Review URL: https://webrtc-codereview.appspot.com/934023
git-svn-id: http://webrtc.googlecode.com/svn/trunk/webrtc@3224 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/modules/modules.gyp b/modules/modules.gyp
index 3244357..29d03ec 100644
--- a/modules/modules.gyp
+++ b/modules/modules.gyp
@@ -45,7 +45,6 @@
'audio_processing/audio_processing_tests.gypi',
'rtp_rtcp/source/rtp_rtcp_tests.gypi',
'rtp_rtcp/test/testFec/test_fec.gypi',
- 'rtp_rtcp/test/testAPI/test_api.gypi',
'video_coding/main/source/video_coding_test.gypi',
'video_coding/codecs/test/video_codecs_test_framework.gypi',
'video_coding/codecs/tools/video_codecs_tools.gypi',
diff --git a/modules/rtp_rtcp/source/rtcp_sender.cc b/modules/rtp_rtcp/source/rtcp_sender.cc
index 789eaf1..051fc44 100644
--- a/modules/rtp_rtcp/source/rtcp_sender.cc
+++ b/modules/rtp_rtcp/source/rtcp_sender.cc
@@ -522,6 +522,12 @@
"%s invalid argument", __FUNCTION__);
return -1;
}
+ std::map<WebRtc_UWord32, RTCPReportBlock*>::iterator it =
+ _reportBlocks.find(SSRC);
+ if (it != _reportBlocks.end()) {
+ delete it->second;
+ _reportBlocks.erase(it);
+ }
RTCPReportBlock* copyReportBlock = new RTCPReportBlock();
memcpy(copyReportBlock, reportBlock, sizeof(RTCPReportBlock));
_reportBlocks[SSRC] = copyReportBlock;
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_tests.gypi b/modules/rtp_rtcp/source/rtp_rtcp_tests.gypi
index 74f9a2d..4ca6819 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_tests.gypi
+++ b/modules/rtp_rtcp/source/rtp_rtcp_tests.gypi
@@ -22,6 +22,12 @@
'../../../',
],
'sources': [
+ '../test/testAPI/test_api.cc',
+ '../test/testAPI/test_api.h',
+ '../test/testAPI/test_api_audio.cc',
+ '../test/testAPI/test_api_nack.cc',
+ '../test/testAPI/test_api_rtcp.cc',
+ '../test/testAPI/test_api_video.cc',
'fec_test_helper.cc',
'fec_test_helper.h',
'producer_fec_unittest.cc',
diff --git a/modules/rtp_rtcp/test/testAPI/test_api.cc b/modules/rtp_rtcp/test/testAPI/test_api.cc
index f2fe144..3503af2 100644
--- a/modules/rtp_rtcp/test/testAPI/test_api.cc
+++ b/modules/rtp_rtcp/test/testAPI/test_api.cc
@@ -24,7 +24,7 @@
protected:
RtpRtcpAPITest() {
test_CSRC[0] = 1234;
- test_CSRC[2] = 2345;
+ test_CSRC[1] = 2345;
test_id = 123;
test_ssrc = 3456;
test_timestamp = 4567;
diff --git a/modules/rtp_rtcp/test/testAPI/test_api.gypi b/modules/rtp_rtcp/test/testAPI/test_api.gypi
deleted file mode 100644
index eaa3a72..0000000
--- a/modules/rtp_rtcp/test/testAPI/test_api.gypi
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
-#
-# Use of this source code is governed by a BSD-style license
-# that can be found in the LICENSE file in the root of the source
-# tree. An additional intellectual property rights grant can be found
-# in the file PATENTS. All contributing project authors may
-# be found in the AUTHORS file in the root of the source tree.
-
-{
- 'targets': [
- {
- 'target_name': 'test_rtp_rtcp_api',
- 'type': 'executable',
- 'dependencies': [
- 'rtp_rtcp',
- '<(webrtc_root)/test/test.gyp:test_support_main',
- '<(DEPTH)/testing/gtest.gyp:gtest',
- ],
-
- 'include_dirs': [
- '../../interface',
- '../../source',
- '../../../../system_wrappers/interface',
- ],
-
- 'sources': [
- 'test_api.cc',
- 'test_api_audio.cc',
- 'test_api_nack.cc',
- 'test_api_rtcp.cc',
- 'test_api_video.cc',
- ],
-
- },
- ],
-}
-
-# Local Variables:
-# tab-width:2
-# indent-tabs-mode:nil
-# End:
-# vim: set expandtab tabstop=2 shiftwidth=2:
diff --git a/modules/rtp_rtcp/test/testAPI/test_api.h b/modules/rtp_rtcp/test/testAPI/test_api.h
index 6261d7f..3e4f2d6 100644
--- a/modules/rtp_rtcp/test/testAPI/test_api.h
+++ b/modules/rtp_rtcp/test/testAPI/test_api.h
@@ -77,12 +77,35 @@
class RtpReceiver : public RtpData {
public:
- virtual WebRtc_Word32 OnReceivedPayloadData(
- const WebRtc_UWord8* payloadData,
- const WebRtc_UWord16 payloadSize,
- const webrtc::WebRtcRTPHeader* rtpHeader) {
+ enum { kMaxPayloadSize = 1500 };
+
+ virtual WebRtc_Word32 OnReceivedPayloadData(
+ const WebRtc_UWord8* payloadData,
+ const WebRtc_UWord16 payloadSize,
+ const webrtc::WebRtcRTPHeader* rtpHeader) {
+ EXPECT_LE(payloadSize, kMaxPayloadSize);
+ memcpy(_payloadData, payloadData, payloadSize);
+ memcpy(&_rtpHeader, rtpHeader, sizeof(_rtpHeader));
+ _payloadSize = payloadSize;
return 0;
}
+
+ const WebRtc_UWord8* payload_data() const {
+ return _payloadData;
+ }
+
+ WebRtc_UWord16 payload_size() const {
+ return _payloadSize;
+ }
+
+ webrtc::WebRtcRTPHeader rtp_header() const {
+ return _rtpHeader;
+ }
+
+ private:
+ WebRtc_UWord8 _payloadData[kMaxPayloadSize];
+ WebRtc_UWord16 _payloadSize;
+ webrtc::WebRtcRTPHeader _rtpHeader;
};
} // namespace webrtc
diff --git a/modules/rtp_rtcp/test/testAPI/test_api_audio.cc b/modules/rtp_rtcp/test/testAPI/test_api_audio.cc
index bf88ace..ce899d7 100644
--- a/modules/rtp_rtcp/test/testAPI/test_api_audio.cc
+++ b/modules/rtp_rtcp/test/testAPI/test_api_audio.cc
@@ -328,5 +328,4 @@
fake_clock.IncrementTime(20);
module1->Process();
}
- delete audioFeedback;
}
diff --git a/modules/rtp_rtcp/test/testAPI/test_api_rtcp.cc b/modules/rtp_rtcp/test/testAPI/test_api_rtcp.cc
index 833f867..d25d4cb 100644
--- a/modules/rtp_rtcp/test/testAPI/test_api_rtcp.cc
+++ b/modules/rtp_rtcp/test/testAPI/test_api_rtcp.cc
@@ -10,10 +10,10 @@
#include <algorithm>
#include <vector>
-#include <gtest/gtest.h>
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
#include "test_api.h"
-
#include "common_types.h"
#include "rtp_rtcp.h"
#include "rtp_rtcp_defines.h"
@@ -80,7 +80,7 @@
protected:
RtpRtcpRtcpTest() {
test_CSRC[0] = 1234;
- test_CSRC[2] = 2345;
+ test_CSRC[1] = 2345;
test_id = 123;
test_ssrc = 3456;
test_timestamp = 4567;
@@ -97,11 +97,12 @@
RtpRtcp::Configuration configuration;
configuration.id = test_id;
- configuration.audio = false;
+ configuration.audio = true;
configuration.clock = &fake_clock;
configuration.outgoing_transport = transport1;
configuration.rtcp_feedback = myRTCPFeedback1;
configuration.intra_frame_callback = myRTCPFeedback1;
+ configuration.incoming_data = receiver;
module1 = RtpRtcp::CreateRtpRtcp(configuration);
@@ -150,6 +151,8 @@
virtual void TearDown() {
delete module1;
delete module2;
+ delete myRTCPFeedback1;
+ delete myRTCPFeedback2;
delete transport1;
delete transport2;
delete receiver;
@@ -217,6 +220,8 @@
TEST_F(RtpRtcpRtcpTest, RTCP) {
RTCPReportBlock reportBlock;
+ reportBlock.remoteSSRC = 1;
+ reportBlock.sourceSSRC = 2;
reportBlock.cumulativeLost = 1;
reportBlock.delaySinceLastSR = 2;
reportBlock.extendedHighSeqNum = 3;
diff --git a/modules/rtp_rtcp/test/testAPI/test_api_video.cc b/modules/rtp_rtcp/test/testAPI/test_api_video.cc
index fdd3ed3..7a9d3db 100644
--- a/modules/rtp_rtcp/test/testAPI/test_api_video.cc
+++ b/modules/rtp_rtcp/test/testAPI/test_api_video.cc
@@ -8,88 +8,157 @@
* be found in the AUTHORS file in the root of the source tree.
*/
+#include <stdlib.h>
+
#include <algorithm>
#include <vector>
-#include <gtest/gtest.h>
-#include "test_api.h"
+#include "gtest/gtest.h"
+#include "webrtc/common_types.h"
+#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
+#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
+#include "webrtc/modules/rtp_rtcp/test/testAPI/test_api.h"
-#include "common_types.h"
-#include "rtp_rtcp.h"
-#include "rtp_rtcp_defines.h"
-
-using namespace webrtc;
+namespace webrtc {
class RtpRtcpVideoTest : public ::testing::Test {
protected:
- RtpRtcpVideoTest() {
- test_id = 123;
- test_ssrc = 3456;
- test_timestamp = 4567;
- test_sequence_number = 2345;
+ RtpRtcpVideoTest()
+ : test_id_(123),
+ test_ssrc_(3456),
+ test_timestamp_(4567),
+ test_sequence_number_(2345) {
}
~RtpRtcpVideoTest() {}
virtual void SetUp() {
- transport = new LoopBackTransport();
- receiver = new RtpReceiver();
+ transport_ = new LoopBackTransport();
+ receiver_ = new RtpReceiver();
RtpRtcp::Configuration configuration;
- configuration.id = test_id;
+ configuration.id = test_id_;
configuration.audio = false;
configuration.clock = &fake_clock;
- configuration.incoming_data = receiver;
- configuration.outgoing_transport = transport;
+ configuration.incoming_data = receiver_;
+ configuration.outgoing_transport = transport_;
- video_module = RtpRtcp::CreateRtpRtcp(configuration);
+ video_module_ = RtpRtcp::CreateRtpRtcp(configuration);
- EXPECT_EQ(0, video_module->SetRTCPStatus(kRtcpCompound));
- EXPECT_EQ(0, video_module->SetSSRC(test_ssrc));
- EXPECT_EQ(0, video_module->SetNACKStatus(kNackRtcp));
- EXPECT_EQ(0, video_module->SetStorePacketsStatus(true));
- EXPECT_EQ(0, video_module->SetSendingStatus(true));
+ EXPECT_EQ(0, video_module_->SetRTCPStatus(kRtcpCompound));
+ EXPECT_EQ(0, video_module_->SetSSRC(test_ssrc_));
+ EXPECT_EQ(0, video_module_->SetNACKStatus(kNackRtcp));
+ EXPECT_EQ(0, video_module_->SetStorePacketsStatus(true));
+ EXPECT_EQ(0, video_module_->SetSendingStatus(true));
- transport->SetSendModule(video_module);
+ transport_->SetSendModule(video_module_);
VideoCodec video_codec;
memset(&video_codec, 0, sizeof(video_codec));
video_codec.plType = 123;
memcpy(video_codec.plName, "I420", 5);
- EXPECT_EQ(0, video_module->RegisterSendPayload(video_codec));
- EXPECT_EQ(0, video_module->RegisterReceivePayload(video_codec));
+ EXPECT_EQ(0, video_module_->RegisterSendPayload(video_codec));
+ EXPECT_EQ(0, video_module_->RegisterReceivePayload(video_codec));
- payload_data_length = sizeof(payload_data);
+ payload_data_length_ = sizeof(video_frame_);
- for (int n = 0; n < payload_data_length; n++) {
- payload_data[n] = n%10;
+ for (int n = 0; n < payload_data_length_; n++) {
+ video_frame_[n] = n%10;
}
}
- virtual void TearDown() {
- delete video_module;
- delete transport;
- delete receiver;
+ WebRtc_Word32 BuildRTPheader(WebRtc_UWord8* dataBuffer,
+ WebRtc_UWord32 timestamp,
+ WebRtc_UWord32 sequence_number) {
+ dataBuffer[0] = static_cast<WebRtc_UWord8>(0x80); // version 2
+ dataBuffer[1] = static_cast<WebRtc_UWord8>(kPayloadType);
+ ModuleRTPUtility::AssignUWord16ToBuffer(dataBuffer + 2,
+ sequence_number);
+ ModuleRTPUtility::AssignUWord32ToBuffer(dataBuffer + 4, timestamp);
+ ModuleRTPUtility::AssignUWord32ToBuffer(dataBuffer + 8,
+ 0x1234); // SSRC.
+ WebRtc_Word32 rtpHeaderLength = 12;
+ return rtpHeaderLength;
}
- int test_id;
- RtpRtcp* video_module;
- LoopBackTransport* transport;
- RtpReceiver* receiver;
- WebRtc_UWord32 test_ssrc;
- WebRtc_UWord32 test_timestamp;
- WebRtc_UWord16 test_sequence_number;
- WebRtc_UWord8 payload_data[65000];
- int payload_data_length;
+ int PaddingPacket(uint8_t* buffer,
+ WebRtc_UWord32 timestamp,
+ WebRtc_UWord32 sequence_number,
+ WebRtc_Word32 bytes) {
+ // Max in the RFC 3550 is 255 bytes, we limit it to be modulus 32 for SRTP.
+ int max_length = 224;
+
+ int padding_bytes_in_packet = max_length;
+ if (bytes < max_length) {
+ padding_bytes_in_packet = (bytes + 16) & 0xffe0; // Keep our modulus 32.
+ }
+ // Correct seq num, timestamp and payload type.
+ int header_length = BuildRTPheader(buffer, timestamp,
+ sequence_number);
+ buffer[0] |= 0x20; // Set padding bit.
+ WebRtc_Word32* data =
+ reinterpret_cast<WebRtc_Word32*>(&(buffer[header_length]));
+
+ // Fill data buffer with random data.
+ for (int j = 0; j < (padding_bytes_in_packet >> 2); j++) {
+ data[j] = rand(); // NOLINT
+ }
+ // Set number of padding bytes in the last byte of the packet.
+ buffer[header_length + padding_bytes_in_packet - 1] =
+ padding_bytes_in_packet;
+ return padding_bytes_in_packet + header_length;
+ }
+
+ virtual void TearDown() {
+ delete video_module_;
+ delete transport_;
+ delete receiver_;
+ }
+
+ int test_id_;
+ RtpRtcp* video_module_;
+ LoopBackTransport* transport_;
+ RtpReceiver* receiver_;
+ WebRtc_UWord32 test_ssrc_;
+ WebRtc_UWord32 test_timestamp_;
+ WebRtc_UWord16 test_sequence_number_;
+ WebRtc_UWord8 video_frame_[65000];
+ int payload_data_length_;
FakeRtpRtcpClock fake_clock;
+ enum { kPayloadType = 100 };
};
TEST_F(RtpRtcpVideoTest, BasicVideo) {
WebRtc_UWord32 timestamp = 3000;
- EXPECT_EQ(0, video_module->SendOutgoingData(webrtc::kVideoFrameDelta, 123,
- timestamp,
- timestamp / 90,
- payload_data,
- payload_data_length));
-
+ EXPECT_EQ(0, video_module_->SendOutgoingData(kVideoFrameDelta, 123,
+ timestamp,
+ timestamp / 90,
+ video_frame_,
+ payload_data_length_));
}
+TEST_F(RtpRtcpVideoTest, PaddingOnlyFrames) {
+ const int kPadSize = 255;
+ uint8_t padding_packet[kPadSize];
+ uint32_t seq_num = 0;
+ uint32_t timestamp = 3000;
+ VideoCodec codec;
+ codec.codecType = kVideoCodecVP8;
+ codec.plType = kPayloadType;
+ strncpy(codec.plName, "VP8", 4);
+ EXPECT_EQ(0, video_module_->RegisterReceivePayload(codec));
+ for (int frame_idx = 0; frame_idx < 10; ++frame_idx) {
+ for (int packet_idx = 0; packet_idx < 5; ++packet_idx) {
+ int packet_size = PaddingPacket(padding_packet, timestamp, seq_num,
+ kPadSize);
+ ++seq_num;
+ EXPECT_EQ(0, video_module_->IncomingPacket(padding_packet, packet_size));
+ EXPECT_EQ(0, receiver_->payload_size());
+ EXPECT_EQ(packet_size - 12, receiver_->rtp_header().header.paddingLength);
+ }
+ timestamp += 3000;
+ fake_clock.IncrementTime(33);
+ }
+}
+
+} // namespace webrtc