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@3224 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
stefan@webrtc.org 2012-12-03 14:01:46 +00:00
parent 5b4fe494e7
commit 8d0cd07d0c
9 changed files with 166 additions and 101 deletions

View File

@ -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',

View File

@ -522,6 +522,12 @@ WebRtc_Word32 RTCPSender::AddReportBlock(const WebRtc_UWord32 SSRC,
"%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;

View File

@ -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',

View File

@ -24,7 +24,7 @@ class RtpRtcpAPITest : public ::testing::Test {
protected:
RtpRtcpAPITest() {
test_CSRC[0] = 1234;
test_CSRC[2] = 2345;
test_CSRC[1] = 2345;
test_id = 123;
test_ssrc = 3456;
test_timestamp = 4567;

View File

@ -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:

View File

@ -77,12 +77,35 @@ class LoopBackTransport : public webrtc::Transport {
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

View File

@ -328,5 +328,4 @@ TEST_F(RtpRtcpAudioTest, DTMF) {
fake_clock.IncrementTime(20);
module1->Process();
}
delete audioFeedback;
}

View File

@ -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 @@ class RtpRtcpRtcpTest : public ::testing::Test {
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 @@ class RtpRtcpRtcpTest : public ::testing::Test {
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 @@ class RtpRtcpRtcpTest : public ::testing::Test {
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_CNAME) {
TEST_F(RtpRtcpRtcpTest, RTCP) {
RTCPReportBlock reportBlock;
reportBlock.remoteSSRC = 1;
reportBlock.sourceSSRC = 2;
reportBlock.cumulativeLost = 1;
reportBlock.delaySinceLastSR = 2;
reportBlock.extendedHighSeqNum = 3;

View File

@ -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