Wire up currently-received video codec to stats.

BUG=webrtc:1844, webrtc:4808
R=mflodman@webrtc.org, pthatcher@webrtc.org

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

Cr-Commit-Position: refs/heads/master@{#9810}
This commit is contained in:
pbos
2015-08-28 07:35:32 -07:00
committed by Commit bot
parent 6813ec84fb
commit f42376c601
13 changed files with 98 additions and 124 deletions

View File

@ -108,6 +108,11 @@ void ExtractCommonSendProperties(const cricket::MediaSenderInfo& info,
report->AddInt64(StatsReport::kStatsValueNameRtt, info.rtt_ms);
}
void ExtractCommonReceiveProperties(const cricket::MediaReceiverInfo& info,
StatsReport* report) {
report->AddString(StatsReport::kStatsValueNameCodecName, info.codec_name);
}
void SetAudioProcessingStats(StatsReport* report, int signal_level,
bool typing_noise_detected, int echo_return_loss,
int echo_return_loss_enhancement, int echo_delay_median_ms,
@ -131,6 +136,7 @@ void SetAudioProcessingStats(StatsReport* report, int signal_level,
}
void ExtractStats(const cricket::VoiceReceiverInfo& info, StatsReport* report) {
ExtractCommonReceiveProperties(info, report);
const FloatForAdd floats[] = {
{ StatsReport::kStatsValueNameExpandRate, info.expand_rate },
{ StatsReport::kStatsValueNameSecondaryDecodedRate,
@ -169,8 +175,6 @@ void ExtractStats(const cricket::VoiceReceiverInfo& info, StatsReport* report) {
info.bytes_rcvd);
report->AddInt64(StatsReport::kStatsValueNameCaptureStartNtpTimeMs,
info.capture_start_ntp_time_ms);
report->AddString(StatsReport::kStatsValueNameCodecName, info.codec_name);
}
void ExtractStats(const cricket::VoiceSenderInfo& info, StatsReport* report) {
@ -191,6 +195,7 @@ void ExtractStats(const cricket::VoiceSenderInfo& info, StatsReport* report) {
}
void ExtractStats(const cricket::VideoReceiverInfo& info, StatsReport* report) {
ExtractCommonReceiveProperties(info, report);
report->AddInt64(StatsReport::kStatsValueNameBytesReceived,
info.bytes_rcvd);
report->AddInt64(StatsReport::kStatsValueNameCaptureStartNtpTimeMs,

View File

@ -2583,6 +2583,17 @@ void WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetSize(int width,
last_height_ = height;
}
std::string
WebRtcVideoChannel2::WebRtcVideoReceiveStream::GetCodecNameFromPayloadType(
int payload_type) {
for (const webrtc::VideoReceiveStream::Decoder& decoder : config_.decoders) {
if (decoder.payload_type == payload_type) {
return decoder.payload_name;
}
}
return "";
}
VideoReceiverInfo
WebRtcVideoChannel2::WebRtcVideoReceiveStream::GetVideoReceiverInfo() {
VideoReceiverInfo info;
@ -2616,6 +2627,8 @@ WebRtcVideoChannel2::WebRtcVideoReceiveStream::GetVideoReceiverInfo() {
info.min_playout_delay_ms = stats.min_playout_delay_ms;
info.render_delay_ms = stats.render_delay_ms;
info.codec_name = GetCodecNameFromPayloadType(stats.current_payload_type);
info.firs_sent = stats.rtcp_packet_type_counts.fir_packets;
info.plis_sent = stats.rtcp_packet_type_counts.pli_packets;
info.nacks_sent = stats.rtcp_packet_type_counts.nack_packets;

View File

@ -458,6 +458,8 @@ class WebRtcVideoChannel2 : public rtc::MessageHandler,
const VideoCodec& codec);
void ClearDecoders(std::vector<AllocatedDecoder>* allocated_decoders);
std::string GetCodecNameFromPayloadType(int payload_type);
webrtc::Call* const call_;
const std::vector<uint32> ssrcs_;
const std::vector<SsrcGroup> ssrc_groups_;

View File

@ -2670,6 +2670,29 @@ TEST_F(WebRtcVideoChannel2Test, ReportsSsrcGroupsInStats) {
EXPECT_EQ(receiver_sp.ssrc_groups, info.receivers[0].ssrc_groups);
}
TEST_F(WebRtcVideoChannel2Test, MapsReceivedPayloadTypeToCodecName) {
FakeVideoReceiveStream* stream = AddRecvStream();
webrtc::VideoReceiveStream::Stats stats;
cricket::VideoMediaInfo info;
// Report no codec name before receiving.
stream->SetStats(stats);
ASSERT_TRUE(channel_->GetStats(&info));
EXPECT_STREQ("", info.receivers[0].codec_name.c_str());
// Report VP8 if we're receiving it.
stats.current_payload_type = kDefaultVp8PlType;
stream->SetStats(stats);
ASSERT_TRUE(channel_->GetStats(&info));
EXPECT_STREQ(kVp8CodecName, info.receivers[0].codec_name.c_str());
// Report no codec name for unknown playload types.
stats.current_payload_type = 3;
stream->SetStats(stats);
ASSERT_TRUE(channel_->GetStats(&info));
EXPECT_STREQ("", info.receivers[0].codec_name.c_str());
}
void WebRtcVideoChannel2Test::TestReceiveUnsignalledSsrcPacket(
uint8_t payload_type,
bool expect_created_receive_stream) {

View File

@ -76,7 +76,7 @@ class VCMReceiveCallback {
return -1;
}
// Called when the current receive codec changes.
virtual void IncomingCodecChanged(const VideoCodec& codec) {}
virtual void OnIncomingPayloadType(int payload_type) {}
protected:
virtual ~VCMReceiveCallback() {

View File

@ -581,7 +581,7 @@ VCMGenericDecoder* VCMCodecDataBase::GetDecoder(
return NULL;
}
VCMReceiveCallback* callback = decoded_frame_callback->UserReceiveCallback();
if (callback) callback->IncomingCodecChanged(receive_codec_);
if (callback) callback->OnIncomingPayloadType(receive_codec_.plType);
if (ptr_decoder_->RegisterDecodeCompleteCallback(decoded_frame_callback)
< 0) {
ReleaseDecoder(ptr_decoder_);

View File

@ -2216,6 +2216,11 @@ TEST_F(EndToEndTest, GetStats) {
stats.rtcp_packet_type_counts.pli_packets != 0 ||
stats.rtcp_packet_type_counts.nack_requests != 0 ||
stats.rtcp_packet_type_counts.unique_nack_requests != 0;
assert(stats.current_payload_type == -1 ||
stats.current_payload_type == kFakeSendPayloadType);
receive_stats_filled_["IncomingPayloadType"] |=
stats.current_payload_type == kFakeSendPayloadType;
}
return AllStatsFilled(receive_stats_filled_);

View File

@ -59,15 +59,19 @@ VideoReceiveStream::Stats ReceiveStatisticsProxy::GetStats() const {
return stats_;
}
void ReceiveStatisticsProxy::IncomingRate(const int video_channel,
const unsigned int framerate,
const unsigned int bitrate_bps) {
void ReceiveStatisticsProxy::OnIncomingPayloadType(int payload_type) {
rtc::CritScope lock(&crit_);
stats_.current_payload_type = payload_type;
}
void ReceiveStatisticsProxy::OnIncomingRate(unsigned int framerate,
unsigned int bitrate_bps) {
rtc::CritScope lock(&crit_);
stats_.network_frame_rate = framerate;
stats_.total_bitrate_bps = bitrate_bps;
}
void ReceiveStatisticsProxy::DecoderTiming(int decode_ms,
void ReceiveStatisticsProxy::OnDecoderTiming(int decode_ms,
int max_decode_ms,
int current_delay_ms,
int target_delay_ms,

View File

@ -31,8 +31,7 @@ class Clock;
class ViECodec;
class ViEDecoderObserver;
class ReceiveStatisticsProxy : public ViEDecoderObserver,
public VCMReceiveStatisticsCallback,
class ReceiveStatisticsProxy : public VCMReceiveStatisticsCallback,
public RtcpStatisticsCallback,
public RtcpPacketTypeCounterObserver,
public StreamDataCountersCallback {
@ -44,25 +43,20 @@ class ReceiveStatisticsProxy : public ViEDecoderObserver,
void OnDecodedFrame();
void OnRenderedFrame(int width, int height);
// Overrides VCMReceiveStatisticsCallback.
void OnReceiveRatesUpdated(uint32_t bitRate, uint32_t frameRate) override;
void OnFrameCountsUpdated(const FrameCounts& frame_counts) override;
void OnDiscardedPacketsUpdated(int discarded_packets) override;
// Overrides ViEDecoderObserver.
void IncomingCodecChanged(const int video_channel,
const VideoCodec& video_codec) override {}
void IncomingRate(const int video_channel,
const unsigned int framerate,
const unsigned int bitrate_bps) override;
void DecoderTiming(int decode_ms,
void OnIncomingPayloadType(int payload_type);
void OnIncomingRate(unsigned int framerate, unsigned int bitrate_bps);
void OnDecoderTiming(int decode_ms,
int max_decode_ms,
int current_delay_ms,
int target_delay_ms,
int jitter_buffer_ms,
int min_playout_delay_ms,
int render_delay_ms) override;
int render_delay_ms);
// Overrides VCMReceiveStatisticsCallback.
void OnReceiveRatesUpdated(uint32_t bitRate, uint32_t frameRate) override;
void OnFrameCountsUpdated(const FrameCounts& frame_counts) override;
void OnDiscardedPacketsUpdated(int discarded_packets) override;
// Overrides RtcpStatisticsCallback.
void StatisticsUpdated(const webrtc::RtcpStatistics& statistics,

View File

@ -215,13 +215,11 @@ VideoReceiveStream::VideoReceiveStream(int num_cpu_cores,
stats_proxy_.reset(
new ReceiveStatisticsProxy(config_.rtp.remote_ssrc, clock_));
vie_channel_->RegisterReceiveStatisticsProxy(stats_proxy_.get());
vie_channel_->RegisterReceiveChannelRtcpStatisticsCallback(
stats_proxy_.get());
vie_channel_->RegisterReceiveChannelRtpStatisticsCallback(stats_proxy_.get());
vie_channel_->RegisterRtcpPacketTypeCounterObserver(stats_proxy_.get());
vie_channel_->RegisterCodecObserver(stats_proxy_.get());
vie_channel_->RegisterReceiveStatisticsProxy(stats_proxy_.get());
DCHECK(!config_.decoders.empty());
for (size_t i = 0; i < config_.decoders.size(); ++i) {
@ -254,10 +252,6 @@ VideoReceiveStream::~VideoReceiveStream() {
for (size_t i = 0; i < config_.decoders.size(); ++i)
vie_channel_->DeRegisterExternalDecoder(config_.decoders[i].payload_type);
vie_channel_->RegisterCodecObserver(nullptr);
vie_channel_->RegisterReceiveChannelRtpStatisticsCallback(nullptr);
vie_channel_->RegisterReceiveChannelRtcpStatisticsCallback(nullptr);
vie_channel_->RegisterRtcpPacketTypeCounterObserver(nullptr);
channel_group_->DeleteChannel(channel_id_);
}

View File

@ -105,16 +105,14 @@ ViEChannel::ViEChannel(int32_t channel_id,
vie_receiver_(channel_id, vcm_, remote_bitrate_estimator, this),
vie_sync_(vcm_),
stats_observer_(new ChannelStatsObserver(this)),
vcm_receive_stats_callback_(NULL),
receive_stats_callback_(nullptr),
incoming_video_stream_(nullptr),
codec_observer_(NULL),
intra_frame_observer_(intra_frame_observer),
rtt_stats_(rtt_stats),
paced_sender_(paced_sender),
packet_router_(packet_router),
bandwidth_observer_(bandwidth_observer),
send_time_observer_(send_time_observer),
decoder_reset_(true),
nack_history_size_sender_(kSendSidePacketHistorySize),
max_nack_reordering_threshold_(kMaxPacketAgeToNack),
pre_render_callback_(NULL),
@ -437,20 +435,6 @@ int32_t ViEChannel::SetReceiveCodec(const VideoCodec& video_codec) {
return 0;
}
int32_t ViEChannel::RegisterCodecObserver(ViEDecoderObserver* observer) {
CriticalSectionScoped cs(crit_.get());
if (observer) {
if (codec_observer_) {
LOG_F(LS_ERROR) << "Observer already registered.";
return -1;
}
codec_observer_ = observer;
} else {
codec_observer_ = NULL;
}
return 0;
}
int32_t ViEChannel::RegisterExternalDecoder(const uint8_t pl_type,
VideoDecoder* decoder,
bool buffered_rendering,
@ -1042,18 +1026,6 @@ CallStatsObserver* ViEChannel::GetStatsObserver() {
int32_t ViEChannel::FrameToRender(VideoFrame& video_frame) { // NOLINT
CriticalSectionScoped cs(crit_.get());
if (decoder_reset_) {
// Trigger a callback to the user if the incoming codec has changed.
if (codec_observer_) {
// The codec set by RegisterReceiveCodec might not be the size we're
// actually decoding.
receive_codec_.width = static_cast<uint16_t>(video_frame.width());
receive_codec_.height = static_cast<uint16_t>(video_frame.height());
codec_observer_->IncomingCodecChanged(channel_id_, receive_codec_);
}
decoder_reset_ = false;
}
if (pre_render_callback_ != NULL)
pre_render_callback_->FrameCallback(&video_frame);
@ -1066,28 +1038,29 @@ int32_t ViEChannel::ReceivedDecodedReferenceFrame(
return rtp_rtcp_modules_[0]->SendRTCPReferencePictureSelection(picture_id);
}
void ViEChannel::IncomingCodecChanged(const VideoCodec& codec) {
void ViEChannel::OnIncomingPayloadType(int payload_type) {
CriticalSectionScoped cs(crit_.get());
receive_codec_ = codec;
if (receive_stats_callback_)
receive_stats_callback_->OnIncomingPayloadType(payload_type);
}
void ViEChannel::OnReceiveRatesUpdated(uint32_t bit_rate, uint32_t frame_rate) {
CriticalSectionScoped cs(crit_.get());
if (codec_observer_)
codec_observer_->IncomingRate(channel_id_, frame_rate, bit_rate);
if (receive_stats_callback_)
receive_stats_callback_->OnIncomingRate(frame_rate, bit_rate);
}
void ViEChannel::OnDiscardedPacketsUpdated(int discarded_packets) {
CriticalSectionScoped cs(crit_.get());
if (vcm_receive_stats_callback_ != NULL)
vcm_receive_stats_callback_->OnDiscardedPacketsUpdated(discarded_packets);
if (receive_stats_callback_)
receive_stats_callback_->OnDiscardedPacketsUpdated(discarded_packets);
}
void ViEChannel::OnFrameCountsUpdated(const FrameCounts& frame_counts) {
CriticalSectionScoped cs(crit_.get());
receive_frame_counts_ = frame_counts;
if (vcm_receive_stats_callback_ != NULL)
vcm_receive_stats_callback_->OnFrameCountsUpdated(frame_counts);
if (receive_stats_callback_)
receive_stats_callback_->OnFrameCountsUpdated(frame_counts);
}
void ViEChannel::OnDecoderTiming(int decode_ms,
@ -1098,15 +1071,11 @@ void ViEChannel::OnDecoderTiming(int decode_ms,
int min_playout_delay_ms,
int render_delay_ms) {
CriticalSectionScoped cs(crit_.get());
if (!codec_observer_)
if (!receive_stats_callback_)
return;
codec_observer_->DecoderTiming(decode_ms,
max_decode_ms,
current_delay_ms,
target_delay_ms,
jitter_buffer_ms,
min_playout_delay_ms,
render_delay_ms);
receive_stats_callback_->OnDecoderTiming(
decode_ms, max_decode_ms, current_delay_ms, target_delay_ms,
jitter_buffer_ms, min_playout_delay_ms, render_delay_ms);
}
int32_t ViEChannel::RequestKeyFrame() {
@ -1261,6 +1230,8 @@ void ViEChannel::RegisterPreDecodeImageCallback(
vcm_->RegisterPreDecodeImageCallback(pre_decode_callback);
}
// TODO(pbos): Remove OnInitializeDecoder which is called from the RTP module,
// any decoder resetting should be handled internally within the VCM.
int32_t ViEChannel::OnInitializeDecoder(
const int32_t id,
const int8_t payload_type,
@ -1272,8 +1243,6 @@ int32_t ViEChannel::OnInitializeDecoder(
<< " " << payload_name;
vcm_->ResetDecoder();
CriticalSectionScoped cs(crit_.get());
decoder_reset_ = true;
return 0;
}
@ -1297,7 +1266,7 @@ void ViEChannel::RegisterSendFrameCountObserver(
void ViEChannel::RegisterReceiveStatisticsProxy(
ReceiveStatisticsProxy* receive_statistics_proxy) {
CriticalSectionScoped cs(crit_.get());
vcm_receive_stats_callback_ = receive_statistics_proxy;
receive_stats_callback_ = receive_statistics_proxy;
}
void ViEChannel::SetIncomingVideoStream(

View File

@ -44,7 +44,6 @@ class ReportBlockStats;
class RtcpRttStats;
class ThreadWrapper;
class ViEChannelProtectionCallback;
class ViEDecoderObserver;
class ViERTPObserver;
class VideoCodingModule;
class VideoDecoder;
@ -56,36 +55,6 @@ enum StreamType {
kViEStreamTypeRtx = 1 // Retransmission media stream
};
// This class declares an abstract interface for a user defined observer. It is
// up to the VideoEngine user to implement a derived class which implements the
// observer class. The observer is registered using RegisterDecoderObserver()
// and deregistered using DeregisterDecoderObserver().
class ViEDecoderObserver {
public:
// This method is called when a new incoming stream is detected, normally
// triggered by a new incoming SSRC or payload type.
virtual void IncomingCodecChanged(const int video_channel,
const VideoCodec& video_codec) = 0;
// This method is called once per second containing the frame rate and bit
// rate for the incoming stream
virtual void IncomingRate(const int video_channel,
const unsigned int framerate,
const unsigned int bitrate) = 0;
// Called periodically with decoder timing information. All values are
// "current" snapshots unless decorated with a min_/max_ prefix.
virtual void DecoderTiming(int decode_ms,
int max_decode_ms,
int current_delay_ms,
int target_delay_ms,
int jitter_buffer_ms,
int min_playout_delay_ms,
int render_delay_ms) = 0;
protected:
virtual ~ViEDecoderObserver() {}
};
class ViEChannel : public VCMFrameTypeCallback,
public VCMReceiveCallback,
public VCMReceiveStatisticsCallback,
@ -118,7 +87,6 @@ class ViEChannel : public VCMFrameTypeCallback,
// type has changed and we should start a new RTP stream.
int32_t SetSendCodec(const VideoCodec& video_codec, bool new_stream = true);
int32_t SetReceiveCodec(const VideoCodec& video_codec);
int32_t RegisterCodecObserver(ViEDecoderObserver* observer);
// Registers an external decoder. |buffered_rendering| means that the decoder
// will render frames after decoding according to the render timestamp
// provided by the video coding module. |render_delay| indicates the time
@ -271,7 +239,7 @@ class ViEChannel : public VCMFrameTypeCallback,
const uint64_t picture_id);
// Implements VCMReceiveCallback.
virtual void IncomingCodecChanged(const VideoCodec& codec);
void OnIncomingPayloadType(int payload_type) override;
// Implements VCMReceiveStatisticsCallback.
void OnReceiveRatesUpdated(uint32_t bit_rate, uint32_t frame_rate) override;
@ -464,11 +432,9 @@ class ViEChannel : public VCMFrameTypeCallback,
rtc::scoped_ptr<ChannelStatsObserver> stats_observer_;
// Not owned.
VCMReceiveStatisticsCallback* vcm_receive_stats_callback_
GUARDED_BY(crit_);
ReceiveStatisticsProxy* receive_stats_callback_ GUARDED_BY(crit_);
FrameCounts receive_frame_counts_ GUARDED_BY(crit_);
IncomingVideoStream* incoming_video_stream_ GUARDED_BY(crit_);
ViEDecoderObserver* codec_observer_ GUARDED_BY(crit_);
RtcpIntraFrameObserver* const intra_frame_observer_;
RtcpRttStats* const rtt_stats_;
PacedSender* const paced_sender_;
@ -477,9 +443,6 @@ class ViEChannel : public VCMFrameTypeCallback,
const rtc::scoped_ptr<RtcpBandwidthObserver> bandwidth_observer_;
SendTimeObserver* const send_time_observer_;
bool decoder_reset_ GUARDED_BY(crit_);
// Current receive codec used for codec change callback.
VideoCodec receive_codec_ GUARDED_BY(crit_);
rtc::scoped_ptr<ThreadWrapper> decode_thread_;
int nack_history_size_sender_;

View File

@ -75,6 +75,8 @@ class VideoReceiveStream : public ReceiveStream {
int min_playout_delay_ms = 0;
int render_delay_ms = 10;
int current_payload_type = -1;
int total_bitrate_bps = 0;
int discarded_packets = 0;