1afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue/*
2afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
3afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue *
4afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue *  Use of this source code is governed by a BSD-style license
5afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue *  that can be found in the LICENSE file in the root of the source
6afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue *  tree. An additional intellectual property rights grant can be found
7afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue *  in the file PATENTS.  All contributing project authors may
8afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue *  be found in the AUTHORS file in the root of the source tree.
9afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue */
10afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue
11afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue#ifndef WEBRTC_VOICE_ENGINE_TEST_AUTO_TEST_FAKES_CONFERENCE_TRANSPORT_H_
12afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue#define WEBRTC_VOICE_ENGINE_TEST_AUTO_TEST_FAKES_CONFERENCE_TRANSPORT_H_
13afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue
14afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue#include <deque>
15afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue#include <map>
16afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue#include <utility>
17afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue
18afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue#include "testing/gtest/include/gtest/gtest.h"
19afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue#include "webrtc/base/basictypes.h"
2012411ef40e08c5e28ccde54ab3418c96676ffcbcpbos#include "webrtc/base/platform_thread.h"
21afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue#include "webrtc/base/scoped_ptr.h"
22afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue#include "webrtc/common_types.h"
23ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
2498f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
2598f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/event_wrapper.h"
26afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue#include "webrtc/voice_engine/include/voe_base.h"
27afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue#include "webrtc/voice_engine/include/voe_codec.h"
28afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue#include "webrtc/voice_engine/include/voe_file.h"
29afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue#include "webrtc/voice_engine/include/voe_network.h"
30afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue#include "webrtc/voice_engine/include/voe_rtp_rtcp.h"
3103bb7c7bfac45e662e2159c111fb7f9bdb006d18minyue#include "webrtc/voice_engine/test/auto_test/fakes/loudest_filter.h"
32afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue
33afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyuestatic const size_t kMaxPacketSizeByte = 1500;
34afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue
35afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyuenamespace voetest {
36afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue
37afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue// This class is to simulate a conference call. There are two Voice Engines, one
38afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue// for local channels and the other for remote channels. There is a simulated
39afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue// reflector, which exchanges RTCP with local channels. For simplicity, it
40afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue// also uses the Voice Engine for remote channels. One can add streams by
41afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue// calling AddStream(), which creates a remote sender channel and a local
42afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue// receive channel. The remote sender channel plays a file as microphone in a
43afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue// looped fashion. Received streams are mixed and played.
44afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue
45afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyueclass ConferenceTransport: public webrtc::Transport {
46afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue public:
47afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  ConferenceTransport();
48afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  virtual ~ConferenceTransport();
49afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue
50afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  /* SetRtt()
51afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue   * Set RTT between local channels and reflector.
52afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue   *
53afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue   * Input:
54afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue   *   rtt_ms : RTT in milliseconds.
55afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue   */
56afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  void SetRtt(unsigned int rtt_ms);
57afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue
58afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  /* AddStream()
59afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue   * Adds a stream in the conference.
60afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue   *
6103bb7c7bfac45e662e2159c111fb7f9bdb006d18minyue   * Input:
6203bb7c7bfac45e662e2159c111fb7f9bdb006d18minyue   *   file_name : name of the file to be added as microphone input.
6303bb7c7bfac45e662e2159c111fb7f9bdb006d18minyue   *   format    : format of the input file.
6403bb7c7bfac45e662e2159c111fb7f9bdb006d18minyue   *
65afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue   * Returns stream id.
66afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue   */
6703bb7c7bfac45e662e2159c111fb7f9bdb006d18minyue  unsigned int AddStream(std::string file_name, webrtc::FileFormats format);
68afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue
69afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  /* RemoveStream()
70afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue   * Removes a stream with specified ID from the conference.
71afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue   *
72afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue   * Input:
73afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue   *   id : stream id.
74afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue   *
75afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue   * Returns false if the specified stream does not exist, true if succeeds.
76afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue   */
77afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  bool RemoveStream(unsigned int id);
78afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue
79afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  /* StartPlayout()
80afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue   * Starts playing out the stream with specified ID, using the default device.
81afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue   *
82afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue   * Input:
83afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue   *   id : stream id.
84afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue   *
85afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue   * Returns false if the specified stream does not exist, true if succeeds.
86afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue   */
87afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  bool StartPlayout(unsigned int id);
88afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue
89afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  /* GetReceiverStatistics()
90afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue   * Gets RTCP statistics of the stream with specified ID.
91afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue   *
92afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue   * Input:
93afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue   *   id : stream id;
94afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue   *   stats : pointer to a CallStatistics to store the result.
95afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue   *
96afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue   * Returns false if the specified stream does not exist, true if succeeds.
97afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue   */
98afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  bool GetReceiverStatistics(unsigned int id, webrtc::CallStatistics* stats);
99afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue
100afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  // Inherit from class webrtc::Transport.
1011d8a506405734d0cef9653704b036ca4f1388960stefan  bool SendRtp(const uint8_t* data,
1021d8a506405734d0cef9653704b036ca4f1388960stefan               size_t len,
1031d8a506405734d0cef9653704b036ca4f1388960stefan               const webrtc::PacketOptions& options) override;
1042d566686a23fe93ada58f1c38a0d4b9a0d68556epbos  bool SendRtcp(const uint8_t *data, size_t len) override;
105afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue
106afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue private:
107afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  struct Packet {
108afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue    enum Type { Rtp, Rtcp, } type_;
109afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue
110afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue    Packet() : len_(0) {}
1110c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    Packet(Type type, const void* data, size_t len, uint32_t time_ms)
112ac547a653862744d0aae560713f8418ad2852085Peter Boström        : type_(type), len_(len), send_time_ms_(time_ms) {
113afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue      EXPECT_LE(len_, kMaxPacketSizeByte);
114afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue      memcpy(data_, data, len_);
115afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue    }
116afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue
117afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue    uint8_t data_[kMaxPacketSizeByte];
118afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue    size_t len_;
1190c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    uint32_t send_time_ms_;
120afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  };
121afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue
122afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  static bool Run(void* transport) {
123afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue    return static_cast<ConferenceTransport*>(transport)->DispatchPackets();
124afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  }
125afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue
126afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  int GetReceiverChannelForSsrc(unsigned int sender_ssrc) const;
127ac547a653862744d0aae560713f8418ad2852085Peter Boström  void StorePacket(Packet::Type type, const void* data, size_t len);
12803bb7c7bfac45e662e2159c111fb7f9bdb006d18minyue  void SendPacket(const Packet& packet);
129afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  bool DispatchPackets();
130afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue
131afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  const rtc::scoped_ptr<webrtc::CriticalSectionWrapper> pq_crit_;
132afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  const rtc::scoped_ptr<webrtc::CriticalSectionWrapper> stream_crit_;
133afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  const rtc::scoped_ptr<webrtc::EventWrapper> packet_event_;
1348c38e8b9b96d72317d6ce94c1442113b4e385dcbPeter Boström  rtc::PlatformThread thread_;
135afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue
136afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  unsigned int rtt_ms_;
137afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  unsigned int stream_count_;
138afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue
139afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  std::map<unsigned int, std::pair<int, int>> streams_
140afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue    GUARDED_BY(stream_crit_.get());
141afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  std::deque<Packet> packet_queue_ GUARDED_BY(pq_crit_.get());
142afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue
143afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  int local_sender_;  // Channel Id of local sender
144afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  int reflector_;
145afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue
146afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  webrtc::VoiceEngine* local_voe_;
147afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  webrtc::VoEBase* local_base_;
148afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  webrtc::VoERTP_RTCP* local_rtp_rtcp_;
149afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  webrtc::VoENetwork* local_network_;
150afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue
151afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  webrtc::VoiceEngine* remote_voe_;
152afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  webrtc::VoEBase* remote_base_;
153afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  webrtc::VoECodec* remote_codec_;
154afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  webrtc::VoERTP_RTCP* remote_rtp_rtcp_;
155afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  webrtc::VoENetwork* remote_network_;
156afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue  webrtc::VoEFile* remote_file_;
15703bb7c7bfac45e662e2159c111fb7f9bdb006d18minyue
15803bb7c7bfac45e662e2159c111fb7f9bdb006d18minyue  LoudestFilter loudest_filter_;
15903bb7c7bfac45e662e2159c111fb7f9bdb006d18minyue
16003bb7c7bfac45e662e2159c111fb7f9bdb006d18minyue  const rtc::scoped_ptr<webrtc::RtpHeaderParser> rtp_header_parser_;
161afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue};
162afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue}  // namespace voetest
163afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue
164afef4bfd1c66b427aae531d8db98d5fb43390c0cMinyue#endif  // WEBRTC_VOICE_ENGINE_TEST_AUTO_TEST_FAKES_CONFERENCE_TRANSPORT_H_
165