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:
parent
5b4fe494e7
commit
8d0cd07d0c
@ -45,7 +45,6 @@
|
|||||||
'audio_processing/audio_processing_tests.gypi',
|
'audio_processing/audio_processing_tests.gypi',
|
||||||
'rtp_rtcp/source/rtp_rtcp_tests.gypi',
|
'rtp_rtcp/source/rtp_rtcp_tests.gypi',
|
||||||
'rtp_rtcp/test/testFec/test_fec.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/main/source/video_coding_test.gypi',
|
||||||
'video_coding/codecs/test/video_codecs_test_framework.gypi',
|
'video_coding/codecs/test/video_codecs_test_framework.gypi',
|
||||||
'video_coding/codecs/tools/video_codecs_tools.gypi',
|
'video_coding/codecs/tools/video_codecs_tools.gypi',
|
||||||
|
@ -522,6 +522,12 @@ WebRtc_Word32 RTCPSender::AddReportBlock(const WebRtc_UWord32 SSRC,
|
|||||||
"%s invalid argument", __FUNCTION__);
|
"%s invalid argument", __FUNCTION__);
|
||||||
return -1;
|
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();
|
RTCPReportBlock* copyReportBlock = new RTCPReportBlock();
|
||||||
memcpy(copyReportBlock, reportBlock, sizeof(RTCPReportBlock));
|
memcpy(copyReportBlock, reportBlock, sizeof(RTCPReportBlock));
|
||||||
_reportBlocks[SSRC] = copyReportBlock;
|
_reportBlocks[SSRC] = copyReportBlock;
|
||||||
|
@ -22,6 +22,12 @@
|
|||||||
'../../../',
|
'../../../',
|
||||||
],
|
],
|
||||||
'sources': [
|
'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.cc',
|
||||||
'fec_test_helper.h',
|
'fec_test_helper.h',
|
||||||
'producer_fec_unittest.cc',
|
'producer_fec_unittest.cc',
|
||||||
|
@ -24,7 +24,7 @@ class RtpRtcpAPITest : public ::testing::Test {
|
|||||||
protected:
|
protected:
|
||||||
RtpRtcpAPITest() {
|
RtpRtcpAPITest() {
|
||||||
test_CSRC[0] = 1234;
|
test_CSRC[0] = 1234;
|
||||||
test_CSRC[2] = 2345;
|
test_CSRC[1] = 2345;
|
||||||
test_id = 123;
|
test_id = 123;
|
||||||
test_ssrc = 3456;
|
test_ssrc = 3456;
|
||||||
test_timestamp = 4567;
|
test_timestamp = 4567;
|
||||||
|
@ -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:
|
|
@ -77,12 +77,35 @@ class LoopBackTransport : public webrtc::Transport {
|
|||||||
|
|
||||||
class RtpReceiver : public RtpData {
|
class RtpReceiver : public RtpData {
|
||||||
public:
|
public:
|
||||||
|
enum { kMaxPayloadSize = 1500 };
|
||||||
|
|
||||||
virtual WebRtc_Word32 OnReceivedPayloadData(
|
virtual WebRtc_Word32 OnReceivedPayloadData(
|
||||||
const WebRtc_UWord8* payloadData,
|
const WebRtc_UWord8* payloadData,
|
||||||
const WebRtc_UWord16 payloadSize,
|
const WebRtc_UWord16 payloadSize,
|
||||||
const webrtc::WebRtcRTPHeader* rtpHeader) {
|
const webrtc::WebRtcRTPHeader* rtpHeader) {
|
||||||
|
EXPECT_LE(payloadSize, kMaxPayloadSize);
|
||||||
|
memcpy(_payloadData, payloadData, payloadSize);
|
||||||
|
memcpy(&_rtpHeader, rtpHeader, sizeof(_rtpHeader));
|
||||||
|
_payloadSize = payloadSize;
|
||||||
return 0;
|
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
|
} // namespace webrtc
|
||||||
|
@ -328,5 +328,4 @@ TEST_F(RtpRtcpAudioTest, DTMF) {
|
|||||||
fake_clock.IncrementTime(20);
|
fake_clock.IncrementTime(20);
|
||||||
module1->Process();
|
module1->Process();
|
||||||
}
|
}
|
||||||
delete audioFeedback;
|
|
||||||
}
|
}
|
||||||
|
@ -10,10 +10,10 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <gtest/gtest.h>
|
|
||||||
|
|
||||||
|
#include "gmock/gmock.h"
|
||||||
|
#include "gtest/gtest.h"
|
||||||
#include "test_api.h"
|
#include "test_api.h"
|
||||||
|
|
||||||
#include "common_types.h"
|
#include "common_types.h"
|
||||||
#include "rtp_rtcp.h"
|
#include "rtp_rtcp.h"
|
||||||
#include "rtp_rtcp_defines.h"
|
#include "rtp_rtcp_defines.h"
|
||||||
@ -80,7 +80,7 @@ class RtpRtcpRtcpTest : public ::testing::Test {
|
|||||||
protected:
|
protected:
|
||||||
RtpRtcpRtcpTest() {
|
RtpRtcpRtcpTest() {
|
||||||
test_CSRC[0] = 1234;
|
test_CSRC[0] = 1234;
|
||||||
test_CSRC[2] = 2345;
|
test_CSRC[1] = 2345;
|
||||||
test_id = 123;
|
test_id = 123;
|
||||||
test_ssrc = 3456;
|
test_ssrc = 3456;
|
||||||
test_timestamp = 4567;
|
test_timestamp = 4567;
|
||||||
@ -97,11 +97,12 @@ class RtpRtcpRtcpTest : public ::testing::Test {
|
|||||||
|
|
||||||
RtpRtcp::Configuration configuration;
|
RtpRtcp::Configuration configuration;
|
||||||
configuration.id = test_id;
|
configuration.id = test_id;
|
||||||
configuration.audio = false;
|
configuration.audio = true;
|
||||||
configuration.clock = &fake_clock;
|
configuration.clock = &fake_clock;
|
||||||
configuration.outgoing_transport = transport1;
|
configuration.outgoing_transport = transport1;
|
||||||
configuration.rtcp_feedback = myRTCPFeedback1;
|
configuration.rtcp_feedback = myRTCPFeedback1;
|
||||||
configuration.intra_frame_callback = myRTCPFeedback1;
|
configuration.intra_frame_callback = myRTCPFeedback1;
|
||||||
|
configuration.incoming_data = receiver;
|
||||||
|
|
||||||
module1 = RtpRtcp::CreateRtpRtcp(configuration);
|
module1 = RtpRtcp::CreateRtpRtcp(configuration);
|
||||||
|
|
||||||
@ -150,6 +151,8 @@ class RtpRtcpRtcpTest : public ::testing::Test {
|
|||||||
virtual void TearDown() {
|
virtual void TearDown() {
|
||||||
delete module1;
|
delete module1;
|
||||||
delete module2;
|
delete module2;
|
||||||
|
delete myRTCPFeedback1;
|
||||||
|
delete myRTCPFeedback2;
|
||||||
delete transport1;
|
delete transport1;
|
||||||
delete transport2;
|
delete transport2;
|
||||||
delete receiver;
|
delete receiver;
|
||||||
@ -217,6 +220,8 @@ TEST_F(RtpRtcpRtcpTest, RTCP_CNAME) {
|
|||||||
|
|
||||||
TEST_F(RtpRtcpRtcpTest, RTCP) {
|
TEST_F(RtpRtcpRtcpTest, RTCP) {
|
||||||
RTCPReportBlock reportBlock;
|
RTCPReportBlock reportBlock;
|
||||||
|
reportBlock.remoteSSRC = 1;
|
||||||
|
reportBlock.sourceSSRC = 2;
|
||||||
reportBlock.cumulativeLost = 1;
|
reportBlock.cumulativeLost = 1;
|
||||||
reportBlock.delaySinceLastSR = 2;
|
reportBlock.delaySinceLastSR = 2;
|
||||||
reportBlock.extendedHighSeqNum = 3;
|
reportBlock.extendedHighSeqNum = 3;
|
||||||
|
@ -8,88 +8,157 @@
|
|||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <vector>
|
#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"
|
namespace webrtc {
|
||||||
#include "rtp_rtcp.h"
|
|
||||||
#include "rtp_rtcp_defines.h"
|
|
||||||
|
|
||||||
using namespace webrtc;
|
|
||||||
|
|
||||||
class RtpRtcpVideoTest : public ::testing::Test {
|
class RtpRtcpVideoTest : public ::testing::Test {
|
||||||
protected:
|
protected:
|
||||||
RtpRtcpVideoTest() {
|
RtpRtcpVideoTest()
|
||||||
test_id = 123;
|
: test_id_(123),
|
||||||
test_ssrc = 3456;
|
test_ssrc_(3456),
|
||||||
test_timestamp = 4567;
|
test_timestamp_(4567),
|
||||||
test_sequence_number = 2345;
|
test_sequence_number_(2345) {
|
||||||
}
|
}
|
||||||
~RtpRtcpVideoTest() {}
|
~RtpRtcpVideoTest() {}
|
||||||
|
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
transport = new LoopBackTransport();
|
transport_ = new LoopBackTransport();
|
||||||
receiver = new RtpReceiver();
|
receiver_ = new RtpReceiver();
|
||||||
RtpRtcp::Configuration configuration;
|
RtpRtcp::Configuration configuration;
|
||||||
configuration.id = test_id;
|
configuration.id = test_id_;
|
||||||
configuration.audio = false;
|
configuration.audio = false;
|
||||||
configuration.clock = &fake_clock;
|
configuration.clock = &fake_clock;
|
||||||
configuration.incoming_data = receiver;
|
configuration.incoming_data = receiver_;
|
||||||
configuration.outgoing_transport = transport;
|
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_->SetRTCPStatus(kRtcpCompound));
|
||||||
EXPECT_EQ(0, video_module->SetSSRC(test_ssrc));
|
EXPECT_EQ(0, video_module_->SetSSRC(test_ssrc_));
|
||||||
EXPECT_EQ(0, video_module->SetNACKStatus(kNackRtcp));
|
EXPECT_EQ(0, video_module_->SetNACKStatus(kNackRtcp));
|
||||||
EXPECT_EQ(0, video_module->SetStorePacketsStatus(true));
|
EXPECT_EQ(0, video_module_->SetStorePacketsStatus(true));
|
||||||
EXPECT_EQ(0, video_module->SetSendingStatus(true));
|
EXPECT_EQ(0, video_module_->SetSendingStatus(true));
|
||||||
|
|
||||||
transport->SetSendModule(video_module);
|
transport_->SetSendModule(video_module_);
|
||||||
|
|
||||||
VideoCodec video_codec;
|
VideoCodec video_codec;
|
||||||
memset(&video_codec, 0, sizeof(video_codec));
|
memset(&video_codec, 0, sizeof(video_codec));
|
||||||
video_codec.plType = 123;
|
video_codec.plType = 123;
|
||||||
memcpy(video_codec.plName, "I420", 5);
|
memcpy(video_codec.plName, "I420", 5);
|
||||||
|
|
||||||
EXPECT_EQ(0, video_module->RegisterSendPayload(video_codec));
|
EXPECT_EQ(0, video_module_->RegisterSendPayload(video_codec));
|
||||||
EXPECT_EQ(0, video_module->RegisterReceivePayload(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++) {
|
for (int n = 0; n < payload_data_length_; n++) {
|
||||||
payload_data[n] = n%10;
|
video_frame_[n] = n%10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 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() {
|
virtual void TearDown() {
|
||||||
delete video_module;
|
delete video_module_;
|
||||||
delete transport;
|
delete transport_;
|
||||||
delete receiver;
|
delete receiver_;
|
||||||
}
|
}
|
||||||
|
|
||||||
int test_id;
|
int test_id_;
|
||||||
RtpRtcp* video_module;
|
RtpRtcp* video_module_;
|
||||||
LoopBackTransport* transport;
|
LoopBackTransport* transport_;
|
||||||
RtpReceiver* receiver;
|
RtpReceiver* receiver_;
|
||||||
WebRtc_UWord32 test_ssrc;
|
WebRtc_UWord32 test_ssrc_;
|
||||||
WebRtc_UWord32 test_timestamp;
|
WebRtc_UWord32 test_timestamp_;
|
||||||
WebRtc_UWord16 test_sequence_number;
|
WebRtc_UWord16 test_sequence_number_;
|
||||||
WebRtc_UWord8 payload_data[65000];
|
WebRtc_UWord8 video_frame_[65000];
|
||||||
int payload_data_length;
|
int payload_data_length_;
|
||||||
FakeRtpRtcpClock fake_clock;
|
FakeRtpRtcpClock fake_clock;
|
||||||
|
enum { kPayloadType = 100 };
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(RtpRtcpVideoTest, BasicVideo) {
|
TEST_F(RtpRtcpVideoTest, BasicVideo) {
|
||||||
WebRtc_UWord32 timestamp = 3000;
|
WebRtc_UWord32 timestamp = 3000;
|
||||||
EXPECT_EQ(0, video_module->SendOutgoingData(webrtc::kVideoFrameDelta, 123,
|
EXPECT_EQ(0, video_module_->SendOutgoingData(kVideoFrameDelta, 123,
|
||||||
timestamp,
|
timestamp,
|
||||||
timestamp / 90,
|
timestamp / 90,
|
||||||
payload_data,
|
video_frame_,
|
||||||
payload_data_length));
|
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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user