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 2631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 |
OLD | NEW |