Extend full stack tests with more stats

BUG=
R=pbos@webrtc.org

Review URL: https://codereview.webrtc.org/1216613002 .

Cr-Commit-Position: refs/heads/master@{#9612}
This commit is contained in:
Erik Språng 2015-07-22 17:17:58 +02:00
parent d89920b74a
commit 085856cd35

View File

@ -18,6 +18,7 @@
#include "webrtc/base/thread_annotations.h"
#include "webrtc/call.h"
#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
#include "webrtc/frame_callback.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
#include "webrtc/system_wrappers/interface/clock.h"
#include "webrtc/system_wrappers/interface/cpu_info.h"
@ -37,6 +38,7 @@
namespace webrtc {
static const int kFullStackTestDurationSecs = 60;
static const int kSendStatsPollingIntervalMs = 1000;
struct FullStackTestParams {
const char* test_label;
@ -63,7 +65,8 @@ class FullStackTest : public test::CallTest {
class VideoAnalyzer : public PacketReceiver,
public newapi::Transport,
public VideoRenderer,
public VideoCaptureInput {
public VideoCaptureInput,
public EncodedFrameObserver {
public:
VideoAnalyzer(VideoCaptureInput* input,
Transport* transport,
@ -74,6 +77,7 @@ class VideoAnalyzer : public PacketReceiver,
: input_(input),
transport_(transport),
receiver_(nullptr),
send_stream_(nullptr),
test_label_(test_label),
frames_to_process_(duration_frames),
frames_recorded_(0),
@ -110,6 +114,10 @@ class VideoAnalyzer : public PacketReceiver,
EXPECT_TRUE(thread->Start());
comparison_thread_pool_.push_back(thread.release());
}
stats_polling_thread_ =
ThreadWrapper::CreateThread(&PollStatsThread, this, "StatsPoller");
EXPECT_TRUE(stats_polling_thread_->Start());
}
~VideoAnalyzer() {
@ -173,6 +181,12 @@ class VideoAnalyzer : public PacketReceiver,
return transport_->SendRtcp(packet, length);
}
void EncodedFrameCallback(const EncodedFrame& frame) override {
rtc::CritScope lock(&comparison_lock_);
if (frames_recorded_ < frames_to_process_)
encoded_frame_size_.AddSample(frame.length_);
}
void RenderFrame(const VideoFrame& video_frame,
int time_to_render_ms) override {
int64_t render_time_ms =
@ -222,11 +236,18 @@ class VideoAnalyzer : public PacketReceiver,
<< "Analyzer stalled while waiting for test to finish.";
last_frames_processed = frames_processed;
}
// Signal stats polling thread if that is still waiting and stop it now,
// since it uses the send_stream_ reference that might be reclaimed after
// returning from this method.
done_->Set();
EXPECT_TRUE(stats_polling_thread_->Stop());
}
VideoCaptureInput* input_;
Transport* transport_;
PacketReceiver* receiver_;
VideoSendStream* send_stream_;
private:
struct FrameComparison {
@ -265,15 +286,39 @@ class VideoAnalyzer : public PacketReceiver,
recv_times_.erase(reference.timestamp());
rtc::CritScope crit(&comparison_lock_);
comparisons_.push_back(FrameComparison(reference,
render,
dropped,
send_time_ms,
recv_time_ms,
comparisons_.push_back(FrameComparison(reference, render, dropped,
send_time_ms, recv_time_ms,
render_time_ms));
comparison_available_event_->Set();
}
static bool PollStatsThread(void* obj) {
return static_cast<VideoAnalyzer*>(obj)->PollStats();
}
bool PollStats() {
switch (done_->Wait(kSendStatsPollingIntervalMs)) {
case kEventSignaled:
case kEventError:
done_->Set(); // Make sure main thread is also signaled.
return false;
case kEventTimeout:
break;
default:
RTC_NOTREACHED();
}
VideoSendStream::Stats stats = send_stream_->GetStats();
rtc::CritScope crit(&comparison_lock_);
encode_frame_rate_.AddSample(stats.encode_frame_rate);
encode_time_ms.AddSample(stats.avg_encode_time_ms);
encode_usage_percent.AddSample(stats.encode_usage_percent);
media_bitrate_bps.AddSample(stats.media_bitrate_bps);
return true;
}
static bool FrameComparisonThread(void* obj) {
return static_cast<VideoAnalyzer*>(obj)->CompareFrames();
}
@ -358,6 +403,12 @@ class VideoAnalyzer : public PacketReceiver,
PrintResult("receiver_time", receiver_time_, " ms");
PrintResult("total_delay_incl_network", end_to_end_, " ms");
PrintResult("time_between_rendered_frames", rendered_delta_, " ms");
PrintResult("encoded_frame_size", encoded_frame_size_, " bytes");
PrintResult("encode_frame_rate", encode_frame_rate_, " fps");
PrintResult("encode_time", encode_time_ms, " ms");
PrintResult("encode_usage_percent", encode_usage_percent, " percent");
PrintResult("media_bitrate", media_bitrate_bps, " bps");
EXPECT_GT(psnr_.Mean(), avg_psnr_threshold_);
EXPECT_GT(ssim_.Mean(), avg_ssim_threshold_);
}
@ -397,12 +448,18 @@ class VideoAnalyzer : public PacketReceiver,
}
const char* const test_label_;
test::Statistics sender_time_;
test::Statistics receiver_time_;
test::Statistics psnr_;
test::Statistics ssim_;
test::Statistics end_to_end_;
test::Statistics rendered_delta_;
test::Statistics sender_time_ GUARDED_BY(comparison_lock_);
test::Statistics receiver_time_ GUARDED_BY(comparison_lock_);
test::Statistics psnr_ GUARDED_BY(comparison_lock_);
test::Statistics ssim_ GUARDED_BY(comparison_lock_);
test::Statistics end_to_end_ GUARDED_BY(comparison_lock_);
test::Statistics rendered_delta_ GUARDED_BY(comparison_lock_);
test::Statistics encoded_frame_size_ GUARDED_BY(comparison_lock_);
test::Statistics encode_frame_rate_ GUARDED_BY(comparison_lock_);
test::Statistics encode_time_ms GUARDED_BY(comparison_lock_);
test::Statistics encode_usage_percent GUARDED_BY(comparison_lock_);
test::Statistics media_bitrate_bps GUARDED_BY(comparison_lock_);
const int frames_to_process_;
int frames_recorded_;
int frames_processed_;
@ -421,6 +478,7 @@ class VideoAnalyzer : public PacketReceiver,
rtc::CriticalSection comparison_lock_;
std::vector<ThreadWrapper*> comparison_thread_pool_;
rtc::scoped_ptr<ThreadWrapper> stats_polling_thread_;
const rtc::scoped_ptr<EventWrapper> comparison_available_event_;
std::deque<FrameComparison> comparisons_ GUARDED_BY(comparison_lock_);
const rtc::scoped_ptr<EventWrapper> done_;
@ -478,8 +536,11 @@ void FullStackTest::RunTest(const FullStackTestParams& params) {
receive_configs_[0].rtp.rtx[kSendRtxPayloadType].payload_type =
kSendRtxPayloadType;
for (auto& config : receive_configs_)
config.pre_decode_callback = &analyzer;
CreateStreams();
analyzer.input_ = send_stream_->Input();
analyzer.send_stream_ = send_stream_;
if (params.screenshare) {
std::vector<std::string> slides;