1/*
2 *  Copyright (c) 2015 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#ifndef WEBRTC_VOICE_ENGINE_TEST_AUTO_TEST_FAKES_CONFERENCE_TRANSPORT_H_
12#define WEBRTC_VOICE_ENGINE_TEST_AUTO_TEST_FAKES_CONFERENCE_TRANSPORT_H_
13
14#include <deque>
15#include <map>
16#include <utility>
17
18#include "testing/gtest/include/gtest/gtest.h"
19#include "webrtc/base/basictypes.h"
20#include "webrtc/base/platform_thread.h"
21#include "webrtc/base/scoped_ptr.h"
22#include "webrtc/common_types.h"
23#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
24#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
25#include "webrtc/system_wrappers/include/event_wrapper.h"
26#include "webrtc/voice_engine/include/voe_base.h"
27#include "webrtc/voice_engine/include/voe_codec.h"
28#include "webrtc/voice_engine/include/voe_file.h"
29#include "webrtc/voice_engine/include/voe_network.h"
30#include "webrtc/voice_engine/include/voe_rtp_rtcp.h"
31#include "webrtc/voice_engine/test/auto_test/fakes/loudest_filter.h"
32
33static const size_t kMaxPacketSizeByte = 1500;
34
35namespace voetest {
36
37// This class is to simulate a conference call. There are two Voice Engines, one
38// for local channels and the other for remote channels. There is a simulated
39// reflector, which exchanges RTCP with local channels. For simplicity, it
40// also uses the Voice Engine for remote channels. One can add streams by
41// calling AddStream(), which creates a remote sender channel and a local
42// receive channel. The remote sender channel plays a file as microphone in a
43// looped fashion. Received streams are mixed and played.
44
45class ConferenceTransport: public webrtc::Transport {
46 public:
47  ConferenceTransport();
48  virtual ~ConferenceTransport();
49
50  /* SetRtt()
51   * Set RTT between local channels and reflector.
52   *
53   * Input:
54   *   rtt_ms : RTT in milliseconds.
55   */
56  void SetRtt(unsigned int rtt_ms);
57
58  /* AddStream()
59   * Adds a stream in the conference.
60   *
61   * Input:
62   *   file_name : name of the file to be added as microphone input.
63   *   format    : format of the input file.
64   *
65   * Returns stream id.
66   */
67  unsigned int AddStream(std::string file_name, webrtc::FileFormats format);
68
69  /* RemoveStream()
70   * Removes a stream with specified ID from the conference.
71   *
72   * Input:
73   *   id : stream id.
74   *
75   * Returns false if the specified stream does not exist, true if succeeds.
76   */
77  bool RemoveStream(unsigned int id);
78
79  /* StartPlayout()
80   * Starts playing out the stream with specified ID, using the default device.
81   *
82   * Input:
83   *   id : stream id.
84   *
85   * Returns false if the specified stream does not exist, true if succeeds.
86   */
87  bool StartPlayout(unsigned int id);
88
89  /* GetReceiverStatistics()
90   * Gets RTCP statistics of the stream with specified ID.
91   *
92   * Input:
93   *   id : stream id;
94   *   stats : pointer to a CallStatistics to store the result.
95   *
96   * Returns false if the specified stream does not exist, true if succeeds.
97   */
98  bool GetReceiverStatistics(unsigned int id, webrtc::CallStatistics* stats);
99
100  // Inherit from class webrtc::Transport.
101  bool SendRtp(const uint8_t* data,
102               size_t len,
103               const webrtc::PacketOptions& options) override;
104  bool SendRtcp(const uint8_t *data, size_t len) override;
105
106 private:
107  struct Packet {
108    enum Type { Rtp, Rtcp, } type_;
109
110    Packet() : len_(0) {}
111    Packet(Type type, const void* data, size_t len, uint32_t time_ms)
112        : type_(type), len_(len), send_time_ms_(time_ms) {
113      EXPECT_LE(len_, kMaxPacketSizeByte);
114      memcpy(data_, data, len_);
115    }
116
117    uint8_t data_[kMaxPacketSizeByte];
118    size_t len_;
119    uint32_t send_time_ms_;
120  };
121
122  static bool Run(void* transport) {
123    return static_cast<ConferenceTransport*>(transport)->DispatchPackets();
124  }
125
126  int GetReceiverChannelForSsrc(unsigned int sender_ssrc) const;
127  void StorePacket(Packet::Type type, const void* data, size_t len);
128  void SendPacket(const Packet& packet);
129  bool DispatchPackets();
130
131  const rtc::scoped_ptr<webrtc::CriticalSectionWrapper> pq_crit_;
132  const rtc::scoped_ptr<webrtc::CriticalSectionWrapper> stream_crit_;
133  const rtc::scoped_ptr<webrtc::EventWrapper> packet_event_;
134  rtc::PlatformThread thread_;
135
136  unsigned int rtt_ms_;
137  unsigned int stream_count_;
138
139  std::map<unsigned int, std::pair<int, int>> streams_
140    GUARDED_BY(stream_crit_.get());
141  std::deque<Packet> packet_queue_ GUARDED_BY(pq_crit_.get());
142
143  int local_sender_;  // Channel Id of local sender
144  int reflector_;
145
146  webrtc::VoiceEngine* local_voe_;
147  webrtc::VoEBase* local_base_;
148  webrtc::VoERTP_RTCP* local_rtp_rtcp_;
149  webrtc::VoENetwork* local_network_;
150
151  webrtc::VoiceEngine* remote_voe_;
152  webrtc::VoEBase* remote_base_;
153  webrtc::VoECodec* remote_codec_;
154  webrtc::VoERTP_RTCP* remote_rtp_rtcp_;
155  webrtc::VoENetwork* remote_network_;
156  webrtc::VoEFile* remote_file_;
157
158  LoudestFilter loudest_filter_;
159
160  const rtc::scoped_ptr<webrtc::RtpHeaderParser> rtp_header_parser_;
161};
162}  // namespace voetest
163
164#endif  // WEBRTC_VOICE_ENGINE_TEST_AUTO_TEST_FAKES_CONFERENCE_TRANSPORT_H_
165