Home | History | Annotate | Download | only in testAPI
      1 /*
      2  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #include <stdlib.h>
     12 
     13 #include <algorithm>
     14 #include <vector>
     15 
     16 #include "testing/gtest/include/gtest/gtest.h"
     17 #include "webrtc/common_types.h"
     18 #include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h"
     19 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
     20 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
     21 #include "webrtc/modules/rtp_rtcp/source/byte_io.h"
     22 #include "webrtc/modules/rtp_rtcp/source/rtp_receiver_video.h"
     23 #include "webrtc/modules/rtp_rtcp/test/testAPI/test_api.h"
     24 
     25 namespace {
     26 
     27 const unsigned char kPayloadType = 100;
     28 
     29 };
     30 
     31 namespace webrtc {
     32 
     33 class RtpRtcpVideoTest : public ::testing::Test {
     34  protected:
     35   RtpRtcpVideoTest()
     36       : rtp_payload_registry_(RTPPayloadStrategy::CreateStrategy(false)),
     37         test_ssrc_(3456),
     38         test_timestamp_(4567),
     39         test_sequence_number_(2345),
     40         fake_clock(123456) {}
     41   ~RtpRtcpVideoTest() {}
     42 
     43   virtual void SetUp() {
     44     transport_ = new LoopBackTransport();
     45     receiver_ = new TestRtpReceiver();
     46     receive_statistics_.reset(ReceiveStatistics::Create(&fake_clock));
     47     RtpRtcp::Configuration configuration;
     48     configuration.audio = false;
     49     configuration.clock = &fake_clock;
     50     configuration.outgoing_transport = transport_;
     51 
     52     video_module_ = RtpRtcp::CreateRtpRtcp(configuration);
     53     rtp_receiver_.reset(RtpReceiver::CreateVideoReceiver(
     54         &fake_clock, receiver_, NULL, &rtp_payload_registry_));
     55 
     56     video_module_->SetRTCPStatus(RtcpMode::kCompound);
     57     video_module_->SetSSRC(test_ssrc_);
     58     rtp_receiver_->SetNACKStatus(kNackRtcp);
     59     video_module_->SetStorePacketsStatus(true, 600);
     60     EXPECT_EQ(0, video_module_->SetSendingStatus(true));
     61 
     62     transport_->SetSendModule(video_module_, &rtp_payload_registry_,
     63                               rtp_receiver_.get(), receive_statistics_.get());
     64 
     65     VideoCodec video_codec;
     66     memset(&video_codec, 0, sizeof(video_codec));
     67     video_codec.plType = 123;
     68     memcpy(video_codec.plName, "I420", 5);
     69 
     70     EXPECT_EQ(0, video_module_->RegisterSendPayload(video_codec));
     71     EXPECT_EQ(0, rtp_receiver_->RegisterReceivePayload(video_codec.plName,
     72                                                        video_codec.plType,
     73                                                        90000,
     74                                                        0,
     75                                                        video_codec.maxBitrate));
     76 
     77     payload_data_length_ = sizeof(video_frame_);
     78 
     79     for (size_t n = 0; n < payload_data_length_; n++) {
     80       video_frame_[n] = n%10;
     81     }
     82   }
     83 
     84   size_t BuildRTPheader(uint8_t* dataBuffer,
     85                          uint32_t timestamp,
     86                          uint32_t sequence_number) {
     87     dataBuffer[0] = static_cast<uint8_t>(0x80);  // version 2
     88     dataBuffer[1] = static_cast<uint8_t>(kPayloadType);
     89     ByteWriter<uint16_t>::WriteBigEndian(dataBuffer + 2, sequence_number);
     90     ByteWriter<uint32_t>::WriteBigEndian(dataBuffer + 4, timestamp);
     91     ByteWriter<uint32_t>::WriteBigEndian(dataBuffer + 8, 0x1234);  // SSRC.
     92     size_t rtpHeaderLength = 12;
     93     return rtpHeaderLength;
     94   }
     95 
     96   size_t PaddingPacket(uint8_t* buffer,
     97                        uint32_t timestamp,
     98                        uint32_t sequence_number,
     99                        size_t bytes) {
    100     // Max in the RFC 3550 is 255 bytes, we limit it to be modulus 32 for SRTP.
    101     size_t max_length = 224;
    102 
    103     size_t padding_bytes_in_packet = max_length;
    104     if (bytes < max_length) {
    105       padding_bytes_in_packet = (bytes + 16) & 0xffe0;  // Keep our modulus 32.
    106     }
    107     // Correct seq num, timestamp and payload type.
    108     size_t header_length = BuildRTPheader(buffer, timestamp, sequence_number);
    109     buffer[0] |= 0x20;  // Set padding bit.
    110     int32_t* data =
    111         reinterpret_cast<int32_t*>(&(buffer[header_length]));
    112 
    113     // Fill data buffer with random data.
    114     for (size_t j = 0; j < (padding_bytes_in_packet >> 2); j++) {
    115       data[j] = rand();  // NOLINT
    116     }
    117     // Set number of padding bytes in the last byte of the packet.
    118     buffer[header_length + padding_bytes_in_packet - 1] =
    119         padding_bytes_in_packet;
    120     return padding_bytes_in_packet + header_length;
    121   }
    122 
    123   virtual void TearDown() {
    124     delete video_module_;
    125     delete transport_;
    126     delete receiver_;
    127   }
    128 
    129   int test_id_;
    130   rtc::scoped_ptr<ReceiveStatistics> receive_statistics_;
    131   RTPPayloadRegistry rtp_payload_registry_;
    132   rtc::scoped_ptr<RtpReceiver> rtp_receiver_;
    133   RtpRtcp* video_module_;
    134   LoopBackTransport* transport_;
    135   TestRtpReceiver* receiver_;
    136   uint32_t test_ssrc_;
    137   uint32_t test_timestamp_;
    138   uint16_t test_sequence_number_;
    139   uint8_t  video_frame_[65000];
    140   size_t payload_data_length_;
    141   SimulatedClock fake_clock;
    142 };
    143 
    144 TEST_F(RtpRtcpVideoTest, BasicVideo) {
    145   uint32_t timestamp = 3000;
    146   EXPECT_EQ(0, video_module_->SendOutgoingData(kVideoFrameDelta, 123,
    147                                                timestamp,
    148                                                timestamp / 90,
    149                                                video_frame_,
    150                                                payload_data_length_));
    151 }
    152 
    153 TEST_F(RtpRtcpVideoTest, PaddingOnlyFrames) {
    154   const size_t kPadSize = 255;
    155   uint8_t padding_packet[kPadSize];
    156   uint32_t seq_num = 0;
    157   uint32_t timestamp = 3000;
    158   VideoCodec codec;
    159   codec.codecType = kVideoCodecVP8;
    160   codec.plType = kPayloadType;
    161   strncpy(codec.plName, "VP8", 4);
    162   EXPECT_EQ(0, rtp_receiver_->RegisterReceivePayload(codec.plName,
    163                                                      codec.plType,
    164                                                      90000,
    165                                                      0,
    166                                                      codec.maxBitrate));
    167   for (int frame_idx = 0; frame_idx < 10; ++frame_idx) {
    168     for (int packet_idx = 0; packet_idx < 5; ++packet_idx) {
    169       size_t packet_size = PaddingPacket(padding_packet, timestamp, seq_num,
    170                                          kPadSize);
    171       ++seq_num;
    172       RTPHeader header;
    173       rtc::scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
    174       EXPECT_TRUE(parser->Parse(padding_packet, packet_size, &header));
    175       PayloadUnion payload_specific;
    176       EXPECT_TRUE(rtp_payload_registry_.GetPayloadSpecifics(header.payloadType,
    177                                                             &payload_specific));
    178       const uint8_t* payload = padding_packet + header.headerLength;
    179       const size_t payload_length = packet_size - header.headerLength;
    180       EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(header, payload,
    181                                                    payload_length,
    182                                                    payload_specific, true));
    183       EXPECT_EQ(0u, receiver_->payload_size());
    184       EXPECT_EQ(payload_length, receiver_->rtp_header().header.paddingLength);
    185     }
    186     timestamp += 3000;
    187     fake_clock.AdvanceTimeMilliseconds(33);
    188   }
    189 }
    190 
    191 }  // namespace webrtc
    192