Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(364)

Side by Side Diff: talk/media/webrtc/webrtcvoiceengine.cc

Issue 1390753002: Implement AudioReceiveStream::GetStats(). (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: merge master Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « talk/media/webrtc/webrtcvoe.h ('k') | talk/media/webrtc/webrtcvoiceengine_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * libjingle 2 * libjingle
3 * Copyright 2004 Google Inc. 3 * Copyright 2004 Google Inc.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright notice, 8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer. 9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice, 10 * 2. Redistributions in binary form must reproduce the above copyright notice,
(...skipping 2631 matching lines...) Expand 10 before | Expand all | Expand 10 after
2642 2642
2643 int median, std; 2643 int median, std;
2644 float dummy; 2644 float dummy;
2645 if (engine()->voe()->processing()->GetEcDelayMetrics( 2645 if (engine()->voe()->processing()->GetEcDelayMetrics(
2646 median, std, dummy) != -1) { 2646 median, std, dummy) != -1) {
2647 echo_delay_median_ms = median; 2647 echo_delay_median_ms = median;
2648 echo_delay_std_ms = std; 2648 echo_delay_std_ms = std;
2649 } 2649 }
2650 } 2650 }
2651 2651
2652 webrtc::CallStatistics cs;
2653 unsigned int ssrc;
2654 webrtc::CodecInst codec;
2655 unsigned int level;
2656
2657 for (const auto& ch : send_streams_) { 2652 for (const auto& ch : send_streams_) {
2658 const int channel = ch.second->channel(); 2653 const int channel = ch.second->channel();
2659 2654
2660 // Fill in the sender info, based on what we know, and what the 2655 // Fill in the sender info, based on what we know, and what the
2661 // remote side told us it got from its RTCP report. 2656 // remote side told us it got from its RTCP report.
2662 VoiceSenderInfo sinfo; 2657 VoiceSenderInfo sinfo;
2663 2658
2659 webrtc::CallStatistics cs = {0};
2660 unsigned int ssrc = 0;
2664 if (engine()->voe()->rtp()->GetRTCPStatistics(channel, cs) == -1 || 2661 if (engine()->voe()->rtp()->GetRTCPStatistics(channel, cs) == -1 ||
2665 engine()->voe()->rtp()->GetLocalSSRC(channel, ssrc) == -1) { 2662 engine()->voe()->rtp()->GetLocalSSRC(channel, ssrc) == -1) {
2666 continue; 2663 continue;
2667 } 2664 }
2668 2665
2669 sinfo.add_ssrc(ssrc); 2666 sinfo.add_ssrc(ssrc);
2670 sinfo.codec_name = send_codec_.get() ? send_codec_->plname : ""; 2667 sinfo.codec_name = send_codec_.get() ? send_codec_->plname : "";
2671 sinfo.bytes_sent = cs.bytesSent; 2668 sinfo.bytes_sent = cs.bytesSent;
2672 sinfo.packets_sent = cs.packetsSent; 2669 sinfo.packets_sent = cs.packetsSent;
2673 // RTT isn't known until a RTCP report is received. Until then, VoiceEngine 2670 // RTT isn't known until a RTCP report is received. Until then, VoiceEngine
2674 // returns 0 to indicate an error value. 2671 // returns 0 to indicate an error value.
2675 sinfo.rtt_ms = (cs.rttMs > 0) ? cs.rttMs : -1; 2672 sinfo.rtt_ms = (cs.rttMs > 0) ? cs.rttMs : -1;
2676 2673
2677 // Get data from the last remote RTCP report. Use default values if no data 2674 // Get data from the last remote RTCP report. Use default values if no data
2678 // available. 2675 // available.
2679 sinfo.fraction_lost = -1.0; 2676 sinfo.fraction_lost = -1.0;
2680 sinfo.jitter_ms = -1; 2677 sinfo.jitter_ms = -1;
2681 sinfo.packets_lost = -1; 2678 sinfo.packets_lost = -1;
2682 sinfo.ext_seqnum = -1; 2679 sinfo.ext_seqnum = -1;
2683 std::vector<webrtc::ReportBlock> receive_blocks; 2680 std::vector<webrtc::ReportBlock> receive_blocks;
2681 webrtc::CodecInst codec = {0};
2684 if (engine()->voe()->rtp()->GetRemoteRTCPReportBlocks( 2682 if (engine()->voe()->rtp()->GetRemoteRTCPReportBlocks(
2685 channel, &receive_blocks) != -1 && 2683 channel, &receive_blocks) != -1 &&
2686 engine()->voe()->codec()->GetSendCodec(channel, codec) != -1) { 2684 engine()->voe()->codec()->GetSendCodec(channel, codec) != -1) {
2687 for (const webrtc::ReportBlock& block : receive_blocks) { 2685 for (const webrtc::ReportBlock& block : receive_blocks) {
2688 // Lookup report for send ssrc only. 2686 // Lookup report for send ssrc only.
2689 if (block.source_SSRC == sinfo.ssrc()) { 2687 if (block.source_SSRC == sinfo.ssrc()) {
2690 // Convert Q8 to floating point. 2688 // Convert Q8 to floating point.
2691 sinfo.fraction_lost = static_cast<float>(block.fraction_lost) / 256; 2689 sinfo.fraction_lost = static_cast<float>(block.fraction_lost) / 256;
2692 // Convert samples to milliseconds. 2690 // Convert samples to milliseconds.
2693 if (codec.plfreq / 1000 > 0) { 2691 if (codec.plfreq / 1000 > 0) {
2694 sinfo.jitter_ms = block.interarrival_jitter / (codec.plfreq / 1000); 2692 sinfo.jitter_ms = block.interarrival_jitter / (codec.plfreq / 1000);
2695 } 2693 }
2696 sinfo.packets_lost = block.cumulative_num_packets_lost; 2694 sinfo.packets_lost = block.cumulative_num_packets_lost;
2697 sinfo.ext_seqnum = block.extended_highest_sequence_number; 2695 sinfo.ext_seqnum = block.extended_highest_sequence_number;
2698 break; 2696 break;
2699 } 2697 }
2700 } 2698 }
2701 } 2699 }
2702 2700
2703 // Local speech level. 2701 // Local speech level.
2702 unsigned int level = 0;
2704 sinfo.audio_level = (engine()->voe()->volume()-> 2703 sinfo.audio_level = (engine()->voe()->volume()->
2705 GetSpeechInputLevelFullRange(level) != -1) ? level : -1; 2704 GetSpeechInputLevelFullRange(level) != -1) ? level : -1;
2706 2705
2707 // TODO(xians): We are injecting the same APM logging to all the send 2706 // TODO(xians): We are injecting the same APM logging to all the send
2708 // channels here because there is no good way to know which send channel 2707 // channels here because there is no good way to know which send channel
2709 // is using the APM. The correct fix is to allow the send channels to have 2708 // is using the APM. The correct fix is to allow the send channels to have
2710 // their own APM so that we can feed the correct APM logging to different 2709 // their own APM so that we can feed the correct APM logging to different
2711 // send channels. See issue crbug/264611 . 2710 // send channels. See issue crbug/264611 .
2712 sinfo.echo_return_loss = echo_return_loss; 2711 sinfo.echo_return_loss = echo_return_loss;
2713 sinfo.echo_return_loss_enhancement = echo_return_loss_enhancement; 2712 sinfo.echo_return_loss_enhancement = echo_return_loss_enhancement;
2714 sinfo.echo_delay_median_ms = echo_delay_median_ms; 2713 sinfo.echo_delay_median_ms = echo_delay_median_ms;
2715 sinfo.echo_delay_std_ms = echo_delay_std_ms; 2714 sinfo.echo_delay_std_ms = echo_delay_std_ms;
2716 // TODO(ajm): Re-enable this metric once we have a reliable implementation. 2715 // TODO(ajm): Re-enable this metric once we have a reliable implementation.
2717 sinfo.aec_quality_min = -1; 2716 sinfo.aec_quality_min = -1;
2718 sinfo.typing_noise_detected = typing_noise_detected_; 2717 sinfo.typing_noise_detected = typing_noise_detected_;
2719 2718
2720 info->senders.push_back(sinfo); 2719 info->senders.push_back(sinfo);
2721 } 2720 }
2722 2721
2723 // Get the SSRC and stats for each receiver. 2722 // Get the SSRC and stats for each receiver.
2724 for (const auto& ch : receive_channels_) { 2723 info->receivers.clear();
2725 int ch_id = ch.second->channel(); 2724 for (const auto& stream : receive_streams_) {
2726 memset(&cs, 0, sizeof(cs)); 2725 webrtc::AudioReceiveStream::Stats stats = stream.second->GetStats();
2727 if (engine()->voe()->rtp()->GetRemoteSSRC(ch_id, ssrc) != -1 && 2726 VoiceReceiverInfo rinfo;
2728 engine()->voe()->rtp()->GetRTCPStatistics(ch_id, cs) != -1 && 2727 rinfo.add_ssrc(stats.remote_ssrc);
2729 engine()->voe()->codec()->GetRecCodec(ch_id, codec) != -1) { 2728 rinfo.bytes_rcvd = stats.bytes_rcvd;
2730 VoiceReceiverInfo rinfo; 2729 rinfo.packets_rcvd = stats.packets_rcvd;
2731 rinfo.add_ssrc(ssrc); 2730 rinfo.packets_lost = stats.packets_lost;
2732 rinfo.bytes_rcvd = cs.bytesReceived; 2731 rinfo.fraction_lost = stats.fraction_lost;
2733 rinfo.packets_rcvd = cs.packetsReceived; 2732 rinfo.codec_name = stats.codec_name;
2734 // The next four fields are from the most recently sent RTCP report. 2733 rinfo.ext_seqnum = stats.ext_seqnum;
2735 // Convert Q8 to floating point. 2734 rinfo.jitter_ms = stats.jitter_ms;
2736 rinfo.fraction_lost = static_cast<float>(cs.fractionLost) / (1 << 8); 2735 rinfo.jitter_buffer_ms = stats.jitter_buffer_ms;
2737 rinfo.packets_lost = cs.cumulativeLost; 2736 rinfo.jitter_buffer_preferred_ms = stats.jitter_buffer_preferred_ms;
2738 rinfo.ext_seqnum = cs.extendedMax; 2737 rinfo.delay_estimate_ms = stats.delay_estimate_ms;
2739 rinfo.capture_start_ntp_time_ms = cs.capture_start_ntp_time_ms_; 2738 rinfo.audio_level = stats.audio_level;
2740 if (codec.pltype != -1) { 2739 rinfo.expand_rate = stats.expand_rate;
2741 rinfo.codec_name = codec.plname; 2740 rinfo.speech_expand_rate = stats.speech_expand_rate;
2742 } 2741 rinfo.secondary_decoded_rate = stats.secondary_decoded_rate;
2743 // Convert samples to milliseconds. 2742 rinfo.accelerate_rate = stats.accelerate_rate;
2744 if (codec.plfreq / 1000 > 0) { 2743 rinfo.preemptive_expand_rate = stats.preemptive_expand_rate;
2745 rinfo.jitter_ms = cs.jitterSamples / (codec.plfreq / 1000); 2744 rinfo.decoding_calls_to_silence_generator =
2746 } 2745 stats.decoding_calls_to_silence_generator;
2747 2746 rinfo.decoding_calls_to_neteq = stats.decoding_calls_to_neteq;
2748 // Get jitter buffer and total delay (alg + jitter + playout) stats. 2747 rinfo.decoding_normal = stats.decoding_normal;
2749 webrtc::NetworkStatistics ns; 2748 rinfo.decoding_plc = stats.decoding_plc;
2750 if (engine()->voe()->neteq() && 2749 rinfo.decoding_cng = stats.decoding_cng;
2751 engine()->voe()->neteq()->GetNetworkStatistics( 2750 rinfo.decoding_plc_cng = stats.decoding_plc_cng;
2752 ch_id, ns) != -1) { 2751 rinfo.capture_start_ntp_time_ms = stats.capture_start_ntp_time_ms;
2753 rinfo.jitter_buffer_ms = ns.currentBufferSize; 2752 info->receivers.push_back(rinfo);
2754 rinfo.jitter_buffer_preferred_ms = ns.preferredBufferSize;
2755 rinfo.expand_rate =
2756 static_cast<float>(ns.currentExpandRate) / (1 << 14);
2757 rinfo.speech_expand_rate =
2758 static_cast<float>(ns.currentSpeechExpandRate) / (1 << 14);
2759 rinfo.secondary_decoded_rate =
2760 static_cast<float>(ns.currentSecondaryDecodedRate) / (1 << 14);
2761 rinfo.accelerate_rate =
2762 static_cast<float>(ns.currentAccelerateRate) / (1 << 14);
2763 rinfo.preemptive_expand_rate =
2764 static_cast<float>(ns.currentPreemptiveRate) / (1 << 14);
2765 }
2766
2767 webrtc::AudioDecodingCallStats ds;
2768 if (engine()->voe()->neteq() &&
2769 engine()->voe()->neteq()->GetDecodingCallStatistics(
2770 ch_id, &ds) != -1) {
2771 rinfo.decoding_calls_to_silence_generator =
2772 ds.calls_to_silence_generator;
2773 rinfo.decoding_calls_to_neteq = ds.calls_to_neteq;
2774 rinfo.decoding_normal = ds.decoded_normal;
2775 rinfo.decoding_plc = ds.decoded_plc;
2776 rinfo.decoding_cng = ds.decoded_cng;
2777 rinfo.decoding_plc_cng = ds.decoded_plc_cng;
2778 }
2779
2780 if (engine()->voe()->sync()) {
2781 int jitter_buffer_delay_ms = 0;
2782 int playout_buffer_delay_ms = 0;
2783 engine()->voe()->sync()->GetDelayEstimate(
2784 ch_id, &jitter_buffer_delay_ms, &playout_buffer_delay_ms);
2785 rinfo.delay_estimate_ms = jitter_buffer_delay_ms +
2786 playout_buffer_delay_ms;
2787 }
2788
2789 // Get speech level.
2790 rinfo.audio_level = (engine()->voe()->volume()->
2791 GetSpeechOutputLevelFullRange(ch_id, level) != -1) ? level : -1;
2792 info->receivers.push_back(rinfo);
2793 }
2794 } 2753 }
2795 2754
2796 return true; 2755 return true;
2797 } 2756 }
2798 2757
2799 void WebRtcVoiceMediaChannel::OnError(int error) { 2758 void WebRtcVoiceMediaChannel::OnError(int error) {
2800 if (send_ == SEND_NOTHING) { 2759 if (send_ == SEND_NOTHING) {
2801 return; 2760 return;
2802 } 2761 }
2803 if (error == VE_TYPING_NOISE_WARNING) { 2762 if (error == VE_TYPING_NOISE_WARNING) {
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
2995 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); 2954 LOG(LS_WARNING) << "Unknown codec " << ToString(codec);
2996 return false; 2955 return false;
2997 } 2956 }
2998 } 2957 }
2999 return true; 2958 return true;
3000 } 2959 }
3001 2960
3002 } // namespace cricket 2961 } // namespace cricket
3003 2962
3004 #endif // HAVE_WEBRTC_VOICE 2963 #endif // HAVE_WEBRTC_VOICE
OLDNEW
« no previous file with comments | « talk/media/webrtc/webrtcvoe.h ('k') | talk/media/webrtc/webrtcvoiceengine_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698