Home | History | Annotate | Download | only in video
      1 /*
      2  *  Copyright (c) 2013 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 // This file includes unit tests for SendStatisticsProxy.
     12 #include "webrtc/video/send_statistics_proxy.h"
     13 
     14 #include <map>
     15 #include <string>
     16 #include <vector>
     17 
     18 #include "testing/gtest/include/gtest/gtest.h"
     19 
     20 namespace webrtc {
     21 
     22 class SendStatisticsProxyTest : public ::testing::Test,
     23                                 protected SendStatisticsProxy::StatsProvider {
     24  public:
     25   SendStatisticsProxyTest() : avg_delay_ms_(0), max_delay_ms_(0) {}
     26   virtual ~SendStatisticsProxyTest() {}
     27 
     28  protected:
     29   virtual void SetUp() {
     30     statistics_proxy_.reset(
     31         new SendStatisticsProxy(GetTestConfig(), this));
     32     config_ = GetTestConfig();
     33     expected_ = VideoSendStream::Stats();
     34   }
     35 
     36   VideoSendStream::Config GetTestConfig() {
     37     VideoSendStream::Config config;
     38     config.rtp.ssrcs.push_back(17);
     39     config.rtp.ssrcs.push_back(42);
     40     return config;
     41   }
     42 
     43   virtual bool GetSendSideDelay(VideoSendStream::Stats* stats) OVERRIDE {
     44     stats->avg_delay_ms = avg_delay_ms_;
     45     stats->max_delay_ms = max_delay_ms_;
     46     return true;
     47   }
     48 
     49   virtual std::string GetCName() { return cname_; }
     50 
     51   void ExpectEqual(VideoSendStream::Stats one, VideoSendStream::Stats other) {
     52     EXPECT_EQ(one.avg_delay_ms, other.avg_delay_ms);
     53     EXPECT_EQ(one.input_frame_rate, other.input_frame_rate);
     54     EXPECT_EQ(one.encode_frame_rate, other.encode_frame_rate);
     55     EXPECT_EQ(one.avg_delay_ms, other.avg_delay_ms);
     56     EXPECT_EQ(one.max_delay_ms, other.max_delay_ms);
     57     EXPECT_EQ(one.suspended, other.suspended);
     58     EXPECT_EQ(one.c_name, other.c_name);
     59 
     60     EXPECT_EQ(one.substreams.size(), other.substreams.size());
     61     for (std::map<uint32_t, StreamStats>::const_iterator it =
     62              one.substreams.begin();
     63          it != one.substreams.end();
     64          ++it) {
     65       std::map<uint32_t, StreamStats>::const_iterator corresponding_it =
     66           other.substreams.find(it->first);
     67       ASSERT_TRUE(corresponding_it != other.substreams.end());
     68       const StreamStats& a = it->second;
     69       const StreamStats& b = corresponding_it->second;
     70 
     71       EXPECT_EQ(a.key_frames, b.key_frames);
     72       EXPECT_EQ(a.delta_frames, b.delta_frames);
     73       EXPECT_EQ(a.bitrate_bps, b.bitrate_bps);
     74 
     75       EXPECT_EQ(a.rtp_stats.bytes, b.rtp_stats.bytes);
     76       EXPECT_EQ(a.rtp_stats.header_bytes, b.rtp_stats.header_bytes);
     77       EXPECT_EQ(a.rtp_stats.padding_bytes, b.rtp_stats.padding_bytes);
     78       EXPECT_EQ(a.rtp_stats.packets, b.rtp_stats.packets);
     79       EXPECT_EQ(a.rtp_stats.retransmitted_packets,
     80                 b.rtp_stats.retransmitted_packets);
     81       EXPECT_EQ(a.rtp_stats.fec_packets, b.rtp_stats.fec_packets);
     82 
     83       EXPECT_EQ(a.rtcp_stats.fraction_lost, b.rtcp_stats.fraction_lost);
     84       EXPECT_EQ(a.rtcp_stats.cumulative_lost, b.rtcp_stats.cumulative_lost);
     85       EXPECT_EQ(a.rtcp_stats.extended_max_sequence_number,
     86                 b.rtcp_stats.extended_max_sequence_number);
     87       EXPECT_EQ(a.rtcp_stats.jitter, b.rtcp_stats.jitter);
     88     }
     89   }
     90 
     91   scoped_ptr<SendStatisticsProxy> statistics_proxy_;
     92   VideoSendStream::Config config_;
     93   int avg_delay_ms_;
     94   int max_delay_ms_;
     95   std::string cname_;
     96   VideoSendStream::Stats expected_;
     97   typedef std::map<uint32_t, StreamStats>::const_iterator StreamIterator;
     98 };
     99 
    100 TEST_F(SendStatisticsProxyTest, RtcpStatistics) {
    101   RtcpStatisticsCallback* callback = statistics_proxy_.get();
    102   for (std::vector<uint32_t>::const_iterator it = config_.rtp.ssrcs.begin();
    103        it != config_.rtp.ssrcs.end();
    104        ++it) {
    105     const uint32_t ssrc = *it;
    106     StreamStats& ssrc_stats = expected_.substreams[ssrc];
    107 
    108     // Add statistics with some arbitrary, but unique, numbers.
    109     uint32_t offset = ssrc * sizeof(RtcpStatistics);
    110     ssrc_stats.rtcp_stats.cumulative_lost = offset;
    111     ssrc_stats.rtcp_stats.extended_max_sequence_number = offset + 1;
    112     ssrc_stats.rtcp_stats.fraction_lost = offset + 2;
    113     ssrc_stats.rtcp_stats.jitter = offset + 3;
    114     callback->StatisticsUpdated(ssrc_stats.rtcp_stats, ssrc);
    115   }
    116 
    117   VideoSendStream::Stats stats = statistics_proxy_->GetStats();
    118   ExpectEqual(expected_, stats);
    119 }
    120 
    121 TEST_F(SendStatisticsProxyTest, FrameRates) {
    122   const int capture_fps = 31;
    123   const int encode_fps = 29;
    124 
    125   ViECaptureObserver* capture_observer = statistics_proxy_.get();
    126   capture_observer->CapturedFrameRate(0, capture_fps);
    127   ViEEncoderObserver* encoder_observer = statistics_proxy_.get();
    128   encoder_observer->OutgoingRate(0, encode_fps, 0);
    129 
    130   VideoSendStream::Stats stats = statistics_proxy_->GetStats();
    131   EXPECT_EQ(capture_fps, stats.input_frame_rate);
    132   EXPECT_EQ(encode_fps, stats.encode_frame_rate);
    133 }
    134 
    135 TEST_F(SendStatisticsProxyTest, Suspended) {
    136   // Verify that the value is false by default.
    137   EXPECT_FALSE(statistics_proxy_->GetStats().suspended);
    138 
    139   // Verify that we can set it to true.
    140   ViEEncoderObserver* encoder_observer = statistics_proxy_.get();
    141   encoder_observer->SuspendChange(0, true);
    142   EXPECT_TRUE(statistics_proxy_->GetStats().suspended);
    143 
    144   // Verify that we can set it back to false again.
    145   encoder_observer->SuspendChange(0, false);
    146   EXPECT_FALSE(statistics_proxy_->GetStats().suspended);
    147 }
    148 
    149 TEST_F(SendStatisticsProxyTest, FrameCounts) {
    150   FrameCountObserver* observer = statistics_proxy_.get();
    151   for (std::vector<uint32_t>::const_iterator it = config_.rtp.ssrcs.begin();
    152        it != config_.rtp.ssrcs.end();
    153        ++it) {
    154     const uint32_t ssrc = *it;
    155     // Add statistics with some arbitrary, but unique, numbers.
    156     StreamStats& stats = expected_.substreams[ssrc];
    157     uint32_t offset = ssrc * sizeof(StreamStats);
    158     stats.key_frames = offset;
    159     stats.delta_frames = offset + 1;
    160     observer->FrameCountUpdated(kVideoFrameKey, stats.key_frames, ssrc);
    161     observer->FrameCountUpdated(kVideoFrameDelta, stats.delta_frames, ssrc);
    162   }
    163 
    164   VideoSendStream::Stats stats = statistics_proxy_->GetStats();
    165   ExpectEqual(expected_, stats);
    166 }
    167 
    168 TEST_F(SendStatisticsProxyTest, DataCounters) {
    169   StreamDataCountersCallback* callback = statistics_proxy_.get();
    170   for (std::vector<uint32_t>::const_iterator it = config_.rtp.ssrcs.begin();
    171        it != config_.rtp.ssrcs.end();
    172        ++it) {
    173     const uint32_t ssrc = *it;
    174     StreamDataCounters& counters = expected_.substreams[ssrc].rtp_stats;
    175     // Add statistics with some arbitrary, but unique, numbers.
    176     uint32_t offset = ssrc * sizeof(StreamDataCounters);
    177     counters.bytes = offset;
    178     counters.header_bytes = offset + 1;
    179     counters.fec_packets = offset + 2;
    180     counters.padding_bytes = offset + 3;
    181     counters.retransmitted_packets = offset + 4;
    182     counters.packets = offset + 5;
    183     callback->DataCountersUpdated(counters, ssrc);
    184   }
    185 
    186   VideoSendStream::Stats stats = statistics_proxy_->GetStats();
    187   ExpectEqual(expected_, stats);
    188 }
    189 
    190 TEST_F(SendStatisticsProxyTest, Bitrate) {
    191   BitrateStatisticsObserver* observer = statistics_proxy_.get();
    192   for (std::vector<uint32_t>::const_iterator it = config_.rtp.ssrcs.begin();
    193        it != config_.rtp.ssrcs.end();
    194        ++it) {
    195     const uint32_t ssrc = *it;
    196     BitrateStatistics bitrate;
    197     bitrate.bitrate_bps = ssrc;
    198     observer->Notify(bitrate, ssrc);
    199     expected_.substreams[ssrc].bitrate_bps = ssrc;
    200   }
    201 
    202   VideoSendStream::Stats stats = statistics_proxy_->GetStats();
    203   ExpectEqual(expected_, stats);
    204 }
    205 
    206 TEST_F(SendStatisticsProxyTest, StreamStats) {
    207   avg_delay_ms_ = 1;
    208   max_delay_ms_ = 2;
    209   cname_ = "qwertyuiop";
    210 
    211   VideoSendStream::Stats stats = statistics_proxy_->GetStats();
    212 
    213   EXPECT_EQ(avg_delay_ms_, stats.avg_delay_ms);
    214   EXPECT_EQ(max_delay_ms_, stats.max_delay_ms);
    215   EXPECT_EQ(cname_, stats.c_name);
    216 }
    217 
    218 TEST_F(SendStatisticsProxyTest, NoSubstreams) {
    219   uint32_t exluded_ssrc =
    220       *std::max_element(config_.rtp.ssrcs.begin(), config_.rtp.ssrcs.end()) + 1;
    221   // From RtcpStatisticsCallback.
    222   RtcpStatistics rtcp_stats;
    223   RtcpStatisticsCallback* rtcp_callback = statistics_proxy_.get();
    224   rtcp_callback->StatisticsUpdated(rtcp_stats, exluded_ssrc);
    225 
    226   // From StreamDataCountersCallback.
    227   StreamDataCounters rtp_stats;
    228   StreamDataCountersCallback* rtp_callback = statistics_proxy_.get();
    229   rtp_callback->DataCountersUpdated(rtp_stats, exluded_ssrc);
    230 
    231   // From BitrateStatisticsObserver.
    232   BitrateStatistics bitrate;
    233   BitrateStatisticsObserver* bitrate_observer = statistics_proxy_.get();
    234   bitrate_observer->Notify(bitrate, exluded_ssrc);
    235 
    236   // From FrameCountObserver.
    237   FrameCountObserver* fps_observer = statistics_proxy_.get();
    238   fps_observer->FrameCountUpdated(kVideoFrameKey, 1, exluded_ssrc);
    239 
    240   VideoSendStream::Stats stats = statistics_proxy_->GetStats();
    241   EXPECT_TRUE(stats.substreams.empty());
    242 }
    243 
    244 }  // namespace webrtc
    245