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     ModuleRTPUtility::AssignUWord16ToBuffer(dataBuffer + 2,
     87                                                     sequence_number);
     88     ModuleRTPUtility::AssignUWord32ToBuffer(dataBuffer + 4, timestamp);
     89     ModuleRTPUtility::AssignUWord32ToBuffer(dataBuffer + 8,
     90                                                     0x1234);  // SSRC.
     91     int32_t rtpHeaderLength = 12;
     92     return rtpHeaderLength;
     93   }
     94 
     95   int PaddingPacket(uint8_t* buffer,
     96                     uint32_t timestamp,
     97                     uint32_t sequence_number,
     98                     int32_t bytes) {
     99     // Max in the RFC 3550 is 255 bytes, we limit it to be modulus 32 for SRTP.
    100     int max_length = 224;
    101 
    102     int padding_bytes_in_packet = max_length;
    103     if (bytes < max_length) {
    104       padding_bytes_in_packet = (bytes + 16) & 0xffe0;  // Keep our modulus 32.
    105     }
    106     // Correct seq num, timestamp and payload type.
    107     int header_length = BuildRTPheader(buffer, timestamp,
    108                                        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 (int 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   scoped_ptr<ReceiveStatistics> receive_statistics_;
    131   RTPPayloadRegistry rtp_payload_registry_;
    132   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   int payload_data_length_;
    141   SimulatedClock fake_clock;
    142   enum { kPayloadType = 100 };
    143 };
    144 
    145 TEST_F(RtpRtcpVideoTest, BasicVideo) {
    146   uint32_t timestamp = 3000;
    147   EXPECT_EQ(0, video_module_->SendOutgoingData(kVideoFrameDelta, 123,
    148                                                timestamp,
    149                                                timestamp / 90,
    150                                                video_frame_,
    151                                                payload_data_length_));
    152 }
    153 
    154 TEST_F(RtpRtcpVideoTest, PaddingOnlyFrames) {
    155   const int kPadSize = 255;
    156   uint8_t padding_packet[kPadSize];
    157   uint32_t seq_num = 0;
    158   uint32_t timestamp = 3000;
    159   VideoCodec codec;
    160   codec.codecType = kVideoCodecVP8;
    161   codec.plType = kPayloadType;
    162   strncpy(codec.plName, "VP8", 4);
    163   EXPECT_EQ(0, rtp_receiver_->RegisterReceivePayload(codec.plName,
    164                                                      codec.plType,
    165                                                      90000,
    166                                                      0,
    167                                                      codec.maxBitrate));
    168   for (int frame_idx = 0; frame_idx < 10; ++frame_idx) {
    169     for (int packet_idx = 0; packet_idx < 5; ++packet_idx) {
    170       int packet_size = PaddingPacket(padding_packet, timestamp, seq_num,
    171                                       kPadSize);
    172       ++seq_num;
    173       RTPHeader header;
    174       scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
    175       EXPECT_TRUE(parser->Parse(padding_packet, packet_size, &header));
    176       PayloadUnion payload_specific;
    177       EXPECT_TRUE(rtp_payload_registry_.GetPayloadSpecifics(header.payloadType,
    178                                                            &payload_specific));
    179       const uint8_t* payload = padding_packet + header.headerLength;
    180       const int payload_length = packet_size - header.headerLength;
    181       EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(header, payload,
    182                                                    payload_length,
    183                                                    payload_specific, true));
    184       EXPECT_EQ(0, receiver_->payload_size());
    185       EXPECT_EQ(payload_length, receiver_->rtp_header().header.paddingLength);
    186     }
    187     timestamp += 3000;
    188     fake_clock.AdvanceTimeMilliseconds(33);
    189   }
    190 }
    191 
    192 }  // namespace webrtc
    193