Update libjingle 62364298->62472237
git-svn-id: http://webrtc.googlecode.com/svn/trunk@5632 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
1bbfb57d71
commit
40b3b68cdf
@ -41,17 +41,21 @@ class AudioTrack : public MediaStreamTrack<AudioTrackInterface> {
|
|||||||
static talk_base::scoped_refptr<AudioTrack> Create(
|
static talk_base::scoped_refptr<AudioTrack> Create(
|
||||||
const std::string& id, AudioSourceInterface* source);
|
const std::string& id, AudioSourceInterface* source);
|
||||||
|
|
||||||
virtual AudioSourceInterface* GetSource() const {
|
// AudioTrackInterface implementation.
|
||||||
|
virtual AudioSourceInterface* GetSource() const OVERRIDE {
|
||||||
return audio_source_.get();
|
return audio_source_.get();
|
||||||
}
|
}
|
||||||
|
// TODO(xians): Implement these methods.
|
||||||
// This method is used for supporting multiple sources/sinks for AudioTracks.
|
virtual void AddSink(AudioTrackSinkInterface* sink) OVERRIDE {}
|
||||||
virtual cricket::AudioRenderer* GetRenderer() {
|
virtual void RemoveSink(AudioTrackSinkInterface* sink) OVERRIDE {}
|
||||||
|
virtual bool GetSignalLevel(int* level) OVERRIDE { return false; }
|
||||||
|
virtual AudioProcessorInterface* GetAudioProcessor() OVERRIDE { return NULL; }
|
||||||
|
virtual cricket::AudioRenderer* GetRenderer() OVERRIDE {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implement MediaStreamTrack
|
// MediaStreamTrack implementation.
|
||||||
virtual std::string kind() const;
|
virtual std::string kind() const OVERRIDE;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
AudioTrack(const std::string& label, AudioSourceInterface* audio_source);
|
AudioTrack(const std::string& label, AudioSourceInterface* audio_source);
|
||||||
|
@ -174,18 +174,55 @@ class AudioTrackSinkInterface {
|
|||||||
virtual ~AudioTrackSinkInterface() {}
|
virtual ~AudioTrackSinkInterface() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Interface of the audio processor used by the audio track to collect
|
||||||
|
// statistics.
|
||||||
|
class AudioProcessorInterface : public talk_base::RefCountInterface {
|
||||||
|
public:
|
||||||
|
struct AudioProcessorStats {
|
||||||
|
AudioProcessorStats() : typing_noise_detected(false),
|
||||||
|
echo_return_loss(0),
|
||||||
|
echo_return_loss_enhancement(0),
|
||||||
|
echo_delay_median_ms(0),
|
||||||
|
aec_quality_min(0.0),
|
||||||
|
echo_delay_std_ms(0) {}
|
||||||
|
~AudioProcessorStats() {}
|
||||||
|
|
||||||
|
bool typing_noise_detected;
|
||||||
|
int echo_return_loss;
|
||||||
|
int echo_return_loss_enhancement;
|
||||||
|
int echo_delay_median_ms;
|
||||||
|
float aec_quality_min;
|
||||||
|
int echo_delay_std_ms;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get audio processor statistics.
|
||||||
|
virtual void GetStats(AudioProcessorStats* stats) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual ~AudioProcessorInterface() {}
|
||||||
|
};
|
||||||
|
|
||||||
class AudioTrackInterface : public MediaStreamTrackInterface {
|
class AudioTrackInterface : public MediaStreamTrackInterface {
|
||||||
public:
|
public:
|
||||||
// TODO(xians): Figure out if the following interface should be const or not.
|
// TODO(xians): Figure out if the following interface should be const or not.
|
||||||
virtual AudioSourceInterface* GetSource() const = 0;
|
virtual AudioSourceInterface* GetSource() const = 0;
|
||||||
|
|
||||||
// Adds/Removes a sink that will receive the audio data from the track.
|
// Add/Remove a sink that will receive the audio data from the track.
|
||||||
// TODO(xians): Make them pure virtual after Chrome implements these
|
virtual void AddSink(AudioTrackSinkInterface* sink) = 0;
|
||||||
// interfaces.
|
virtual void RemoveSink(AudioTrackSinkInterface* sink) = 0;
|
||||||
virtual void AddSink(AudioTrackSinkInterface* sink) {}
|
|
||||||
virtual void RemoveSink(AudioTrackSinkInterface* sink) {}
|
|
||||||
|
|
||||||
// Gets a pointer to the audio renderer of this AudioTrack.
|
// Get the signal level from the audio track.
|
||||||
|
// Return true on success, otherwise false.
|
||||||
|
// TODO(xians): Change the interface to int GetSignalLevel() and pure virtual
|
||||||
|
// after Chrome has the correct implementation of the interface.
|
||||||
|
virtual bool GetSignalLevel(int* level) { return false; }
|
||||||
|
|
||||||
|
// Get the audio processor used by the audio track. Return NULL if the track
|
||||||
|
// does not have any processor.
|
||||||
|
// TODO(xians): Make the interface pure virtual.
|
||||||
|
virtual AudioProcessorInterface* GetAudioProcessor() { return NULL; }
|
||||||
|
|
||||||
|
// Get a pointer to the audio renderer of this AudioTrack.
|
||||||
// The pointer is valid for the lifetime of this AudioTrack.
|
// The pointer is valid for the lifetime of this AudioTrack.
|
||||||
// TODO(xians): Remove the following interface after Chrome switches to
|
// TODO(xians): Remove the following interface after Chrome switches to
|
||||||
// AddSink() and RemoveSink() interfaces.
|
// AddSink() and RemoveSink() interfaces.
|
||||||
|
@ -321,8 +321,29 @@ bool MediaStreamSignaling::AddLocalStream(MediaStreamInterface* local_stream) {
|
|||||||
|
|
||||||
void MediaStreamSignaling::RemoveLocalStream(
|
void MediaStreamSignaling::RemoveLocalStream(
|
||||||
MediaStreamInterface* local_stream) {
|
MediaStreamInterface* local_stream) {
|
||||||
local_streams_->RemoveStream(local_stream);
|
AudioTrackVector audio_tracks = local_stream->GetAudioTracks();
|
||||||
|
for (AudioTrackVector::const_iterator it = audio_tracks.begin();
|
||||||
|
it != audio_tracks.end(); ++it) {
|
||||||
|
const TrackInfo* track_info = FindTrackInfo(local_audio_tracks_,
|
||||||
|
local_stream->label(),
|
||||||
|
(*it)->id());
|
||||||
|
if (track_info) {
|
||||||
|
stream_observer_->OnRemoveLocalAudioTrack(local_stream, *it,
|
||||||
|
track_info->ssrc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
VideoTrackVector video_tracks = local_stream->GetVideoTracks();
|
||||||
|
for (VideoTrackVector::const_iterator it = video_tracks.begin();
|
||||||
|
it != video_tracks.end(); ++it) {
|
||||||
|
const TrackInfo* track_info = FindTrackInfo(local_video_tracks_,
|
||||||
|
local_stream->label(),
|
||||||
|
(*it)->id());
|
||||||
|
if (track_info) {
|
||||||
|
stream_observer_->OnRemoveLocalVideoTrack(local_stream, *it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
local_streams_->RemoveStream(local_stream);
|
||||||
stream_observer_->OnRemoveLocalStream(local_stream);
|
stream_observer_->OnRemoveLocalStream(local_stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -725,7 +746,8 @@ void MediaStreamSignaling::UpdateLocalTracks(
|
|||||||
cricket::StreamParams params;
|
cricket::StreamParams params;
|
||||||
if (!cricket::GetStreamBySsrc(streams, info.ssrc, ¶ms) ||
|
if (!cricket::GetStreamBySsrc(streams, info.ssrc, ¶ms) ||
|
||||||
params.id != info.track_id || params.sync_label != info.stream_label) {
|
params.id != info.track_id || params.sync_label != info.stream_label) {
|
||||||
OnLocalTrackRemoved(info.stream_label, info.track_id, media_type);
|
OnLocalTrackRemoved(info.stream_label, info.track_id, info.ssrc,
|
||||||
|
media_type);
|
||||||
track_it = current_tracks->erase(track_it);
|
track_it = current_tracks->erase(track_it);
|
||||||
} else {
|
} else {
|
||||||
++track_it;
|
++track_it;
|
||||||
@ -787,6 +809,7 @@ void MediaStreamSignaling::OnLocalTrackSeen(
|
|||||||
void MediaStreamSignaling::OnLocalTrackRemoved(
|
void MediaStreamSignaling::OnLocalTrackRemoved(
|
||||||
const std::string& stream_label,
|
const std::string& stream_label,
|
||||||
const std::string& track_id,
|
const std::string& track_id,
|
||||||
|
uint32 ssrc,
|
||||||
cricket::MediaType media_type) {
|
cricket::MediaType media_type) {
|
||||||
MediaStreamInterface* stream = local_streams_->find(stream_label);
|
MediaStreamInterface* stream = local_streams_->find(stream_label);
|
||||||
if (!stream) {
|
if (!stream) {
|
||||||
@ -803,7 +826,7 @@ void MediaStreamSignaling::OnLocalTrackRemoved(
|
|||||||
if (!audio_track) {
|
if (!audio_track) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
stream_observer_->OnRemoveLocalAudioTrack(stream, audio_track);
|
stream_observer_->OnRemoveLocalAudioTrack(stream, audio_track, ssrc);
|
||||||
} else if (media_type == cricket::MEDIA_TYPE_VIDEO) {
|
} else if (media_type == cricket::MEDIA_TYPE_VIDEO) {
|
||||||
VideoTrackInterface* video_track = stream->FindVideoTrack(track_id);
|
VideoTrackInterface* video_track = stream->FindVideoTrack(track_id);
|
||||||
if (!video_track) {
|
if (!video_track) {
|
||||||
|
@ -92,7 +92,8 @@ class MediaStreamSignalingObserver {
|
|||||||
|
|
||||||
// Triggered when the local SessionDescription has removed an audio track.
|
// Triggered when the local SessionDescription has removed an audio track.
|
||||||
virtual void OnRemoveLocalAudioTrack(MediaStreamInterface* stream,
|
virtual void OnRemoveLocalAudioTrack(MediaStreamInterface* stream,
|
||||||
AudioTrackInterface* audio_track) = 0;
|
AudioTrackInterface* audio_track,
|
||||||
|
uint32 ssrc) = 0;
|
||||||
|
|
||||||
// Triggered when the local SessionDescription has removed a video track.
|
// Triggered when the local SessionDescription has removed a video track.
|
||||||
virtual void OnRemoveLocalVideoTrack(MediaStreamInterface* stream,
|
virtual void OnRemoveLocalVideoTrack(MediaStreamInterface* stream,
|
||||||
@ -354,6 +355,7 @@ class MediaStreamSignaling {
|
|||||||
// MediaStreamTrack in a MediaStream in |local_streams_|.
|
// MediaStreamTrack in a MediaStream in |local_streams_|.
|
||||||
void OnLocalTrackRemoved(const std::string& stream_label,
|
void OnLocalTrackRemoved(const std::string& stream_label,
|
||||||
const std::string& track_id,
|
const std::string& track_id,
|
||||||
|
uint32 ssrc,
|
||||||
cricket::MediaType media_type);
|
cricket::MediaType media_type);
|
||||||
|
|
||||||
void UpdateLocalRtpDataChannels(const cricket::StreamParamsVec& streams);
|
void UpdateLocalRtpDataChannels(const cricket::StreamParamsVec& streams);
|
||||||
|
@ -298,7 +298,8 @@ class MockSignalingObserver : public webrtc::MediaStreamSignalingObserver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnRemoveLocalAudioTrack(MediaStreamInterface* stream,
|
virtual void OnRemoveLocalAudioTrack(MediaStreamInterface* stream,
|
||||||
AudioTrackInterface* audio_track) {
|
AudioTrackInterface* audio_track,
|
||||||
|
uint32 ssrc) {
|
||||||
RemoveTrack(&local_audio_tracks_, stream, audio_track);
|
RemoveTrack(&local_audio_tracks_, stream, audio_track);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +42,10 @@ BEGIN_PROXY_MAP(AudioTrack)
|
|||||||
PROXY_CONSTMETHOD0(TrackState, state)
|
PROXY_CONSTMETHOD0(TrackState, state)
|
||||||
PROXY_CONSTMETHOD0(bool, enabled)
|
PROXY_CONSTMETHOD0(bool, enabled)
|
||||||
PROXY_CONSTMETHOD0(AudioSourceInterface*, GetSource)
|
PROXY_CONSTMETHOD0(AudioSourceInterface*, GetSource)
|
||||||
|
PROXY_METHOD1(void, AddSink, AudioTrackSinkInterface*)
|
||||||
|
PROXY_METHOD1(void, RemoveSink, AudioTrackSinkInterface*)
|
||||||
|
PROXY_METHOD1(bool, GetSignalLevel, int*)
|
||||||
|
PROXY_METHOD0(AudioProcessorInterface*, GetAudioProcessor)
|
||||||
PROXY_METHOD0(cricket::AudioRenderer*, GetRenderer)
|
PROXY_METHOD0(cricket::AudioRenderer*, GetRenderer)
|
||||||
|
|
||||||
PROXY_METHOD1(bool, set_enabled, bool)
|
PROXY_METHOD1(bool, set_enabled, bool)
|
||||||
|
@ -706,6 +706,7 @@ void PeerConnection::OnAddLocalAudioTrack(MediaStreamInterface* stream,
|
|||||||
AudioTrackInterface* audio_track,
|
AudioTrackInterface* audio_track,
|
||||||
uint32 ssrc) {
|
uint32 ssrc) {
|
||||||
stream_handler_container_->AddLocalAudioTrack(stream, audio_track, ssrc);
|
stream_handler_container_->AddLocalAudioTrack(stream, audio_track, ssrc);
|
||||||
|
stats_.AddLocalAudioTrack(audio_track, ssrc);
|
||||||
}
|
}
|
||||||
void PeerConnection::OnAddLocalVideoTrack(MediaStreamInterface* stream,
|
void PeerConnection::OnAddLocalVideoTrack(MediaStreamInterface* stream,
|
||||||
VideoTrackInterface* video_track,
|
VideoTrackInterface* video_track,
|
||||||
@ -714,8 +715,10 @@ void PeerConnection::OnAddLocalVideoTrack(MediaStreamInterface* stream,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PeerConnection::OnRemoveLocalAudioTrack(MediaStreamInterface* stream,
|
void PeerConnection::OnRemoveLocalAudioTrack(MediaStreamInterface* stream,
|
||||||
AudioTrackInterface* audio_track) {
|
AudioTrackInterface* audio_track,
|
||||||
|
uint32 ssrc) {
|
||||||
stream_handler_container_->RemoveLocalTrack(stream, audio_track);
|
stream_handler_container_->RemoveLocalTrack(stream, audio_track);
|
||||||
|
stats_.RemoveLocalAudioTrack(audio_track, ssrc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeerConnection::OnRemoveLocalVideoTrack(MediaStreamInterface* stream,
|
void PeerConnection::OnRemoveLocalVideoTrack(MediaStreamInterface* stream,
|
||||||
|
@ -136,7 +136,8 @@ class PeerConnection : public PeerConnectionInterface,
|
|||||||
uint32 ssrc) OVERRIDE;
|
uint32 ssrc) OVERRIDE;
|
||||||
virtual void OnRemoveLocalAudioTrack(
|
virtual void OnRemoveLocalAudioTrack(
|
||||||
MediaStreamInterface* stream,
|
MediaStreamInterface* stream,
|
||||||
AudioTrackInterface* audio_track) OVERRIDE;
|
AudioTrackInterface* audio_track,
|
||||||
|
uint32 ssrc) OVERRIDE;
|
||||||
virtual void OnRemoveLocalVideoTrack(
|
virtual void OnRemoveLocalVideoTrack(
|
||||||
MediaStreamInterface* stream,
|
MediaStreamInterface* stream,
|
||||||
VideoTrackInterface* video_track) OVERRIDE;
|
VideoTrackInterface* video_track) OVERRIDE;
|
||||||
|
@ -201,6 +201,19 @@ void StatsReport::AddBoolean(const std::string& name, bool value) {
|
|||||||
AddValue(name, value ? "true" : "false");
|
AddValue(name, value ? "true" : "false");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StatsReport::ReplaceValue(const std::string& name,
|
||||||
|
const std::string& value) {
|
||||||
|
for (Values::iterator it = values.begin(); it != values.end(); ++it) {
|
||||||
|
if ((*it).name == name) {
|
||||||
|
it->value = value;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// It is not reachable here, add an ASSERT to make sure the overwriting is
|
||||||
|
// always a success.
|
||||||
|
ASSERT(false);
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
typedef std::map<std::string, StatsReport> StatsMap;
|
typedef std::map<std::string, StatsReport> StatsMap;
|
||||||
|
|
||||||
@ -458,6 +471,32 @@ void StatsCollector::AddStream(MediaStreamInterface* stream) {
|
|||||||
&reports_);
|
&reports_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StatsCollector::AddLocalAudioTrack(AudioTrackInterface* audio_track,
|
||||||
|
uint32 ssrc) {
|
||||||
|
ASSERT(audio_track != NULL);
|
||||||
|
#ifdef _DEBUG
|
||||||
|
for (LocalAudioTrackVector::iterator it = local_audio_tracks_.begin();
|
||||||
|
it != local_audio_tracks_.end(); ++it) {
|
||||||
|
ASSERT(it->first != audio_track || it->second != ssrc);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
local_audio_tracks_.push_back(std::make_pair(audio_track, ssrc));
|
||||||
|
}
|
||||||
|
|
||||||
|
void StatsCollector::RemoveLocalAudioTrack(AudioTrackInterface* audio_track,
|
||||||
|
uint32 ssrc) {
|
||||||
|
ASSERT(audio_track != NULL);
|
||||||
|
for (LocalAudioTrackVector::iterator it = local_audio_tracks_.begin();
|
||||||
|
it != local_audio_tracks_.end(); ++it) {
|
||||||
|
if (it->first == audio_track && it->second == ssrc) {
|
||||||
|
local_audio_tracks_.erase(it);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(false);
|
||||||
|
}
|
||||||
|
|
||||||
bool StatsCollector::GetStats(MediaStreamTrackInterface* track,
|
bool StatsCollector::GetStats(MediaStreamTrackInterface* track,
|
||||||
StatsReports* reports) {
|
StatsReports* reports) {
|
||||||
ASSERT(reports != NULL);
|
ASSERT(reports != NULL);
|
||||||
@ -784,6 +823,8 @@ void StatsCollector::ExtractVoiceInfo() {
|
|||||||
}
|
}
|
||||||
ExtractStatsFromList(voice_info.receivers, transport_id, this);
|
ExtractStatsFromList(voice_info.receivers, transport_id, this);
|
||||||
ExtractStatsFromList(voice_info.senders, transport_id, this);
|
ExtractStatsFromList(voice_info.senders, transport_id, this);
|
||||||
|
|
||||||
|
UpdateStatsFromExistingLocalAudioTracks();
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatsCollector::ExtractVideoInfo(
|
void StatsCollector::ExtractVideoInfo(
|
||||||
@ -840,19 +881,86 @@ bool StatsCollector::GetTransportIdFromProxy(const std::string& proxy,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
StatsReport* StatsCollector::GetOrCreateReport(const std::string& type,
|
StatsReport* StatsCollector::GetReport(const std::string& type,
|
||||||
const std::string& id) {
|
const std::string& id) {
|
||||||
std::string statsid = StatsId(type, id);
|
std::string statsid = StatsId(type, id);
|
||||||
StatsReport* report = NULL;
|
StatsReport* report = NULL;
|
||||||
std::map<std::string, StatsReport>::iterator it = reports_.find(statsid);
|
std::map<std::string, StatsReport>::iterator it = reports_.find(statsid);
|
||||||
if (it == reports_.end()) {
|
if (it != reports_.end())
|
||||||
report = &reports_[statsid]; // Create new element.
|
|
||||||
report->id = statsid;
|
|
||||||
report->type = type;
|
|
||||||
} else {
|
|
||||||
report = &(it->second);
|
report = &(it->second);
|
||||||
}
|
|
||||||
return report;
|
return report;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StatsReport* StatsCollector::GetOrCreateReport(const std::string& type,
|
||||||
|
const std::string& id) {
|
||||||
|
StatsReport* report = GetReport(type, id);
|
||||||
|
if (report == NULL) {
|
||||||
|
std::string statsid = StatsId(type, id);
|
||||||
|
report = &reports_[statsid]; // Create new element.
|
||||||
|
report->id = statsid;
|
||||||
|
report->type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
return report;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StatsCollector::UpdateStatsFromExistingLocalAudioTracks() {
|
||||||
|
// Loop through the existing local audio tracks.
|
||||||
|
for (LocalAudioTrackVector::const_iterator it = local_audio_tracks_.begin();
|
||||||
|
it != local_audio_tracks_.end(); ++it) {
|
||||||
|
AudioTrackInterface* track = it->first;
|
||||||
|
uint32 ssrc = it->second;
|
||||||
|
std::string ssrc_id = talk_base::ToString<uint32>(ssrc);
|
||||||
|
StatsReport* report = GetReport(StatsReport::kStatsReportTypeSsrc,
|
||||||
|
ssrc_id);
|
||||||
|
ASSERT(report != NULL);
|
||||||
|
|
||||||
|
// The same ssrc can be used by both local and remote audio tracks.
|
||||||
|
std::string track_id;
|
||||||
|
if (!ExtractValueFromReport(*report,
|
||||||
|
StatsReport::kStatsValueNameTrackId,
|
||||||
|
&track_id) ||
|
||||||
|
track_id != track->id()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateReportFromAudioTrack(track, report);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StatsCollector::UpdateReportFromAudioTrack(AudioTrackInterface* track,
|
||||||
|
StatsReport* report) {
|
||||||
|
ASSERT(track != NULL);
|
||||||
|
if (report == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int signal_level = 0;
|
||||||
|
if (track->GetSignalLevel(&signal_level)) {
|
||||||
|
report->ReplaceValue(StatsReport::kStatsValueNameAudioInputLevel,
|
||||||
|
talk_base::ToString<int>(signal_level));
|
||||||
|
}
|
||||||
|
|
||||||
|
talk_base::scoped_refptr<AudioProcessorInterface> audio_processor(
|
||||||
|
track->GetAudioProcessor());
|
||||||
|
if (audio_processor.get() == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
AudioProcessorInterface::AudioProcessorStats stats;
|
||||||
|
audio_processor->GetStats(&stats);
|
||||||
|
report->ReplaceValue(StatsReport::kStatsValueNameTypingNoiseState,
|
||||||
|
stats.typing_noise_detected ? "true" : "false");
|
||||||
|
report->ReplaceValue(StatsReport::kStatsValueNameEchoReturnLoss,
|
||||||
|
talk_base::ToString<int>(stats.echo_return_loss));
|
||||||
|
report->ReplaceValue(
|
||||||
|
StatsReport::kStatsValueNameEchoReturnLossEnhancement,
|
||||||
|
talk_base::ToString<int>(stats.echo_return_loss_enhancement));
|
||||||
|
report->ReplaceValue(StatsReport::kStatsValueNameEchoDelayMedian,
|
||||||
|
talk_base::ToString<int>(stats.echo_delay_median_ms));
|
||||||
|
report->ReplaceValue(StatsReport::kStatsValueNameEchoCancellationQualityMin,
|
||||||
|
talk_base::ToString<float>(stats.aec_quality_min));
|
||||||
|
report->ReplaceValue(StatsReport::kStatsValueNameEchoDelayStdDev,
|
||||||
|
talk_base::ToString<int>(stats.echo_delay_std_ms));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@ -31,8 +31,9 @@
|
|||||||
#ifndef TALK_APP_WEBRTC_STATSCOLLECTOR_H_
|
#ifndef TALK_APP_WEBRTC_STATSCOLLECTOR_H_
|
||||||
#define TALK_APP_WEBRTC_STATSCOLLECTOR_H_
|
#define TALK_APP_WEBRTC_STATSCOLLECTOR_H_
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "talk/app/webrtc/mediastreaminterface.h"
|
#include "talk/app/webrtc/mediastreaminterface.h"
|
||||||
#include "talk/app/webrtc/peerconnectioninterface.h"
|
#include "talk/app/webrtc/peerconnectioninterface.h"
|
||||||
@ -57,6 +58,13 @@ class StatsCollector {
|
|||||||
// to GetStats.
|
// to GetStats.
|
||||||
void AddStream(MediaStreamInterface* stream);
|
void AddStream(MediaStreamInterface* stream);
|
||||||
|
|
||||||
|
// Adds a local audio track that is used for getting some voice statistics.
|
||||||
|
void AddLocalAudioTrack(AudioTrackInterface* audio_track, uint32 ssrc);
|
||||||
|
|
||||||
|
// Removes a local audio tracks that is used for getting some voice
|
||||||
|
// statistics.
|
||||||
|
void RemoveLocalAudioTrack(AudioTrackInterface* audio_track, uint32 ssrc);
|
||||||
|
|
||||||
// Gather statistics from the session and store them for future use.
|
// Gather statistics from the session and store them for future use.
|
||||||
void UpdateStats(PeerConnectionInterface::StatsOutputLevel level);
|
void UpdateStats(PeerConnectionInterface::StatsOutputLevel level);
|
||||||
|
|
||||||
@ -95,6 +103,13 @@ class StatsCollector {
|
|||||||
WebRtcSession* session() { return session_; }
|
WebRtcSession* session() { return session_; }
|
||||||
webrtc::StatsReport* GetOrCreateReport(const std::string& type,
|
webrtc::StatsReport* GetOrCreateReport(const std::string& type,
|
||||||
const std::string& id);
|
const std::string& id);
|
||||||
|
webrtc::StatsReport* GetReport(const std::string& type,
|
||||||
|
const std::string& id);
|
||||||
|
|
||||||
|
// Helper method to get stats from the local audio tracks.
|
||||||
|
void UpdateStatsFromExistingLocalAudioTracks();
|
||||||
|
void UpdateReportFromAudioTrack(AudioTrackInterface* track,
|
||||||
|
StatsReport* report);
|
||||||
|
|
||||||
// A map from the report id to the report.
|
// A map from the report id to the report.
|
||||||
std::map<std::string, StatsReport> reports_;
|
std::map<std::string, StatsReport> reports_;
|
||||||
@ -103,6 +118,10 @@ class StatsCollector {
|
|||||||
double stats_gathering_started_;
|
double stats_gathering_started_;
|
||||||
talk_base::Timing timing_;
|
talk_base::Timing timing_;
|
||||||
cricket::ProxyTransportMap proxy_to_transport_;
|
cricket::ProxyTransportMap proxy_to_transport_;
|
||||||
|
|
||||||
|
typedef std::vector<std::pair<AudioTrackInterface*, uint32> >
|
||||||
|
LocalAudioTrackVector;
|
||||||
|
LocalAudioTrackVector local_audio_tracks_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@ -29,6 +29,8 @@
|
|||||||
#include "talk/app/webrtc/statscollector.h"
|
#include "talk/app/webrtc/statscollector.h"
|
||||||
|
|
||||||
#include "talk/app/webrtc/mediastream.h"
|
#include "talk/app/webrtc/mediastream.h"
|
||||||
|
#include "talk/app/webrtc/mediastreaminterface.h"
|
||||||
|
#include "talk/app/webrtc/mediastreamtrack.h"
|
||||||
#include "talk/app/webrtc/videotrack.h"
|
#include "talk/app/webrtc/videotrack.h"
|
||||||
#include "talk/base/base64.h"
|
#include "talk/base/base64.h"
|
||||||
#include "talk/base/fakesslidentity.h"
|
#include "talk/base/fakesslidentity.h"
|
||||||
@ -47,6 +49,8 @@ using testing::Return;
|
|||||||
using testing::ReturnNull;
|
using testing::ReturnNull;
|
||||||
using testing::SetArgPointee;
|
using testing::SetArgPointee;
|
||||||
using webrtc::PeerConnectionInterface;
|
using webrtc::PeerConnectionInterface;
|
||||||
|
using webrtc::StatsReport;
|
||||||
|
using webrtc::StatsReports;
|
||||||
|
|
||||||
namespace cricket {
|
namespace cricket {
|
||||||
|
|
||||||
@ -63,6 +67,7 @@ const char kNoReports[] = "NO REPORTS";
|
|||||||
|
|
||||||
// Constant names for track identification.
|
// Constant names for track identification.
|
||||||
const char kTrackId[] = "somename";
|
const char kTrackId[] = "somename";
|
||||||
|
const char kAudioTrackId[] = "audio_track_id";
|
||||||
const uint32 kSsrcOfTrack = 1234;
|
const uint32 kSsrcOfTrack = 1234;
|
||||||
|
|
||||||
class MockWebRtcSession : public webrtc::WebRtcSession {
|
class MockWebRtcSession : public webrtc::WebRtcSession {
|
||||||
@ -71,6 +76,7 @@ class MockWebRtcSession : public webrtc::WebRtcSession {
|
|||||||
: WebRtcSession(channel_manager, talk_base::Thread::Current(),
|
: WebRtcSession(channel_manager, talk_base::Thread::Current(),
|
||||||
talk_base::Thread::Current(), NULL, NULL) {
|
talk_base::Thread::Current(), NULL, NULL) {
|
||||||
}
|
}
|
||||||
|
MOCK_METHOD0(voice_channel, cricket::VoiceChannel*());
|
||||||
MOCK_METHOD0(video_channel, cricket::VideoChannel*());
|
MOCK_METHOD0(video_channel, cricket::VideoChannel*());
|
||||||
MOCK_METHOD2(GetTrackIdBySsrc, bool(uint32, std::string*));
|
MOCK_METHOD2(GetTrackIdBySsrc, bool(uint32, std::string*));
|
||||||
MOCK_METHOD1(GetStats, bool(cricket::SessionStats*));
|
MOCK_METHOD1(GetStats, bool(cricket::SessionStats*));
|
||||||
@ -86,10 +92,60 @@ class MockVideoMediaChannel : public cricket::FakeVideoMediaChannel {
|
|||||||
MOCK_METHOD2(GetStats, bool(const StatsOptions&, cricket::VideoMediaInfo*));
|
MOCK_METHOD2(GetStats, bool(const StatsOptions&, cricket::VideoMediaInfo*));
|
||||||
};
|
};
|
||||||
|
|
||||||
bool GetValue(const webrtc::StatsReport* report,
|
class MockVoiceMediaChannel : public cricket::FakeVoiceMediaChannel {
|
||||||
|
public:
|
||||||
|
MockVoiceMediaChannel() : cricket::FakeVoiceMediaChannel(NULL) {
|
||||||
|
}
|
||||||
|
MOCK_METHOD1(GetStats, bool(cricket::VoiceMediaInfo*));
|
||||||
|
};
|
||||||
|
|
||||||
|
class FakeAudioProcessor : public webrtc::AudioProcessorInterface {
|
||||||
|
public:
|
||||||
|
FakeAudioProcessor() {}
|
||||||
|
~FakeAudioProcessor() {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual void GetStats(
|
||||||
|
AudioProcessorInterface::AudioProcessorStats* stats) OVERRIDE {
|
||||||
|
stats->typing_noise_detected = true;
|
||||||
|
stats->echo_return_loss = 2;
|
||||||
|
stats->echo_return_loss_enhancement = 3;
|
||||||
|
stats->echo_delay_median_ms = 4;
|
||||||
|
stats->aec_quality_min = 5.1f;
|
||||||
|
stats->echo_delay_std_ms = 6;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class FakeLocalAudioTrack
|
||||||
|
: public webrtc::MediaStreamTrack<webrtc::AudioTrackInterface> {
|
||||||
|
public:
|
||||||
|
explicit FakeLocalAudioTrack(const std::string& id)
|
||||||
|
: webrtc::MediaStreamTrack<webrtc::AudioTrackInterface>(id),
|
||||||
|
processor_(new talk_base::RefCountedObject<FakeAudioProcessor>()) {}
|
||||||
|
std::string kind() const OVERRIDE {
|
||||||
|
return "audio";
|
||||||
|
}
|
||||||
|
virtual webrtc::AudioSourceInterface* GetSource() const OVERRIDE {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
virtual void AddSink(webrtc::AudioTrackSinkInterface* sink) OVERRIDE {}
|
||||||
|
virtual void RemoveSink(webrtc::AudioTrackSinkInterface* sink) OVERRIDE {}
|
||||||
|
virtual bool GetSignalLevel(int* level) OVERRIDE {
|
||||||
|
*level = 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
virtual webrtc::AudioProcessorInterface* GetAudioProcessor() OVERRIDE {
|
||||||
|
return processor_.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
talk_base::scoped_refptr<FakeAudioProcessor> processor_;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool GetValue(const StatsReport* report,
|
||||||
const std::string& name,
|
const std::string& name,
|
||||||
std::string* value) {
|
std::string* value) {
|
||||||
webrtc::StatsReport::Values::const_iterator it = report->values.begin();
|
StatsReport::Values::const_iterator it = report->values.begin();
|
||||||
for (; it != report->values.end(); ++it) {
|
for (; it != report->values.end(); ++it) {
|
||||||
if (it->name == name) {
|
if (it->name == name) {
|
||||||
*value = it->value;
|
*value = it->value;
|
||||||
@ -100,7 +156,7 @@ bool GetValue(const webrtc::StatsReport* report,
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string ExtractStatsValue(const std::string& type,
|
std::string ExtractStatsValue(const std::string& type,
|
||||||
const webrtc::StatsReports& reports,
|
const StatsReports& reports,
|
||||||
const std::string name) {
|
const std::string name) {
|
||||||
if (reports.empty()) {
|
if (reports.empty()) {
|
||||||
return kNoReports;
|
return kNoReports;
|
||||||
@ -119,8 +175,8 @@ std::string ExtractStatsValue(const std::string& type,
|
|||||||
|
|
||||||
// Finds the |n|-th report of type |type| in |reports|.
|
// Finds the |n|-th report of type |type| in |reports|.
|
||||||
// |n| starts from 1 for finding the first report.
|
// |n| starts from 1 for finding the first report.
|
||||||
const webrtc::StatsReport* FindNthReportByType(
|
const StatsReport* FindNthReportByType(
|
||||||
const webrtc::StatsReports& reports, const std::string& type, int n) {
|
const StatsReports& reports, const std::string& type, int n) {
|
||||||
for (size_t i = 0; i < reports.size(); ++i) {
|
for (size_t i = 0; i < reports.size(); ++i) {
|
||||||
if (reports[i].type == type) {
|
if (reports[i].type == type) {
|
||||||
n--;
|
n--;
|
||||||
@ -131,8 +187,8 @@ const webrtc::StatsReport* FindNthReportByType(
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const webrtc::StatsReport* FindReportById(const webrtc::StatsReports& reports,
|
const StatsReport* FindReportById(const StatsReports& reports,
|
||||||
const std::string& id) {
|
const std::string& id) {
|
||||||
for (size_t i = 0; i < reports.size(); ++i) {
|
for (size_t i = 0; i < reports.size(); ++i) {
|
||||||
if (reports[i].id == id) {
|
if (reports[i].id == id) {
|
||||||
return &reports[i];
|
return &reports[i];
|
||||||
@ -141,16 +197,16 @@ const webrtc::StatsReport* FindReportById(const webrtc::StatsReports& reports,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ExtractSsrcStatsValue(webrtc::StatsReports reports,
|
std::string ExtractSsrcStatsValue(StatsReports reports,
|
||||||
const std::string& name) {
|
const std::string& name) {
|
||||||
return ExtractStatsValue(
|
return ExtractStatsValue(
|
||||||
webrtc::StatsReport::kStatsReportTypeSsrc, reports, name);
|
StatsReport::kStatsReportTypeSsrc, reports, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ExtractBweStatsValue(webrtc::StatsReports reports,
|
std::string ExtractBweStatsValue(StatsReports reports,
|
||||||
const std::string& name) {
|
const std::string& name) {
|
||||||
return ExtractStatsValue(
|
return ExtractStatsValue(
|
||||||
webrtc::StatsReport::kStatsReportTypeBwe, reports, name);
|
StatsReport::kStatsReportTypeBwe, reports, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DerToPem(const std::string& der) {
|
std::string DerToPem(const std::string& der) {
|
||||||
@ -167,18 +223,18 @@ std::vector<std::string> DersToPems(
|
|||||||
return pems;
|
return pems;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckCertChainReports(const webrtc::StatsReports& reports,
|
void CheckCertChainReports(const StatsReports& reports,
|
||||||
const std::vector<std::string>& ders,
|
const std::vector<std::string>& ders,
|
||||||
const std::string& start_id) {
|
const std::string& start_id) {
|
||||||
std::string certificate_id = start_id;
|
std::string certificate_id = start_id;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
const webrtc::StatsReport* report = FindReportById(reports, certificate_id);
|
const StatsReport* report = FindReportById(reports, certificate_id);
|
||||||
ASSERT_TRUE(report != NULL);
|
ASSERT_TRUE(report != NULL);
|
||||||
|
|
||||||
std::string der_base64;
|
std::string der_base64;
|
||||||
EXPECT_TRUE(GetValue(
|
EXPECT_TRUE(GetValue(
|
||||||
report, webrtc::StatsReport::kStatsValueNameDer, &der_base64));
|
report, StatsReport::kStatsValueNameDer, &der_base64));
|
||||||
std::string der = talk_base::Base64::Decode(der_base64,
|
std::string der = talk_base::Base64::Decode(der_base64,
|
||||||
talk_base::Base64::DO_STRICT);
|
talk_base::Base64::DO_STRICT);
|
||||||
EXPECT_EQ(ders[i], der);
|
EXPECT_EQ(ders[i], der);
|
||||||
@ -186,7 +242,7 @@ void CheckCertChainReports(const webrtc::StatsReports& reports,
|
|||||||
std::string fingerprint_algorithm;
|
std::string fingerprint_algorithm;
|
||||||
EXPECT_TRUE(GetValue(
|
EXPECT_TRUE(GetValue(
|
||||||
report,
|
report,
|
||||||
webrtc::StatsReport::kStatsValueNameFingerprintAlgorithm,
|
StatsReport::kStatsValueNameFingerprintAlgorithm,
|
||||||
&fingerprint_algorithm));
|
&fingerprint_algorithm));
|
||||||
// The digest algorithm for a FakeSSLCertificate is always SHA-1.
|
// The digest algorithm for a FakeSSLCertificate is always SHA-1.
|
||||||
std::string sha_1_str = talk_base::DIGEST_SHA_1;
|
std::string sha_1_str = talk_base::DIGEST_SHA_1;
|
||||||
@ -195,17 +251,68 @@ void CheckCertChainReports(const webrtc::StatsReports& reports,
|
|||||||
std::string dummy_fingerprint; // Value is not checked.
|
std::string dummy_fingerprint; // Value is not checked.
|
||||||
EXPECT_TRUE(GetValue(
|
EXPECT_TRUE(GetValue(
|
||||||
report,
|
report,
|
||||||
webrtc::StatsReport::kStatsValueNameFingerprint,
|
StatsReport::kStatsValueNameFingerprint,
|
||||||
&dummy_fingerprint));
|
&dummy_fingerprint));
|
||||||
|
|
||||||
++i;
|
++i;
|
||||||
if (!GetValue(
|
if (!GetValue(
|
||||||
report, webrtc::StatsReport::kStatsValueNameIssuerId, &certificate_id))
|
report, StatsReport::kStatsValueNameIssuerId, &certificate_id))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
EXPECT_EQ(ders.size(), i);
|
EXPECT_EQ(ders.size(), i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VerifyVoiceSenderInfoReport(const StatsReport* report,
|
||||||
|
const cricket::VoiceSenderInfo& sinfo) {
|
||||||
|
std::string value_in_report;
|
||||||
|
EXPECT_TRUE(GetValue(
|
||||||
|
report, StatsReport::kStatsValueNameCodecName, &value_in_report));
|
||||||
|
EXPECT_EQ(sinfo.codec_name, value_in_report);
|
||||||
|
EXPECT_TRUE(GetValue(
|
||||||
|
report, StatsReport::kStatsValueNameBytesSent, &value_in_report));
|
||||||
|
EXPECT_EQ(talk_base::ToString<int64>(sinfo.bytes_sent), value_in_report);
|
||||||
|
EXPECT_TRUE(GetValue(
|
||||||
|
report, StatsReport::kStatsValueNamePacketsSent, &value_in_report));
|
||||||
|
EXPECT_EQ(talk_base::ToString<int>(sinfo.packets_sent), value_in_report);
|
||||||
|
EXPECT_TRUE(GetValue(
|
||||||
|
report, StatsReport::kStatsValueNameRtt, &value_in_report));
|
||||||
|
EXPECT_EQ(talk_base::ToString<int>(sinfo.rtt_ms), value_in_report);
|
||||||
|
EXPECT_TRUE(GetValue(
|
||||||
|
report, StatsReport::kStatsValueNameRtt, &value_in_report));
|
||||||
|
EXPECT_EQ(talk_base::ToString<int>(sinfo.rtt_ms), value_in_report);
|
||||||
|
EXPECT_TRUE(GetValue(
|
||||||
|
report, StatsReport::kStatsValueNameJitterReceived, &value_in_report));
|
||||||
|
EXPECT_EQ(talk_base::ToString<int>(sinfo.jitter_ms), value_in_report);
|
||||||
|
EXPECT_TRUE(GetValue(
|
||||||
|
report, StatsReport::kStatsValueNameEchoCancellationQualityMin,
|
||||||
|
&value_in_report));
|
||||||
|
EXPECT_EQ(talk_base::ToString<float>(sinfo.aec_quality_min), value_in_report);
|
||||||
|
EXPECT_TRUE(GetValue(
|
||||||
|
report, StatsReport::kStatsValueNameEchoDelayMedian, &value_in_report));
|
||||||
|
EXPECT_EQ(talk_base::ToString<int>(sinfo.echo_delay_median_ms),
|
||||||
|
value_in_report);
|
||||||
|
EXPECT_TRUE(GetValue(
|
||||||
|
report, StatsReport::kStatsValueNameEchoDelayStdDev, &value_in_report));
|
||||||
|
EXPECT_EQ(talk_base::ToString<int>(sinfo.echo_delay_std_ms),
|
||||||
|
value_in_report);
|
||||||
|
EXPECT_TRUE(GetValue(
|
||||||
|
report, StatsReport::kStatsValueNameEchoReturnLoss, &value_in_report));
|
||||||
|
EXPECT_EQ(talk_base::ToString<int>(sinfo.echo_return_loss),
|
||||||
|
value_in_report);
|
||||||
|
EXPECT_TRUE(GetValue(
|
||||||
|
report, StatsReport::kStatsValueNameEchoReturnLossEnhancement,
|
||||||
|
&value_in_report));
|
||||||
|
EXPECT_EQ(talk_base::ToString<int>(sinfo.echo_return_loss_enhancement),
|
||||||
|
value_in_report);
|
||||||
|
EXPECT_TRUE(GetValue(
|
||||||
|
report, StatsReport::kStatsValueNameAudioInputLevel, &value_in_report));
|
||||||
|
EXPECT_EQ(talk_base::ToString<int>(sinfo.audio_level), value_in_report);
|
||||||
|
EXPECT_TRUE(GetValue(
|
||||||
|
report, StatsReport::kStatsValueNameTypingNoiseState, &value_in_report));
|
||||||
|
std::string typing_detected = sinfo.typing_noise_detected ? "true" : "false";
|
||||||
|
EXPECT_EQ(typing_detected, value_in_report);
|
||||||
|
}
|
||||||
|
|
||||||
class StatsCollectorTest : public testing::Test {
|
class StatsCollectorTest : public testing::Test {
|
||||||
protected:
|
protected:
|
||||||
StatsCollectorTest()
|
StatsCollectorTest()
|
||||||
@ -245,12 +352,25 @@ class StatsCollectorTest : public testing::Test {
|
|||||||
Return(true)));
|
Return(true)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Adds a local audio track with a given SSRC into the stats.
|
||||||
|
void AddLocalAudioTrackStats() {
|
||||||
|
if (stream_ == NULL)
|
||||||
|
stream_ = webrtc::MediaStream::Create("streamlabel");
|
||||||
|
|
||||||
|
audio_track_ =
|
||||||
|
new talk_base::RefCountedObject<FakeLocalAudioTrack>(kAudioTrackId);
|
||||||
|
stream_->AddTrack(audio_track_);
|
||||||
|
EXPECT_CALL(session_, GetTrackIdBySsrc(kSsrcOfTrack, _))
|
||||||
|
.WillRepeatedly(DoAll(SetArgPointee<1>(kAudioTrackId),
|
||||||
|
Return(true)));
|
||||||
|
}
|
||||||
|
|
||||||
void TestCertificateReports(const talk_base::FakeSSLCertificate& local_cert,
|
void TestCertificateReports(const talk_base::FakeSSLCertificate& local_cert,
|
||||||
const std::vector<std::string>& local_ders,
|
const std::vector<std::string>& local_ders,
|
||||||
const talk_base::FakeSSLCertificate& remote_cert,
|
const talk_base::FakeSSLCertificate& remote_cert,
|
||||||
const std::vector<std::string>& remote_ders) {
|
const std::vector<std::string>& remote_ders) {
|
||||||
webrtc::StatsCollector stats; // Implementation under test.
|
webrtc::StatsCollector stats; // Implementation under test.
|
||||||
webrtc::StatsReports reports; // returned values.
|
StatsReports reports; // returned values.
|
||||||
stats.set_session(&session_);
|
stats.set_session(&session_);
|
||||||
|
|
||||||
// Fake stats to process.
|
// Fake stats to process.
|
||||||
@ -289,22 +409,22 @@ class StatsCollectorTest : public testing::Test {
|
|||||||
EXPECT_CALL(session_, GetStats(_))
|
EXPECT_CALL(session_, GetStats(_))
|
||||||
.WillOnce(DoAll(SetArgPointee<0>(session_stats),
|
.WillOnce(DoAll(SetArgPointee<0>(session_stats),
|
||||||
Return(true)));
|
Return(true)));
|
||||||
EXPECT_CALL(session_, video_channel())
|
EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
|
||||||
.WillRepeatedly(ReturnNull());
|
EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
|
||||||
|
|
||||||
stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
|
stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
|
||||||
|
|
||||||
stats.GetStats(NULL, &reports);
|
stats.GetStats(NULL, &reports);
|
||||||
|
|
||||||
const webrtc::StatsReport* channel_report = FindNthReportByType(
|
const StatsReport* channel_report = FindNthReportByType(
|
||||||
reports, webrtc::StatsReport::kStatsReportTypeComponent, 1);
|
reports, StatsReport::kStatsReportTypeComponent, 1);
|
||||||
EXPECT_TRUE(channel_report != NULL);
|
EXPECT_TRUE(channel_report != NULL);
|
||||||
|
|
||||||
// Check local certificate chain.
|
// Check local certificate chain.
|
||||||
std::string local_certificate_id = ExtractStatsValue(
|
std::string local_certificate_id = ExtractStatsValue(
|
||||||
webrtc::StatsReport::kStatsReportTypeComponent,
|
StatsReport::kStatsReportTypeComponent,
|
||||||
reports,
|
reports,
|
||||||
webrtc::StatsReport::kStatsValueNameLocalCertificateId);
|
StatsReport::kStatsValueNameLocalCertificateId);
|
||||||
if (local_ders.size() > 0) {
|
if (local_ders.size() > 0) {
|
||||||
EXPECT_NE(kNotFound, local_certificate_id);
|
EXPECT_NE(kNotFound, local_certificate_id);
|
||||||
CheckCertChainReports(reports, local_ders, local_certificate_id);
|
CheckCertChainReports(reports, local_ders, local_certificate_id);
|
||||||
@ -314,9 +434,9 @@ class StatsCollectorTest : public testing::Test {
|
|||||||
|
|
||||||
// Check remote certificate chain.
|
// Check remote certificate chain.
|
||||||
std::string remote_certificate_id = ExtractStatsValue(
|
std::string remote_certificate_id = ExtractStatsValue(
|
||||||
webrtc::StatsReport::kStatsReportTypeComponent,
|
StatsReport::kStatsReportTypeComponent,
|
||||||
reports,
|
reports,
|
||||||
webrtc::StatsReport::kStatsValueNameRemoteCertificateId);
|
StatsReport::kStatsValueNameRemoteCertificateId);
|
||||||
if (remote_ders.size() > 0) {
|
if (remote_ders.size() > 0) {
|
||||||
EXPECT_NE(kNotFound, remote_certificate_id);
|
EXPECT_NE(kNotFound, remote_certificate_id);
|
||||||
CheckCertChainReports(reports, remote_ders, remote_certificate_id);
|
CheckCertChainReports(reports, remote_ders, remote_certificate_id);
|
||||||
@ -331,6 +451,7 @@ class StatsCollectorTest : public testing::Test {
|
|||||||
cricket::SessionStats session_stats_;
|
cricket::SessionStats session_stats_;
|
||||||
talk_base::scoped_refptr<webrtc::MediaStream> stream_;
|
talk_base::scoped_refptr<webrtc::MediaStream> stream_;
|
||||||
talk_base::scoped_refptr<webrtc::VideoTrack> track_;
|
talk_base::scoped_refptr<webrtc::VideoTrack> track_;
|
||||||
|
talk_base::scoped_refptr<FakeLocalAudioTrack> audio_track_;
|
||||||
std::string track_id_;
|
std::string track_id_;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -340,7 +461,7 @@ TEST_F(StatsCollectorTest, BytesCounterHandles64Bits) {
|
|||||||
MockVideoMediaChannel* media_channel = new MockVideoMediaChannel;
|
MockVideoMediaChannel* media_channel = new MockVideoMediaChannel;
|
||||||
cricket::VideoChannel video_channel(talk_base::Thread::Current(),
|
cricket::VideoChannel video_channel(talk_base::Thread::Current(),
|
||||||
media_engine_, media_channel, &session_, "", false, NULL);
|
media_engine_, media_channel, &session_, "", false, NULL);
|
||||||
webrtc::StatsReports reports; // returned values.
|
StatsReports reports; // returned values.
|
||||||
cricket::VideoSenderInfo video_sender_info;
|
cricket::VideoSenderInfo video_sender_info;
|
||||||
cricket::VideoMediaInfo stats_read;
|
cricket::VideoMediaInfo stats_read;
|
||||||
// The number of bytes must be larger than 0xFFFFFFFF for this test.
|
// The number of bytes must be larger than 0xFFFFFFFF for this test.
|
||||||
@ -356,8 +477,8 @@ TEST_F(StatsCollectorTest, BytesCounterHandles64Bits) {
|
|||||||
video_sender_info.bytes_sent = kBytesSent;
|
video_sender_info.bytes_sent = kBytesSent;
|
||||||
stats_read.senders.push_back(video_sender_info);
|
stats_read.senders.push_back(video_sender_info);
|
||||||
|
|
||||||
EXPECT_CALL(session_, video_channel())
|
EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
|
||||||
.WillRepeatedly(Return(&video_channel));
|
EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
|
||||||
EXPECT_CALL(*media_channel, GetStats(_, _))
|
EXPECT_CALL(*media_channel, GetStats(_, _))
|
||||||
.WillOnce(DoAll(SetArgPointee<1>(stats_read),
|
.WillOnce(DoAll(SetArgPointee<1>(stats_read),
|
||||||
Return(true)));
|
Return(true)));
|
||||||
@ -373,7 +494,7 @@ TEST_F(StatsCollectorTest, BandwidthEstimationInfoIsReported) {
|
|||||||
MockVideoMediaChannel* media_channel = new MockVideoMediaChannel;
|
MockVideoMediaChannel* media_channel = new MockVideoMediaChannel;
|
||||||
cricket::VideoChannel video_channel(talk_base::Thread::Current(),
|
cricket::VideoChannel video_channel(talk_base::Thread::Current(),
|
||||||
media_engine_, media_channel, &session_, "", false, NULL);
|
media_engine_, media_channel, &session_, "", false, NULL);
|
||||||
webrtc::StatsReports reports; // returned values.
|
StatsReports reports; // returned values.
|
||||||
cricket::VideoSenderInfo video_sender_info;
|
cricket::VideoSenderInfo video_sender_info;
|
||||||
cricket::VideoMediaInfo stats_read;
|
cricket::VideoMediaInfo stats_read;
|
||||||
// Set up an SSRC just to test that we get both kinds of stats back: SSRC and
|
// Set up an SSRC just to test that we get both kinds of stats back: SSRC and
|
||||||
@ -395,8 +516,8 @@ TEST_F(StatsCollectorTest, BandwidthEstimationInfoIsReported) {
|
|||||||
bwe.target_enc_bitrate = kTargetEncBitrate;
|
bwe.target_enc_bitrate = kTargetEncBitrate;
|
||||||
stats_read.bw_estimations.push_back(bwe);
|
stats_read.bw_estimations.push_back(bwe);
|
||||||
|
|
||||||
EXPECT_CALL(session_, video_channel())
|
EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
|
||||||
.WillRepeatedly(Return(&video_channel));
|
EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
|
||||||
EXPECT_CALL(*media_channel, GetStats(_, _))
|
EXPECT_CALL(*media_channel, GetStats(_, _))
|
||||||
.WillOnce(DoAll(SetArgPointee<1>(stats_read),
|
.WillOnce(DoAll(SetArgPointee<1>(stats_read),
|
||||||
Return(true)));
|
Return(true)));
|
||||||
@ -413,14 +534,14 @@ TEST_F(StatsCollectorTest, BandwidthEstimationInfoIsReported) {
|
|||||||
// exists in the returned stats.
|
// exists in the returned stats.
|
||||||
TEST_F(StatsCollectorTest, SessionObjectExists) {
|
TEST_F(StatsCollectorTest, SessionObjectExists) {
|
||||||
webrtc::StatsCollector stats; // Implementation under test.
|
webrtc::StatsCollector stats; // Implementation under test.
|
||||||
webrtc::StatsReports reports; // returned values.
|
StatsReports reports; // returned values.
|
||||||
stats.set_session(&session_);
|
stats.set_session(&session_);
|
||||||
EXPECT_CALL(session_, video_channel())
|
EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
|
||||||
.WillRepeatedly(ReturnNull());
|
EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
|
||||||
stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
|
stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
|
||||||
stats.GetStats(NULL, &reports);
|
stats.GetStats(NULL, &reports);
|
||||||
const webrtc::StatsReport* session_report = FindNthReportByType(
|
const StatsReport* session_report = FindNthReportByType(
|
||||||
reports, webrtc::StatsReport::kStatsReportTypeSession, 1);
|
reports, StatsReport::kStatsReportTypeSession, 1);
|
||||||
EXPECT_FALSE(session_report == NULL);
|
EXPECT_FALSE(session_report == NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -428,18 +549,18 @@ TEST_F(StatsCollectorTest, SessionObjectExists) {
|
|||||||
// in the returned stats.
|
// in the returned stats.
|
||||||
TEST_F(StatsCollectorTest, OnlyOneSessionObjectExists) {
|
TEST_F(StatsCollectorTest, OnlyOneSessionObjectExists) {
|
||||||
webrtc::StatsCollector stats; // Implementation under test.
|
webrtc::StatsCollector stats; // Implementation under test.
|
||||||
webrtc::StatsReports reports; // returned values.
|
StatsReports reports; // returned values.
|
||||||
stats.set_session(&session_);
|
stats.set_session(&session_);
|
||||||
EXPECT_CALL(session_, video_channel())
|
EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
|
||||||
.WillRepeatedly(ReturnNull());
|
EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
|
||||||
stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
|
stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
|
||||||
stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
|
stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
|
||||||
stats.GetStats(NULL, &reports);
|
stats.GetStats(NULL, &reports);
|
||||||
const webrtc::StatsReport* session_report = FindNthReportByType(
|
const StatsReport* session_report = FindNthReportByType(
|
||||||
reports, webrtc::StatsReport::kStatsReportTypeSession, 1);
|
reports, StatsReport::kStatsReportTypeSession, 1);
|
||||||
EXPECT_FALSE(session_report == NULL);
|
EXPECT_FALSE(session_report == NULL);
|
||||||
session_report = FindNthReportByType(
|
session_report = FindNthReportByType(
|
||||||
reports, webrtc::StatsReport::kStatsReportTypeSession, 2);
|
reports, StatsReport::kStatsReportTypeSession, 2);
|
||||||
EXPECT_EQ(NULL, session_report);
|
EXPECT_EQ(NULL, session_report);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -455,18 +576,18 @@ TEST_F(StatsCollectorTest, TrackObjectExistsWithoutUpdateStats) {
|
|||||||
|
|
||||||
stats.set_session(&session_);
|
stats.set_session(&session_);
|
||||||
|
|
||||||
webrtc::StatsReports reports;
|
StatsReports reports;
|
||||||
|
|
||||||
// Verfies the existence of the track report.
|
// Verfies the existence of the track report.
|
||||||
stats.GetStats(NULL, &reports);
|
stats.GetStats(NULL, &reports);
|
||||||
EXPECT_EQ((size_t)1, reports.size());
|
EXPECT_EQ((size_t)1, reports.size());
|
||||||
EXPECT_EQ(std::string(webrtc::StatsReport::kStatsReportTypeTrack),
|
EXPECT_EQ(std::string(StatsReport::kStatsReportTypeTrack),
|
||||||
reports[0].type);
|
reports[0].type);
|
||||||
|
|
||||||
std::string trackValue =
|
std::string trackValue =
|
||||||
ExtractStatsValue(webrtc::StatsReport::kStatsReportTypeTrack,
|
ExtractStatsValue(StatsReport::kStatsReportTypeTrack,
|
||||||
reports,
|
reports,
|
||||||
webrtc::StatsReport::kStatsValueNameTrackId);
|
StatsReport::kStatsValueNameTrackId);
|
||||||
EXPECT_EQ(kTrackId, trackValue);
|
EXPECT_EQ(kTrackId, trackValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -482,7 +603,7 @@ TEST_F(StatsCollectorTest, TrackAndSsrcObjectExistAfterUpdateSsrcStats) {
|
|||||||
|
|
||||||
stats.set_session(&session_);
|
stats.set_session(&session_);
|
||||||
|
|
||||||
webrtc::StatsReports reports;
|
StatsReports reports;
|
||||||
|
|
||||||
// Constructs an ssrc stats update.
|
// Constructs an ssrc stats update.
|
||||||
cricket::VideoSenderInfo video_sender_info;
|
cricket::VideoSenderInfo video_sender_info;
|
||||||
@ -494,8 +615,8 @@ TEST_F(StatsCollectorTest, TrackAndSsrcObjectExistAfterUpdateSsrcStats) {
|
|||||||
video_sender_info.bytes_sent = kBytesSent;
|
video_sender_info.bytes_sent = kBytesSent;
|
||||||
stats_read.senders.push_back(video_sender_info);
|
stats_read.senders.push_back(video_sender_info);
|
||||||
|
|
||||||
EXPECT_CALL(session_, video_channel())
|
EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
|
||||||
.WillRepeatedly(Return(&video_channel));
|
EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
|
||||||
EXPECT_CALL(*media_channel, GetStats(_, _))
|
EXPECT_CALL(*media_channel, GetStats(_, _))
|
||||||
.WillOnce(DoAll(SetArgPointee<1>(stats_read),
|
.WillOnce(DoAll(SetArgPointee<1>(stats_read),
|
||||||
Return(true)));
|
Return(true)));
|
||||||
@ -505,8 +626,8 @@ TEST_F(StatsCollectorTest, TrackAndSsrcObjectExistAfterUpdateSsrcStats) {
|
|||||||
// |reports| should contain at least one session report, one track report,
|
// |reports| should contain at least one session report, one track report,
|
||||||
// and one ssrc report.
|
// and one ssrc report.
|
||||||
EXPECT_LE((size_t)3, reports.size());
|
EXPECT_LE((size_t)3, reports.size());
|
||||||
const webrtc::StatsReport* track_report = FindNthReportByType(
|
const StatsReport* track_report = FindNthReportByType(
|
||||||
reports, webrtc::StatsReport::kStatsReportTypeTrack, 1);
|
reports, StatsReport::kStatsReportTypeTrack, 1);
|
||||||
EXPECT_FALSE(track_report == NULL);
|
EXPECT_FALSE(track_report == NULL);
|
||||||
|
|
||||||
stats.GetStats(track_, &reports);
|
stats.GetStats(track_, &reports);
|
||||||
@ -514,15 +635,15 @@ TEST_F(StatsCollectorTest, TrackAndSsrcObjectExistAfterUpdateSsrcStats) {
|
|||||||
// and one ssrc report.
|
// and one ssrc report.
|
||||||
EXPECT_LE((size_t)3, reports.size());
|
EXPECT_LE((size_t)3, reports.size());
|
||||||
track_report = FindNthReportByType(
|
track_report = FindNthReportByType(
|
||||||
reports, webrtc::StatsReport::kStatsReportTypeTrack, 1);
|
reports, StatsReport::kStatsReportTypeTrack, 1);
|
||||||
EXPECT_FALSE(track_report == NULL);
|
EXPECT_FALSE(track_report == NULL);
|
||||||
|
|
||||||
std::string ssrc_id = ExtractSsrcStatsValue(
|
std::string ssrc_id = ExtractSsrcStatsValue(
|
||||||
reports, webrtc::StatsReport::kStatsValueNameSsrc);
|
reports, StatsReport::kStatsValueNameSsrc);
|
||||||
EXPECT_EQ(talk_base::ToString<uint32>(kSsrcOfTrack), ssrc_id);
|
EXPECT_EQ(talk_base::ToString<uint32>(kSsrcOfTrack), ssrc_id);
|
||||||
|
|
||||||
std::string track_id = ExtractSsrcStatsValue(
|
std::string track_id = ExtractSsrcStatsValue(
|
||||||
reports, webrtc::StatsReport::kStatsValueNameTrackId);
|
reports, StatsReport::kStatsValueNameTrackId);
|
||||||
EXPECT_EQ(kTrackId, track_id);
|
EXPECT_EQ(kTrackId, track_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -540,7 +661,7 @@ TEST_F(StatsCollectorTest, TransportObjectLinkedFromSsrcObject) {
|
|||||||
|
|
||||||
stats.set_session(&session_);
|
stats.set_session(&session_);
|
||||||
|
|
||||||
webrtc::StatsReports reports;
|
StatsReports reports;
|
||||||
|
|
||||||
// Constructs an ssrc stats update.
|
// Constructs an ssrc stats update.
|
||||||
cricket::VideoSenderInfo video_sender_info;
|
cricket::VideoSenderInfo video_sender_info;
|
||||||
@ -552,26 +673,26 @@ TEST_F(StatsCollectorTest, TransportObjectLinkedFromSsrcObject) {
|
|||||||
video_sender_info.bytes_sent = kBytesSent;
|
video_sender_info.bytes_sent = kBytesSent;
|
||||||
stats_read.senders.push_back(video_sender_info);
|
stats_read.senders.push_back(video_sender_info);
|
||||||
|
|
||||||
EXPECT_CALL(session_, video_channel())
|
EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
|
||||||
.WillRepeatedly(Return(&video_channel));
|
EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
|
||||||
EXPECT_CALL(*media_channel, GetStats(_, _))
|
EXPECT_CALL(*media_channel, GetStats(_, _))
|
||||||
.WillRepeatedly(DoAll(SetArgPointee<1>(stats_read),
|
.WillRepeatedly(DoAll(SetArgPointee<1>(stats_read),
|
||||||
Return(true)));
|
Return(true)));
|
||||||
|
|
||||||
InitSessionStats(kVcName);
|
InitSessionStats(kVcName);
|
||||||
EXPECT_CALL(session_, GetStats(_))
|
EXPECT_CALL(session_, GetStats(_))
|
||||||
.WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
|
.WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
|
||||||
Return(true)));
|
Return(true)));
|
||||||
|
|
||||||
stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
|
stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
|
||||||
stats.GetStats(NULL, &reports);
|
stats.GetStats(NULL, &reports);
|
||||||
std::string transport_id = ExtractStatsValue(
|
std::string transport_id = ExtractStatsValue(
|
||||||
webrtc::StatsReport::kStatsReportTypeSsrc,
|
StatsReport::kStatsReportTypeSsrc,
|
||||||
reports,
|
reports,
|
||||||
webrtc::StatsReport::kStatsValueNameTransportId);
|
StatsReport::kStatsValueNameTransportId);
|
||||||
ASSERT_NE(kNotFound, transport_id);
|
ASSERT_NE(kNotFound, transport_id);
|
||||||
const webrtc::StatsReport* transport_report = FindReportById(reports,
|
const StatsReport* transport_report = FindReportById(reports,
|
||||||
transport_id);
|
transport_id);
|
||||||
ASSERT_FALSE(transport_report == NULL);
|
ASSERT_FALSE(transport_report == NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -589,14 +710,14 @@ TEST_F(StatsCollectorTest, RemoteSsrcInfoIsAbsent) {
|
|||||||
|
|
||||||
stats.set_session(&session_);
|
stats.set_session(&session_);
|
||||||
|
|
||||||
EXPECT_CALL(session_, video_channel())
|
EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
|
||||||
.WillRepeatedly(ReturnNull());
|
EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
|
||||||
|
|
||||||
stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
|
stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
|
||||||
webrtc::StatsReports reports;
|
StatsReports reports;
|
||||||
stats.GetStats(NULL, &reports);
|
stats.GetStats(NULL, &reports);
|
||||||
const webrtc::StatsReport* remote_report = FindNthReportByType(reports,
|
const StatsReport* remote_report = FindNthReportByType(reports,
|
||||||
webrtc::StatsReport::kStatsReportTypeRemoteSsrc, 1);
|
StatsReport::kStatsReportTypeRemoteSsrc, 1);
|
||||||
EXPECT_TRUE(remote_report == NULL);
|
EXPECT_TRUE(remote_report == NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -614,13 +735,13 @@ TEST_F(StatsCollectorTest, RemoteSsrcInfoIsPresent) {
|
|||||||
|
|
||||||
stats.set_session(&session_);
|
stats.set_session(&session_);
|
||||||
|
|
||||||
webrtc::StatsReports reports;
|
StatsReports reports;
|
||||||
|
|
||||||
// Instruct the session to return stats containing the transport channel.
|
// Instruct the session to return stats containing the transport channel.
|
||||||
InitSessionStats(kVcName);
|
InitSessionStats(kVcName);
|
||||||
EXPECT_CALL(session_, GetStats(_))
|
EXPECT_CALL(session_, GetStats(_))
|
||||||
.WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
|
.WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
|
||||||
Return(true)));
|
Return(true)));
|
||||||
|
|
||||||
// Constructs an ssrc stats update.
|
// Constructs an ssrc stats update.
|
||||||
cricket::VideoMediaInfo stats_read;
|
cricket::VideoMediaInfo stats_read;
|
||||||
@ -633,16 +754,16 @@ TEST_F(StatsCollectorTest, RemoteSsrcInfoIsPresent) {
|
|||||||
video_sender_info.remote_stats.push_back(remote_ssrc_stats);
|
video_sender_info.remote_stats.push_back(remote_ssrc_stats);
|
||||||
stats_read.senders.push_back(video_sender_info);
|
stats_read.senders.push_back(video_sender_info);
|
||||||
|
|
||||||
EXPECT_CALL(session_, video_channel())
|
EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
|
||||||
.WillRepeatedly(Return(&video_channel));
|
EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
|
||||||
EXPECT_CALL(*media_channel, GetStats(_, _))
|
EXPECT_CALL(*media_channel, GetStats(_, _))
|
||||||
.WillRepeatedly(DoAll(SetArgPointee<1>(stats_read),
|
.WillRepeatedly(DoAll(SetArgPointee<1>(stats_read),
|
||||||
Return(true)));
|
Return(true)));
|
||||||
|
|
||||||
stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
|
stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
|
||||||
stats.GetStats(NULL, &reports);
|
stats.GetStats(NULL, &reports);
|
||||||
const webrtc::StatsReport* remote_report = FindNthReportByType(reports,
|
const StatsReport* remote_report = FindNthReportByType(reports,
|
||||||
webrtc::StatsReport::kStatsReportTypeRemoteSsrc, 1);
|
StatsReport::kStatsReportTypeRemoteSsrc, 1);
|
||||||
EXPECT_FALSE(remote_report == NULL);
|
EXPECT_FALSE(remote_report == NULL);
|
||||||
EXPECT_NE(0, remote_report->timestamp);
|
EXPECT_NE(0, remote_report->timestamp);
|
||||||
}
|
}
|
||||||
@ -689,7 +810,7 @@ TEST_F(StatsCollectorTest, ChainlessCertificateReportsCreated) {
|
|||||||
// transport is present.
|
// transport is present.
|
||||||
TEST_F(StatsCollectorTest, NoTransport) {
|
TEST_F(StatsCollectorTest, NoTransport) {
|
||||||
webrtc::StatsCollector stats; // Implementation under test.
|
webrtc::StatsCollector stats; // Implementation under test.
|
||||||
webrtc::StatsReports reports; // returned values.
|
StatsReports reports; // returned values.
|
||||||
stats.set_session(&session_);
|
stats.set_session(&session_);
|
||||||
|
|
||||||
// Fake stats to process.
|
// Fake stats to process.
|
||||||
@ -711,24 +832,24 @@ TEST_F(StatsCollectorTest, NoTransport) {
|
|||||||
.WillOnce(DoAll(SetArgPointee<0>(session_stats),
|
.WillOnce(DoAll(SetArgPointee<0>(session_stats),
|
||||||
Return(true)));
|
Return(true)));
|
||||||
|
|
||||||
EXPECT_CALL(session_, video_channel())
|
EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
|
||||||
.WillRepeatedly(ReturnNull());
|
EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
|
||||||
|
|
||||||
stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
|
stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
|
||||||
stats.GetStats(NULL, &reports);
|
stats.GetStats(NULL, &reports);
|
||||||
|
|
||||||
// Check that the local certificate is absent.
|
// Check that the local certificate is absent.
|
||||||
std::string local_certificate_id = ExtractStatsValue(
|
std::string local_certificate_id = ExtractStatsValue(
|
||||||
webrtc::StatsReport::kStatsReportTypeComponent,
|
StatsReport::kStatsReportTypeComponent,
|
||||||
reports,
|
reports,
|
||||||
webrtc::StatsReport::kStatsValueNameLocalCertificateId);
|
StatsReport::kStatsValueNameLocalCertificateId);
|
||||||
ASSERT_EQ(kNotFound, local_certificate_id);
|
ASSERT_EQ(kNotFound, local_certificate_id);
|
||||||
|
|
||||||
// Check that the remote certificate is absent.
|
// Check that the remote certificate is absent.
|
||||||
std::string remote_certificate_id = ExtractStatsValue(
|
std::string remote_certificate_id = ExtractStatsValue(
|
||||||
webrtc::StatsReport::kStatsReportTypeComponent,
|
StatsReport::kStatsReportTypeComponent,
|
||||||
reports,
|
reports,
|
||||||
webrtc::StatsReport::kStatsValueNameRemoteCertificateId);
|
StatsReport::kStatsValueNameRemoteCertificateId);
|
||||||
ASSERT_EQ(kNotFound, remote_certificate_id);
|
ASSERT_EQ(kNotFound, remote_certificate_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -736,7 +857,7 @@ TEST_F(StatsCollectorTest, NoTransport) {
|
|||||||
// does not have any certificates.
|
// does not have any certificates.
|
||||||
TEST_F(StatsCollectorTest, NoCertificates) {
|
TEST_F(StatsCollectorTest, NoCertificates) {
|
||||||
webrtc::StatsCollector stats; // Implementation under test.
|
webrtc::StatsCollector stats; // Implementation under test.
|
||||||
webrtc::StatsReports reports; // returned values.
|
StatsReports reports; // returned values.
|
||||||
stats.set_session(&session_);
|
stats.set_session(&session_);
|
||||||
|
|
||||||
// Fake stats to process.
|
// Fake stats to process.
|
||||||
@ -764,24 +885,24 @@ TEST_F(StatsCollectorTest, NoCertificates) {
|
|||||||
EXPECT_CALL(session_, GetStats(_))
|
EXPECT_CALL(session_, GetStats(_))
|
||||||
.WillOnce(DoAll(SetArgPointee<0>(session_stats),
|
.WillOnce(DoAll(SetArgPointee<0>(session_stats),
|
||||||
Return(true)));
|
Return(true)));
|
||||||
EXPECT_CALL(session_, video_channel())
|
EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
|
||||||
.WillRepeatedly(ReturnNull());
|
EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
|
||||||
|
|
||||||
stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
|
stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
|
||||||
stats.GetStats(NULL, &reports);
|
stats.GetStats(NULL, &reports);
|
||||||
|
|
||||||
// Check that the local certificate is absent.
|
// Check that the local certificate is absent.
|
||||||
std::string local_certificate_id = ExtractStatsValue(
|
std::string local_certificate_id = ExtractStatsValue(
|
||||||
webrtc::StatsReport::kStatsReportTypeComponent,
|
StatsReport::kStatsReportTypeComponent,
|
||||||
reports,
|
reports,
|
||||||
webrtc::StatsReport::kStatsValueNameLocalCertificateId);
|
StatsReport::kStatsValueNameLocalCertificateId);
|
||||||
ASSERT_EQ(kNotFound, local_certificate_id);
|
ASSERT_EQ(kNotFound, local_certificate_id);
|
||||||
|
|
||||||
// Check that the remote certificate is absent.
|
// Check that the remote certificate is absent.
|
||||||
std::string remote_certificate_id = ExtractStatsValue(
|
std::string remote_certificate_id = ExtractStatsValue(
|
||||||
webrtc::StatsReport::kStatsReportTypeComponent,
|
StatsReport::kStatsReportTypeComponent,
|
||||||
reports,
|
reports,
|
||||||
webrtc::StatsReport::kStatsValueNameRemoteCertificateId);
|
StatsReport::kStatsValueNameRemoteCertificateId);
|
||||||
ASSERT_EQ(kNotFound, remote_certificate_id);
|
ASSERT_EQ(kNotFound, remote_certificate_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -810,7 +931,7 @@ TEST_F(StatsCollectorTest, StatsOutputLevelVerbose) {
|
|||||||
media_engine_, media_channel, &session_, "", false, NULL);
|
media_engine_, media_channel, &session_, "", false, NULL);
|
||||||
stats.set_session(&session_);
|
stats.set_session(&session_);
|
||||||
|
|
||||||
webrtc::StatsReports reports; // returned values.
|
StatsReports reports; // returned values.
|
||||||
cricket::VideoMediaInfo stats_read;
|
cricket::VideoMediaInfo stats_read;
|
||||||
cricket::BandwidthEstimationInfo bwe;
|
cricket::BandwidthEstimationInfo bwe;
|
||||||
bwe.total_received_propagation_delta_ms = 10;
|
bwe.total_received_propagation_delta_ms = 10;
|
||||||
@ -822,6 +943,7 @@ TEST_F(StatsCollectorTest, StatsOutputLevelVerbose) {
|
|||||||
|
|
||||||
EXPECT_CALL(session_, video_channel())
|
EXPECT_CALL(session_, video_channel())
|
||||||
.WillRepeatedly(Return(&video_channel));
|
.WillRepeatedly(Return(&video_channel));
|
||||||
|
EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
|
||||||
|
|
||||||
StatsOptions options;
|
StatsOptions options;
|
||||||
options.include_received_propagation_stats = true;
|
options.include_received_propagation_stats = true;
|
||||||
@ -844,4 +966,175 @@ TEST_F(StatsCollectorTest, StatsOutputLevelVerbose) {
|
|||||||
EXPECT_EQ("[1000, 2000]", result);
|
EXPECT_EQ("[1000, 2000]", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This test verifies that a local stats object can get statistics via
|
||||||
|
// AudioTrackInterface::GetStats() method.
|
||||||
|
TEST_F(StatsCollectorTest, GetStatsFromLocalAudioTrack) {
|
||||||
|
webrtc::StatsCollector stats; // Implementation under test.
|
||||||
|
MockVoiceMediaChannel* media_channel = new MockVoiceMediaChannel();
|
||||||
|
// The content_name known by the voice channel.
|
||||||
|
const std::string kVcName("vcname");
|
||||||
|
cricket::VoiceChannel voice_channel(talk_base::Thread::Current(),
|
||||||
|
media_engine_, media_channel, &session_, kVcName, false);
|
||||||
|
AddLocalAudioTrackStats();
|
||||||
|
stats.AddStream(stream_);
|
||||||
|
stats.AddLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
|
||||||
|
|
||||||
|
stats.set_session(&session_);
|
||||||
|
|
||||||
|
// Instruct the session to return stats containing the transport channel.
|
||||||
|
InitSessionStats(kVcName);
|
||||||
|
EXPECT_CALL(session_, GetStats(_))
|
||||||
|
.WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
|
||||||
|
Return(true)));
|
||||||
|
|
||||||
|
cricket::VoiceSenderInfo voice_sender_info;
|
||||||
|
// Contents won't be modified by the AudioTrackInterface::GetStats().
|
||||||
|
voice_sender_info.add_ssrc(kSsrcOfTrack);
|
||||||
|
voice_sender_info.codec_name = "fake_codec";
|
||||||
|
voice_sender_info.bytes_sent = 100;
|
||||||
|
voice_sender_info.packets_sent = 101;
|
||||||
|
voice_sender_info.rtt_ms = 102;
|
||||||
|
voice_sender_info.fraction_lost = 103;
|
||||||
|
voice_sender_info.jitter_ms = 104;
|
||||||
|
voice_sender_info.packets_lost = 105;
|
||||||
|
voice_sender_info.ext_seqnum = 106;
|
||||||
|
|
||||||
|
// Contents will be modified by the AudioTrackInterface::GetStats().
|
||||||
|
voice_sender_info.audio_level = 107;
|
||||||
|
voice_sender_info.echo_return_loss = 108;;
|
||||||
|
voice_sender_info.echo_return_loss_enhancement = 109;
|
||||||
|
voice_sender_info.echo_delay_median_ms = 110;
|
||||||
|
voice_sender_info.echo_delay_std_ms = 111;
|
||||||
|
voice_sender_info.aec_quality_min = 112.0f;
|
||||||
|
voice_sender_info.typing_noise_detected = false;
|
||||||
|
|
||||||
|
// Constructs an ssrc stats update.
|
||||||
|
cricket::VoiceMediaInfo stats_read;
|
||||||
|
stats_read.senders.push_back(voice_sender_info);
|
||||||
|
|
||||||
|
EXPECT_CALL(session_, voice_channel()).WillRepeatedly(Return(&voice_channel));
|
||||||
|
EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
|
||||||
|
EXPECT_CALL(*media_channel, GetStats(_))
|
||||||
|
.WillRepeatedly(DoAll(SetArgPointee<0>(stats_read),
|
||||||
|
Return(true)));
|
||||||
|
|
||||||
|
StatsReports reports; // returned values.
|
||||||
|
stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
|
||||||
|
stats.GetStats(NULL, &reports);
|
||||||
|
|
||||||
|
// Verfy the existence of the track report.
|
||||||
|
const StatsReport* report = FindNthReportByType(
|
||||||
|
reports, StatsReport::kStatsReportTypeSsrc, 1);
|
||||||
|
EXPECT_FALSE(report == NULL);
|
||||||
|
std::string track_id = ExtractSsrcStatsValue(
|
||||||
|
reports, StatsReport::kStatsValueNameTrackId);
|
||||||
|
EXPECT_EQ(kAudioTrackId, track_id);
|
||||||
|
std::string ssrc_id = ExtractSsrcStatsValue(
|
||||||
|
reports, StatsReport::kStatsValueNameSsrc);
|
||||||
|
EXPECT_EQ(talk_base::ToString<uint32>(kSsrcOfTrack), ssrc_id);
|
||||||
|
|
||||||
|
// Verifies the values in the track report.
|
||||||
|
audio_track_->GetSignalLevel(&voice_sender_info.audio_level);
|
||||||
|
webrtc::AudioProcessorInterface::AudioProcessorStats audio_processor_stats;
|
||||||
|
audio_track_->GetAudioProcessor()->GetStats(&audio_processor_stats);
|
||||||
|
voice_sender_info.typing_noise_detected =
|
||||||
|
audio_processor_stats.typing_noise_detected;
|
||||||
|
voice_sender_info.echo_return_loss = audio_processor_stats.echo_return_loss;
|
||||||
|
voice_sender_info.echo_return_loss_enhancement =
|
||||||
|
audio_processor_stats.echo_return_loss_enhancement;
|
||||||
|
voice_sender_info.echo_delay_median_ms =
|
||||||
|
audio_processor_stats.echo_delay_median_ms;
|
||||||
|
voice_sender_info.aec_quality_min = audio_processor_stats.aec_quality_min;
|
||||||
|
voice_sender_info.echo_delay_std_ms = audio_processor_stats.echo_delay_std_ms;
|
||||||
|
VerifyVoiceSenderInfoReport(report, voice_sender_info);
|
||||||
|
|
||||||
|
// Verify we get the same result by passing a track to GetStats().
|
||||||
|
StatsReports track_reports; // returned values.
|
||||||
|
stats.GetStats(audio_track_.get(), &track_reports);
|
||||||
|
const StatsReport* track_report = FindNthReportByType(
|
||||||
|
track_reports, StatsReport::kStatsReportTypeSsrc, 1);
|
||||||
|
EXPECT_FALSE(track_report == NULL);
|
||||||
|
track_id = ExtractSsrcStatsValue(track_reports,
|
||||||
|
StatsReport::kStatsValueNameTrackId);
|
||||||
|
EXPECT_EQ(kAudioTrackId, track_id);
|
||||||
|
ssrc_id = ExtractSsrcStatsValue(track_reports,
|
||||||
|
StatsReport::kStatsValueNameSsrc);
|
||||||
|
EXPECT_EQ(talk_base::ToString<uint32>(kSsrcOfTrack), ssrc_id);
|
||||||
|
VerifyVoiceSenderInfoReport(track_report, voice_sender_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This test verifies that a local stats object won't update its statistics
|
||||||
|
// after a RemoveLocalAudioTrack() call.
|
||||||
|
TEST_F(StatsCollectorTest, GetStatsAfterRemoveAudioStream) {
|
||||||
|
webrtc::StatsCollector stats; // Implementation under test.
|
||||||
|
MockVoiceMediaChannel* media_channel = new MockVoiceMediaChannel();
|
||||||
|
// The content_name known by the voice channel.
|
||||||
|
const std::string kVcName("vcname");
|
||||||
|
cricket::VoiceChannel voice_channel(talk_base::Thread::Current(),
|
||||||
|
media_engine_, media_channel, &session_, kVcName, false);
|
||||||
|
AddLocalAudioTrackStats();
|
||||||
|
stats.AddStream(stream_);
|
||||||
|
stats.AddLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
|
||||||
|
|
||||||
|
stats.set_session(&session_);
|
||||||
|
|
||||||
|
// Instruct the session to return stats containing the transport channel.
|
||||||
|
InitSessionStats(kVcName);
|
||||||
|
EXPECT_CALL(session_, GetStats(_))
|
||||||
|
.WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
|
||||||
|
Return(true)));
|
||||||
|
|
||||||
|
stats.RemoveLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
|
||||||
|
cricket::VoiceSenderInfo voice_sender_info;
|
||||||
|
// Contents won't be modified by the AudioTrackInterface::GetStats().
|
||||||
|
voice_sender_info.add_ssrc(kSsrcOfTrack);
|
||||||
|
voice_sender_info.codec_name = "fake_codec";
|
||||||
|
voice_sender_info.bytes_sent = 100;
|
||||||
|
voice_sender_info.packets_sent = 101;
|
||||||
|
voice_sender_info.rtt_ms = 102;
|
||||||
|
voice_sender_info.fraction_lost = 103;
|
||||||
|
voice_sender_info.jitter_ms = 104;
|
||||||
|
voice_sender_info.packets_lost = 105;
|
||||||
|
voice_sender_info.ext_seqnum = 106;
|
||||||
|
|
||||||
|
// Contents will be modified by the AudioTrackInterface::GetStats().
|
||||||
|
voice_sender_info.audio_level = 107;
|
||||||
|
voice_sender_info.echo_return_loss = 108;;
|
||||||
|
voice_sender_info.echo_return_loss_enhancement = 109;
|
||||||
|
voice_sender_info.echo_delay_median_ms = 110;
|
||||||
|
voice_sender_info.echo_delay_std_ms = 111;
|
||||||
|
voice_sender_info.aec_quality_min = 112;
|
||||||
|
voice_sender_info.typing_noise_detected = false;
|
||||||
|
|
||||||
|
// Constructs an ssrc stats update.
|
||||||
|
cricket::VoiceMediaInfo stats_read;
|
||||||
|
stats_read.senders.push_back(voice_sender_info);
|
||||||
|
|
||||||
|
EXPECT_CALL(session_, voice_channel()).WillRepeatedly(Return(&voice_channel));
|
||||||
|
EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
|
||||||
|
EXPECT_CALL(*media_channel, GetStats(_))
|
||||||
|
.WillRepeatedly(DoAll(SetArgPointee<0>(stats_read),
|
||||||
|
Return(true)));
|
||||||
|
|
||||||
|
StatsReports reports; // returned values.
|
||||||
|
stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
|
||||||
|
stats.GetStats(NULL, &reports);
|
||||||
|
|
||||||
|
// The report will exist since we don't remove them in RemoveStream().
|
||||||
|
const StatsReport* report = FindNthReportByType(
|
||||||
|
reports, StatsReport::kStatsReportTypeSsrc, 1);
|
||||||
|
EXPECT_FALSE(report == NULL);
|
||||||
|
std::string track_id = ExtractSsrcStatsValue(
|
||||||
|
reports, StatsReport::kStatsValueNameTrackId);
|
||||||
|
EXPECT_EQ(kAudioTrackId, track_id);
|
||||||
|
std::string ssrc_id = ExtractSsrcStatsValue(
|
||||||
|
reports, StatsReport::kStatsValueNameSsrc);
|
||||||
|
EXPECT_EQ(talk_base::ToString<uint32>(kSsrcOfTrack), ssrc_id);
|
||||||
|
|
||||||
|
// Verifies the values in the track report, no value will be changed by the
|
||||||
|
// AudioTrackInterface::GetSignalValue() and
|
||||||
|
// AudioProcessorInterface::AudioProcessorStats::GetStats();
|
||||||
|
VerifyVoiceSenderInfoReport(report, voice_sender_info);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -57,6 +57,8 @@ class StatsReport {
|
|||||||
void AddValue(const std::string& name, const std::vector<T>& value);
|
void AddValue(const std::string& name, const std::vector<T>& value);
|
||||||
void AddBoolean(const std::string& name, bool value);
|
void AddBoolean(const std::string& name, bool value);
|
||||||
|
|
||||||
|
void ReplaceValue(const std::string& name, const std::string& value);
|
||||||
|
|
||||||
double timestamp; // Time since 1970-01-01T00:00:00Z in milliseconds.
|
double timestamp; // Time since 1970-01-01T00:00:00Z in milliseconds.
|
||||||
typedef std::vector<Value> Values;
|
typedef std::vector<Value> Values;
|
||||||
Values values;
|
Values values;
|
||||||
|
@ -122,7 +122,8 @@ class FakeMediaStreamSignaling : public webrtc::MediaStreamSignaling,
|
|||||||
|
|
||||||
virtual void OnRemoveLocalAudioTrack(
|
virtual void OnRemoveLocalAudioTrack(
|
||||||
webrtc::MediaStreamInterface* stream,
|
webrtc::MediaStreamInterface* stream,
|
||||||
webrtc::AudioTrackInterface* audio_track) {
|
webrtc::AudioTrackInterface* audio_track,
|
||||||
|
uint32 ssrc) {
|
||||||
}
|
}
|
||||||
virtual void OnRemoveLocalVideoTrack(
|
virtual void OnRemoveLocalVideoTrack(
|
||||||
webrtc::MediaStreamInterface* stream,
|
webrtc::MediaStreamInterface* stream,
|
||||||
|
@ -45,9 +45,6 @@
|
|||||||
#include "talk/examples/call/console.h"
|
#include "talk/examples/call/console.h"
|
||||||
#include "talk/examples/call/mediaenginefactory.h"
|
#include "talk/examples/call/mediaenginefactory.h"
|
||||||
#include "talk/p2p/base/constants.h"
|
#include "talk/p2p/base/constants.h"
|
||||||
#ifdef ANDROID
|
|
||||||
#include "talk/media/other/androidmediaengine.h"
|
|
||||||
#endif
|
|
||||||
#include "talk/session/media/mediasessionclient.h"
|
#include "talk/session/media/mediasessionclient.h"
|
||||||
#include "talk/session/media/srtpfilter.h"
|
#include "talk/session/media/srtpfilter.h"
|
||||||
#include "talk/xmpp/xmppauth.h"
|
#include "talk/xmpp/xmppauth.h"
|
||||||
@ -185,7 +182,7 @@ static const int DEFAULT_PORT = 5222;
|
|||||||
static std::vector<cricket::AudioCodec> codecs;
|
static std::vector<cricket::AudioCodec> codecs;
|
||||||
static const cricket::AudioCodec ISAC(103, "ISAC", 40000, 16000, 1, 0);
|
static const cricket::AudioCodec ISAC(103, "ISAC", 40000, 16000, 1, 0);
|
||||||
|
|
||||||
cricket::MediaEngine *AndroidMediaEngineFactory() {
|
cricket::MediaEngineInterface *CreateAndroidMediaEngine() {
|
||||||
cricket::FakeMediaEngine *engine = new cricket::FakeMediaEngine();
|
cricket::FakeMediaEngine *engine = new cricket::FakeMediaEngine();
|
||||||
|
|
||||||
codecs.push_back(ISAC);
|
codecs.push_back(ISAC);
|
||||||
@ -438,7 +435,7 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ANDROID
|
#ifdef ANDROID
|
||||||
InitAndroidMediaEngineFactory(AndroidMediaEngineFactory);
|
MediaEngineFactory::SetCreateFunction(&CreateAndroidMediaEngine);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if WIN32
|
#if WIN32
|
||||||
|
@ -42,6 +42,13 @@ const int MediaEngineInterface::kDefaultAudioDelayOffset = 0;
|
|||||||
#if defined(HAVE_WEBRTC_VIDEO)
|
#if defined(HAVE_WEBRTC_VIDEO)
|
||||||
#include "talk/media/webrtc/webrtcvideoengine.h"
|
#include "talk/media/webrtc/webrtcvideoengine.h"
|
||||||
#endif // HAVE_WEBRTC_VIDEO
|
#endif // HAVE_WEBRTC_VIDEO
|
||||||
|
#if defined(HAVE_LMI)
|
||||||
|
#include "talk/media/base/hybridvideoengine.h"
|
||||||
|
#include "talk/media/lmi/lmimediaengine.h"
|
||||||
|
#endif // HAVE_LMI
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif // HAVE_CONFIG
|
||||||
|
|
||||||
namespace cricket {
|
namespace cricket {
|
||||||
#if defined(HAVE_WEBRTC_VOICE)
|
#if defined(HAVE_WEBRTC_VOICE)
|
||||||
@ -51,22 +58,59 @@ namespace cricket {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_WEBRTC_VIDEO)
|
#if defined(HAVE_WEBRTC_VIDEO)
|
||||||
|
#if !defined(HAVE_LMI)
|
||||||
template<>
|
template<>
|
||||||
CompositeMediaEngine<WebRtcVoiceEngine, WebRtcVideoEngine>::
|
CompositeMediaEngine<WebRtcVoiceEngine, WebRtcVideoEngine>::
|
||||||
CompositeMediaEngine() {
|
CompositeMediaEngine() {
|
||||||
video_.SetVoiceEngine(&voice_);
|
video_.SetVoiceEngine(&voice_);
|
||||||
}
|
}
|
||||||
#define VIDEO_ENG_NAME WebRtcVideoEngine
|
#define VIDEO_ENG_NAME WebRtcVideoEngine
|
||||||
|
#else
|
||||||
|
// If we have both WebRtcVideoEngine and LmiVideoEngine, enable dual-stack.
|
||||||
|
// This small class here allows us to hook the WebRtcVideoChannel up to
|
||||||
|
// the capturer owned by the LMI engine, without infecting the rest of the
|
||||||
|
// HybridVideoEngine classes with this abstraction violation.
|
||||||
|
class WebRtcLmiHybridVideoEngine
|
||||||
|
: public HybridVideoEngine<WebRtcVideoEngine, LmiVideoEngine> {
|
||||||
|
public:
|
||||||
|
void SetVoiceEngine(WebRtcVoiceEngine* engine) {
|
||||||
|
video1_.SetVoiceEngine(engine);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<>
|
||||||
|
CompositeMediaEngine<WebRtcVoiceEngine, WebRtcLmiHybridVideoEngine>::
|
||||||
|
CompositeMediaEngine() {
|
||||||
|
video_.SetVoiceEngine(&voice_);
|
||||||
|
}
|
||||||
|
#define VIDEO_ENG_NAME WebRtcLmiHybridVideoEngine
|
||||||
|
#endif
|
||||||
|
#elif defined(HAVE_LMI)
|
||||||
|
#define VIDEO_ENG_NAME LmiVideoEngine
|
||||||
|
#else
|
||||||
|
#define VIDEO_ENG_NAME NullVideoEngine
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
MediaEngineFactory::MediaEngineCreateFunction
|
||||||
|
MediaEngineFactory::create_function_ = NULL;
|
||||||
|
MediaEngineFactory::MediaEngineCreateFunction
|
||||||
|
MediaEngineFactory::SetCreateFunction(MediaEngineCreateFunction function) {
|
||||||
|
MediaEngineCreateFunction old_function = create_function_;
|
||||||
|
create_function_ = function;
|
||||||
|
return old_function;
|
||||||
|
};
|
||||||
|
|
||||||
MediaEngineInterface* MediaEngineFactory::Create() {
|
MediaEngineInterface* MediaEngineFactory::Create() {
|
||||||
|
if (create_function_) {
|
||||||
|
return create_function_();
|
||||||
|
} else {
|
||||||
#if defined(HAVE_LINPHONE)
|
#if defined(HAVE_LINPHONE)
|
||||||
return new LinphoneMediaEngine("", "");
|
return new LinphoneMediaEngine("", "");
|
||||||
#elif defined(AUDIO_ENG_NAME) && defined(VIDEO_ENG_NAME)
|
#elif defined(AUDIO_ENG_NAME) && defined(VIDEO_ENG_NAME)
|
||||||
return new CompositeMediaEngine<AUDIO_ENG_NAME, VIDEO_ENG_NAME>();
|
return new CompositeMediaEngine<AUDIO_ENG_NAME, VIDEO_ENG_NAME>();
|
||||||
#else
|
#else
|
||||||
return new NullMediaEngine();
|
return new NullMediaEngine();
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}; // namespace cricket
|
}; // namespace cricket
|
||||||
|
@ -157,7 +157,18 @@ class MediaEngineInterface {
|
|||||||
#if !defined(DISABLE_MEDIA_ENGINE_FACTORY)
|
#if !defined(DISABLE_MEDIA_ENGINE_FACTORY)
|
||||||
class MediaEngineFactory {
|
class MediaEngineFactory {
|
||||||
public:
|
public:
|
||||||
|
typedef cricket::MediaEngineInterface* (*MediaEngineCreateFunction)();
|
||||||
|
// Creates a media engine, using either the compiled system default or the
|
||||||
|
// creation function specified in SetCreateFunction, if specified.
|
||||||
static MediaEngineInterface* Create();
|
static MediaEngineInterface* Create();
|
||||||
|
// Sets the function used when calling Create. If unset, the compiled system
|
||||||
|
// default will be used. Returns the old create function, or NULL if one
|
||||||
|
// wasn't set. Likewise, NULL can be used as the |function| parameter to
|
||||||
|
// reset to the default behavior.
|
||||||
|
static MediaEngineCreateFunction SetCreateFunction(
|
||||||
|
MediaEngineCreateFunction function);
|
||||||
|
private:
|
||||||
|
static MediaEngineCreateFunction create_function_;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
0
talk/media/other/androidmediaengine.cc
Normal file
0
talk/media/other/androidmediaengine.cc
Normal file
0
talk/media/other/androidmediaengine.h
Normal file
0
talk/media/other/androidmediaengine.h
Normal file
Loading…
x
Reference in New Issue
Block a user