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