blob: 22711bd5fb9b9c908160fbf5ebedd237d58193a4 [file] [log] [blame]
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
#include <deque>
#include <map>
#include <memory>
#include <utility>
#include "webrtc/common_types.h"
#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
#include "webrtc/rtc_base/basictypes.h"
#include "webrtc/rtc_base/criticalsection.h"
#include "webrtc/rtc_base/platform_thread.h"
#include "webrtc/system_wrappers/include/event_wrapper.h"
#include "webrtc/test/gtest.h"
#include "webrtc/voice_engine/include/voe_base.h"
#include "webrtc/voice_engine/include/voe_codec.h"
#include "webrtc/voice_engine/include/voe_file.h"
#include "webrtc/voice_engine/include/voe_network.h"
#include "webrtc/voice_engine/include/voe_rtp_rtcp.h"
#include "webrtc/voice_engine/test/auto_test/fakes/loudest_filter.h"
namespace webrtc {
namespace voetest {
static const size_t kMaxPacketSizeByte = 1500;
// This class is to simulate a conference call. There are two Voice Engines, one
// for local channels and the other for remote channels. There is a simulated
// reflector, which exchanges RTCP with local channels. For simplicity, it
// also uses the Voice Engine for remote channels. One can add streams by
// calling AddStream(), which creates a remote sender channel and a local
// receive channel. The remote sender channel plays a file as microphone in a
// looped fashion. Received streams are mixed and played.
class ConferenceTransport: public webrtc::Transport {
virtual ~ConferenceTransport();
/* SetRtt()
* Set RTT between local channels and reflector.
* Input:
* rtt_ms : RTT in milliseconds.
void SetRtt(unsigned int rtt_ms);
/* AddStream()
* Adds a stream in the conference.
* Input:
* file_name : name of the file to be added as microphone input.
* format : format of the input file.
* Returns stream id.
unsigned int AddStream(std::string file_name, webrtc::FileFormats format);
/* RemoveStream()
* Removes a stream with specified ID from the conference.
* Input:
* id : stream id.
* Returns false if the specified stream does not exist, true if succeeds.
bool RemoveStream(unsigned int id);
/* StartPlayout()
* Starts playing out the stream with specified ID, using the default device.
* Input:
* id : stream id.
* Returns false if the specified stream does not exist, true if succeeds.
bool StartPlayout(unsigned int id);
/* GetReceiverStatistics()
* Gets RTCP statistics of the stream with specified ID.
* Input:
* id : stream id;
* stats : pointer to a CallStatistics to store the result.
* Returns false if the specified stream does not exist, true if succeeds.
bool GetReceiverStatistics(unsigned int id, webrtc::CallStatistics* stats);
// Inherit from class webrtc::Transport.
bool SendRtp(const uint8_t* data,
size_t len,
const webrtc::PacketOptions& options) override;
bool SendRtcp(const uint8_t *data, size_t len) override;
struct Packet {
enum Type { Rtp, Rtcp, } type_;
Packet() : len_(0) {}
Packet(Type type, const void* data, size_t len, int64_t time_ms)
: type_(type), len_(len), send_time_ms_(time_ms) {
EXPECT_LE(len_, kMaxPacketSizeByte);
memcpy(data_, data, len_);
uint8_t data_[kMaxPacketSizeByte];
size_t len_;
int64_t send_time_ms_;
static bool Run(void* transport) {
return static_cast<ConferenceTransport*>(transport)->DispatchPackets();
int GetReceiverChannelForSsrc(unsigned int sender_ssrc) const;
void StorePacket(Packet::Type type, const void* data, size_t len);
void SendPacket(const Packet& packet);
bool DispatchPackets();
rtc::CriticalSection pq_crit_;
rtc::CriticalSection stream_crit_;
const std::unique_ptr<webrtc::EventWrapper> packet_event_;
rtc::PlatformThread thread_;
unsigned int rtt_ms_;
unsigned int stream_count_;
std::map<unsigned int, std::pair<int, int>> streams_ GUARDED_BY(stream_crit_);
std::deque<Packet> packet_queue_ GUARDED_BY(pq_crit_);
int local_sender_; // Channel Id of local sender
int reflector_;
webrtc::VoiceEngine* local_voe_;
webrtc::VoEBase* local_base_;
webrtc::VoERTP_RTCP* local_rtp_rtcp_;
webrtc::VoENetwork* local_network_;
rtc::scoped_refptr<webrtc::AudioProcessing> local_apm_;
webrtc::VoiceEngine* remote_voe_;
webrtc::VoEBase* remote_base_;
webrtc::VoECodec* remote_codec_;
webrtc::VoERTP_RTCP* remote_rtp_rtcp_;
webrtc::VoENetwork* remote_network_;
webrtc::VoEFile* remote_file_;
rtc::scoped_refptr<webrtc::AudioProcessing> remote_apm_;
LoudestFilter loudest_filter_;
const std::unique_ptr<webrtc::RtpHeaderParser> rtp_header_parser_;
} // namespace voetest
} // namespace webrtc