Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 2676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2687 | 2687 |
| 2688 int median, std; | 2688 int median, std; |
| 2689 float dummy; | 2689 float dummy; |
| 2690 if (engine()->voe()->processing()->GetEcDelayMetrics( | 2690 if (engine()->voe()->processing()->GetEcDelayMetrics( |
| 2691 median, std, dummy) != -1) { | 2691 median, std, dummy) != -1) { |
| 2692 echo_delay_median_ms = median; | 2692 echo_delay_median_ms = median; |
| 2693 echo_delay_std_ms = std; | 2693 echo_delay_std_ms = std; |
| 2694 } | 2694 } |
| 2695 } | 2695 } |
| 2696 | 2696 |
| 2697 webrtc::CallStatistics cs; | |
| 2698 unsigned int ssrc; | |
| 2699 webrtc::CodecInst codec; | |
| 2700 unsigned int level; | |
| 2701 | |
| 2702 for (const auto& ch : send_channels_) { | 2697 for (const auto& ch : send_channels_) { |
| 2703 const int channel = ch.second->channel(); | 2698 const int channel = ch.second->channel(); |
| 2704 | 2699 |
| 2705 // Fill in the sender info, based on what we know, and what the | 2700 // Fill in the sender info, based on what we know, and what the |
| 2706 // remote side told us it got from its RTCP report. | 2701 // remote side told us it got from its RTCP report. |
| 2707 VoiceSenderInfo sinfo; | 2702 VoiceSenderInfo sinfo; |
| 2708 | 2703 |
| 2704 webrtc::CallStatistics cs = {0}; | |
| 2705 unsigned int ssrc = 0; | |
| 2709 if (engine()->voe()->rtp()->GetRTCPStatistics(channel, cs) == -1 || | 2706 if (engine()->voe()->rtp()->GetRTCPStatistics(channel, cs) == -1 || |
| 2710 engine()->voe()->rtp()->GetLocalSSRC(channel, ssrc) == -1) { | 2707 engine()->voe()->rtp()->GetLocalSSRC(channel, ssrc) == -1) { |
| 2711 continue; | 2708 continue; |
| 2712 } | 2709 } |
| 2713 | 2710 |
| 2714 sinfo.add_ssrc(ssrc); | 2711 sinfo.add_ssrc(ssrc); |
| 2715 sinfo.codec_name = send_codec_.get() ? send_codec_->plname : ""; | 2712 sinfo.codec_name = send_codec_.get() ? send_codec_->plname : ""; |
| 2716 sinfo.bytes_sent = cs.bytesSent; | 2713 sinfo.bytes_sent = cs.bytesSent; |
| 2717 sinfo.packets_sent = cs.packetsSent; | 2714 sinfo.packets_sent = cs.packetsSent; |
| 2718 // RTT isn't known until a RTCP report is received. Until then, VoiceEngine | 2715 // RTT isn't known until a RTCP report is received. Until then, VoiceEngine |
| 2719 // returns 0 to indicate an error value. | 2716 // returns 0 to indicate an error value. |
| 2720 sinfo.rtt_ms = (cs.rttMs > 0) ? cs.rttMs : -1; | 2717 sinfo.rtt_ms = (cs.rttMs > 0) ? cs.rttMs : -1; |
| 2721 | 2718 |
| 2722 // Get data from the last remote RTCP report. Use default values if no data | 2719 // Get data from the last remote RTCP report. Use default values if no data |
| 2723 // available. | 2720 // available. |
| 2724 sinfo.fraction_lost = -1.0; | 2721 sinfo.fraction_lost = -1.0; |
| 2725 sinfo.jitter_ms = -1; | 2722 sinfo.jitter_ms = -1; |
| 2726 sinfo.packets_lost = -1; | 2723 sinfo.packets_lost = -1; |
| 2727 sinfo.ext_seqnum = -1; | 2724 sinfo.ext_seqnum = -1; |
| 2728 std::vector<webrtc::ReportBlock> receive_blocks; | 2725 std::vector<webrtc::ReportBlock> receive_blocks; |
| 2726 webrtc::CodecInst codec = {0}; | |
| 2729 if (engine()->voe()->rtp()->GetRemoteRTCPReportBlocks( | 2727 if (engine()->voe()->rtp()->GetRemoteRTCPReportBlocks( |
| 2730 channel, &receive_blocks) != -1 && | 2728 channel, &receive_blocks) != -1 && |
| 2731 engine()->voe()->codec()->GetSendCodec(channel, codec) != -1) { | 2729 engine()->voe()->codec()->GetSendCodec(channel, codec) != -1) { |
| 2732 for (const webrtc::ReportBlock& block : receive_blocks) { | 2730 for (const webrtc::ReportBlock& block : receive_blocks) { |
| 2733 // Lookup report for send ssrc only. | 2731 // Lookup report for send ssrc only. |
| 2734 if (block.source_SSRC == sinfo.ssrc()) { | 2732 if (block.source_SSRC == sinfo.ssrc()) { |
| 2735 // Convert Q8 to floating point. | 2733 // Convert Q8 to floating point. |
| 2736 sinfo.fraction_lost = static_cast<float>(block.fraction_lost) / 256; | 2734 sinfo.fraction_lost = static_cast<float>(block.fraction_lost) / 256; |
| 2737 // Convert samples to milliseconds. | 2735 // Convert samples to milliseconds. |
| 2738 if (codec.plfreq / 1000 > 0) { | 2736 if (codec.plfreq / 1000 > 0) { |
| 2739 sinfo.jitter_ms = block.interarrival_jitter / (codec.plfreq / 1000); | 2737 sinfo.jitter_ms = block.interarrival_jitter / (codec.plfreq / 1000); |
| 2740 } | 2738 } |
| 2741 sinfo.packets_lost = block.cumulative_num_packets_lost; | 2739 sinfo.packets_lost = block.cumulative_num_packets_lost; |
| 2742 sinfo.ext_seqnum = block.extended_highest_sequence_number; | 2740 sinfo.ext_seqnum = block.extended_highest_sequence_number; |
| 2743 break; | 2741 break; |
| 2744 } | 2742 } |
| 2745 } | 2743 } |
| 2746 } | 2744 } |
| 2747 | 2745 |
| 2748 // Local speech level. | 2746 // Local speech level. |
| 2747 unsigned int level = 0; | |
| 2749 sinfo.audio_level = (engine()->voe()->volume()-> | 2748 sinfo.audio_level = (engine()->voe()->volume()-> |
| 2750 GetSpeechInputLevelFullRange(level) != -1) ? level : -1; | 2749 GetSpeechInputLevelFullRange(level) != -1) ? level : -1; |
| 2751 | 2750 |
| 2752 // TODO(xians): We are injecting the same APM logging to all the send | 2751 // TODO(xians): We are injecting the same APM logging to all the send |
| 2753 // channels here because there is no good way to know which send channel | 2752 // channels here because there is no good way to know which send channel |
| 2754 // is using the APM. The correct fix is to allow the send channels to have | 2753 // is using the APM. The correct fix is to allow the send channels to have |
| 2755 // their own APM so that we can feed the correct APM logging to different | 2754 // their own APM so that we can feed the correct APM logging to different |
| 2756 // send channels. See issue crbug/264611 . | 2755 // send channels. See issue crbug/264611 . |
| 2757 sinfo.echo_return_loss = echo_return_loss; | 2756 sinfo.echo_return_loss = echo_return_loss; |
| 2758 sinfo.echo_return_loss_enhancement = echo_return_loss_enhancement; | 2757 sinfo.echo_return_loss_enhancement = echo_return_loss_enhancement; |
| 2759 sinfo.echo_delay_median_ms = echo_delay_median_ms; | 2758 sinfo.echo_delay_median_ms = echo_delay_median_ms; |
| 2760 sinfo.echo_delay_std_ms = echo_delay_std_ms; | 2759 sinfo.echo_delay_std_ms = echo_delay_std_ms; |
| 2761 // TODO(ajm): Re-enable this metric once we have a reliable implementation. | 2760 // TODO(ajm): Re-enable this metric once we have a reliable implementation. |
| 2762 sinfo.aec_quality_min = -1; | 2761 sinfo.aec_quality_min = -1; |
| 2763 sinfo.typing_noise_detected = typing_noise_detected_; | 2762 sinfo.typing_noise_detected = typing_noise_detected_; |
| 2764 | 2763 |
| 2765 info->senders.push_back(sinfo); | 2764 info->senders.push_back(sinfo); |
| 2766 } | 2765 } |
| 2767 | 2766 |
| 2768 // Get the SSRC and stats for each receiver. | 2767 // Get the SSRC and stats for each receiver. |
| 2769 for (const auto& ch : receive_channels_) { | 2768 info->receivers.clear(); |
| 2770 int ch_id = ch.second->channel(); | 2769 for (const auto& stream : receive_streams_) { |
| 2771 memset(&cs, 0, sizeof(cs)); | 2770 webrtc::AudioReceiveStream::Stats stats = stream.second->GetStats(); |
| 2772 if (engine()->voe()->rtp()->GetRemoteSSRC(ch_id, ssrc) != -1 && | 2771 VoiceReceiverInfo rinfo; |
| 2773 engine()->voe()->rtp()->GetRTCPStatistics(ch_id, cs) != -1 && | 2772 rinfo.add_ssrc(stats.remote_ssrc); |
|
tommi
2015/10/19 12:36:24
What do you think about moving all this boiler pla
the sun
2015/10/19 14:25:01
You mean forcing VoiceReceiveInfo to know about th
tommi
2015/10/19 14:55:44
OK, sgtm. There are a lot of vars being set here s
the sun
2015/10/20 08:31:29
Acknowledged.
| |
| 2774 engine()->voe()->codec()->GetRecCodec(ch_id, codec) != -1) { | 2773 rinfo.bytes_rcvd = stats.bytes_rcvd; |
| 2775 VoiceReceiverInfo rinfo; | 2774 rinfo.packets_rcvd = stats.packets_rcvd; |
| 2776 rinfo.add_ssrc(ssrc); | 2775 rinfo.packets_lost = stats.packets_lost; |
| 2777 rinfo.bytes_rcvd = cs.bytesReceived; | 2776 rinfo.fraction_lost = stats.fraction_lost; |
| 2778 rinfo.packets_rcvd = cs.packetsReceived; | 2777 rinfo.codec_name = stats.codec_name; |
| 2779 // The next four fields are from the most recently sent RTCP report. | 2778 rinfo.ext_seqnum = stats.ext_seqnum; |
| 2780 // Convert Q8 to floating point. | 2779 rinfo.jitter_ms = stats.jitter_ms; |
| 2781 rinfo.fraction_lost = static_cast<float>(cs.fractionLost) / (1 << 8); | 2780 rinfo.jitter_buffer_ms = stats.jitter_buffer_ms; |
| 2782 rinfo.packets_lost = cs.cumulativeLost; | 2781 rinfo.jitter_buffer_preferred_ms = stats.jitter_buffer_preferred_ms; |
| 2783 rinfo.ext_seqnum = cs.extendedMax; | 2782 rinfo.delay_estimate_ms = stats.delay_estimate_ms; |
| 2784 rinfo.capture_start_ntp_time_ms = cs.capture_start_ntp_time_ms_; | 2783 rinfo.audio_level = stats.audio_level; |
| 2785 if (codec.pltype != -1) { | 2784 rinfo.expand_rate = stats.expand_rate; |
| 2786 rinfo.codec_name = codec.plname; | 2785 rinfo.speech_expand_rate = stats.speech_expand_rate; |
| 2787 } | 2786 rinfo.secondary_decoded_rate = stats.secondary_decoded_rate; |
| 2788 // Convert samples to milliseconds. | 2787 rinfo.accelerate_rate = stats.accelerate_rate; |
| 2789 if (codec.plfreq / 1000 > 0) { | 2788 rinfo.preemptive_expand_rate = stats.preemptive_expand_rate; |
| 2790 rinfo.jitter_ms = cs.jitterSamples / (codec.plfreq / 1000); | 2789 rinfo.decoding_calls_to_silence_generator = |
| 2791 } | 2790 stats.decoding_calls_to_silence_generator; |
| 2792 | 2791 rinfo.decoding_calls_to_neteq = stats.decoding_calls_to_neteq; |
| 2793 // Get jitter buffer and total delay (alg + jitter + playout) stats. | 2792 rinfo.decoding_normal = stats.decoding_normal; |
| 2794 webrtc::NetworkStatistics ns; | 2793 rinfo.decoding_plc = stats.decoding_plc; |
| 2795 if (engine()->voe()->neteq() && | 2794 rinfo.decoding_cng = stats.decoding_cng; |
| 2796 engine()->voe()->neteq()->GetNetworkStatistics( | 2795 rinfo.decoding_plc_cng = stats.decoding_plc_cng; |
| 2797 ch_id, ns) != -1) { | 2796 rinfo.capture_start_ntp_time_ms = stats.capture_start_ntp_time_ms; |
| 2798 rinfo.jitter_buffer_ms = ns.currentBufferSize; | 2797 info->receivers.push_back(rinfo); |
| 2799 rinfo.jitter_buffer_preferred_ms = ns.preferredBufferSize; | |
| 2800 rinfo.expand_rate = | |
| 2801 static_cast<float>(ns.currentExpandRate) / (1 << 14); | |
| 2802 rinfo.speech_expand_rate = | |
| 2803 static_cast<float>(ns.currentSpeechExpandRate) / (1 << 14); | |
| 2804 rinfo.secondary_decoded_rate = | |
| 2805 static_cast<float>(ns.currentSecondaryDecodedRate) / (1 << 14); | |
| 2806 rinfo.accelerate_rate = | |
| 2807 static_cast<float>(ns.currentAccelerateRate) / (1 << 14); | |
| 2808 rinfo.preemptive_expand_rate = | |
| 2809 static_cast<float>(ns.currentPreemptiveRate) / (1 << 14); | |
| 2810 } | |
| 2811 | |
| 2812 webrtc::AudioDecodingCallStats ds; | |
| 2813 if (engine()->voe()->neteq() && | |
| 2814 engine()->voe()->neteq()->GetDecodingCallStatistics( | |
| 2815 ch_id, &ds) != -1) { | |
| 2816 rinfo.decoding_calls_to_silence_generator = | |
| 2817 ds.calls_to_silence_generator; | |
| 2818 rinfo.decoding_calls_to_neteq = ds.calls_to_neteq; | |
| 2819 rinfo.decoding_normal = ds.decoded_normal; | |
| 2820 rinfo.decoding_plc = ds.decoded_plc; | |
| 2821 rinfo.decoding_cng = ds.decoded_cng; | |
| 2822 rinfo.decoding_plc_cng = ds.decoded_plc_cng; | |
| 2823 } | |
| 2824 | |
| 2825 if (engine()->voe()->sync()) { | |
| 2826 int jitter_buffer_delay_ms = 0; | |
| 2827 int playout_buffer_delay_ms = 0; | |
| 2828 engine()->voe()->sync()->GetDelayEstimate( | |
| 2829 ch_id, &jitter_buffer_delay_ms, &playout_buffer_delay_ms); | |
| 2830 rinfo.delay_estimate_ms = jitter_buffer_delay_ms + | |
| 2831 playout_buffer_delay_ms; | |
| 2832 } | |
| 2833 | |
| 2834 // Get speech level. | |
| 2835 rinfo.audio_level = (engine()->voe()->volume()-> | |
| 2836 GetSpeechOutputLevelFullRange(ch_id, level) != -1) ? level : -1; | |
| 2837 info->receivers.push_back(rinfo); | |
| 2838 } | |
| 2839 } | 2798 } |
| 2840 | 2799 |
| 2841 return true; | 2800 return true; |
| 2842 } | 2801 } |
| 2843 | 2802 |
| 2844 void WebRtcVoiceMediaChannel::OnError(int error) { | 2803 void WebRtcVoiceMediaChannel::OnError(int error) { |
| 2845 if (send_ == SEND_NOTHING) { | 2804 if (send_ == SEND_NOTHING) { |
| 2846 return; | 2805 return; |
| 2847 } | 2806 } |
| 2848 if (error == VE_TYPING_NOISE_WARNING) { | 2807 if (error == VE_TYPING_NOISE_WARNING) { |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3052 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); | 3011 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); |
| 3053 return false; | 3012 return false; |
| 3054 } | 3013 } |
| 3055 } | 3014 } |
| 3056 return true; | 3015 return true; |
| 3057 } | 3016 } |
| 3058 | 3017 |
| 3059 } // namespace cricket | 3018 } // namespace cricket |
| 3060 | 3019 |
| 3061 #endif // HAVE_WEBRTC_VOICE | 3020 #endif // HAVE_WEBRTC_VOICE |
| OLD | NEW |