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 2607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2618 | 2618 |
2619 int median, std; | 2619 int median, std; |
2620 float dummy; | 2620 float dummy; |
2621 if (engine()->voe()->processing()->GetEcDelayMetrics( | 2621 if (engine()->voe()->processing()->GetEcDelayMetrics( |
2622 median, std, dummy) != -1) { | 2622 median, std, dummy) != -1) { |
2623 echo_delay_median_ms = median; | 2623 echo_delay_median_ms = median; |
2624 echo_delay_std_ms = std; | 2624 echo_delay_std_ms = std; |
2625 } | 2625 } |
2626 } | 2626 } |
2627 | 2627 |
2628 webrtc::CallStatistics cs; | |
2629 unsigned int ssrc; | |
2630 webrtc::CodecInst codec; | |
2631 unsigned int level; | |
2632 | |
2633 for (const auto& ch : send_channels_) { | 2628 for (const auto& ch : send_channels_) { |
2634 const int channel = ch.second->channel(); | 2629 const int channel = ch.second->channel(); |
2635 | 2630 |
2636 // Fill in the sender info, based on what we know, and what the | 2631 // Fill in the sender info, based on what we know, and what the |
2637 // remote side told us it got from its RTCP report. | 2632 // remote side told us it got from its RTCP report. |
2638 VoiceSenderInfo sinfo; | 2633 VoiceSenderInfo sinfo; |
2639 | 2634 |
| 2635 webrtc::CallStatistics cs = {0}; |
| 2636 unsigned int ssrc = 0; |
2640 if (engine()->voe()->rtp()->GetRTCPStatistics(channel, cs) == -1 || | 2637 if (engine()->voe()->rtp()->GetRTCPStatistics(channel, cs) == -1 || |
2641 engine()->voe()->rtp()->GetLocalSSRC(channel, ssrc) == -1) { | 2638 engine()->voe()->rtp()->GetLocalSSRC(channel, ssrc) == -1) { |
2642 continue; | 2639 continue; |
2643 } | 2640 } |
2644 | 2641 |
2645 sinfo.add_ssrc(ssrc); | 2642 sinfo.add_ssrc(ssrc); |
2646 sinfo.codec_name = send_codec_.get() ? send_codec_->plname : ""; | 2643 sinfo.codec_name = send_codec_.get() ? send_codec_->plname : ""; |
2647 sinfo.bytes_sent = cs.bytesSent; | 2644 sinfo.bytes_sent = cs.bytesSent; |
2648 sinfo.packets_sent = cs.packetsSent; | 2645 sinfo.packets_sent = cs.packetsSent; |
2649 // RTT isn't known until a RTCP report is received. Until then, VoiceEngine | 2646 // RTT isn't known until a RTCP report is received. Until then, VoiceEngine |
2650 // returns 0 to indicate an error value. | 2647 // returns 0 to indicate an error value. |
2651 sinfo.rtt_ms = (cs.rttMs > 0) ? cs.rttMs : -1; | 2648 sinfo.rtt_ms = (cs.rttMs > 0) ? cs.rttMs : -1; |
2652 | 2649 |
2653 // Get data from the last remote RTCP report. Use default values if no data | 2650 // Get data from the last remote RTCP report. Use default values if no data |
2654 // available. | 2651 // available. |
2655 sinfo.fraction_lost = -1.0; | 2652 sinfo.fraction_lost = -1.0; |
2656 sinfo.jitter_ms = -1; | 2653 sinfo.jitter_ms = -1; |
2657 sinfo.packets_lost = -1; | 2654 sinfo.packets_lost = -1; |
2658 sinfo.ext_seqnum = -1; | 2655 sinfo.ext_seqnum = -1; |
2659 std::vector<webrtc::ReportBlock> receive_blocks; | 2656 std::vector<webrtc::ReportBlock> receive_blocks; |
| 2657 webrtc::CodecInst codec = {0}; |
2660 if (engine()->voe()->rtp()->GetRemoteRTCPReportBlocks( | 2658 if (engine()->voe()->rtp()->GetRemoteRTCPReportBlocks( |
2661 channel, &receive_blocks) != -1 && | 2659 channel, &receive_blocks) != -1 && |
2662 engine()->voe()->codec()->GetSendCodec(channel, codec) != -1) { | 2660 engine()->voe()->codec()->GetSendCodec(channel, codec) != -1) { |
2663 for (const webrtc::ReportBlock& block : receive_blocks) { | 2661 for (const webrtc::ReportBlock& block : receive_blocks) { |
2664 // Lookup report for send ssrc only. | 2662 // Lookup report for send ssrc only. |
2665 if (block.source_SSRC == sinfo.ssrc()) { | 2663 if (block.source_SSRC == sinfo.ssrc()) { |
2666 // Convert Q8 to floating point. | 2664 // Convert Q8 to floating point. |
2667 sinfo.fraction_lost = static_cast<float>(block.fraction_lost) / 256; | 2665 sinfo.fraction_lost = static_cast<float>(block.fraction_lost) / 256; |
2668 // Convert samples to milliseconds. | 2666 // Convert samples to milliseconds. |
2669 if (codec.plfreq / 1000 > 0) { | 2667 if (codec.plfreq / 1000 > 0) { |
2670 sinfo.jitter_ms = block.interarrival_jitter / (codec.plfreq / 1000); | 2668 sinfo.jitter_ms = block.interarrival_jitter / (codec.plfreq / 1000); |
2671 } | 2669 } |
2672 sinfo.packets_lost = block.cumulative_num_packets_lost; | 2670 sinfo.packets_lost = block.cumulative_num_packets_lost; |
2673 sinfo.ext_seqnum = block.extended_highest_sequence_number; | 2671 sinfo.ext_seqnum = block.extended_highest_sequence_number; |
2674 break; | 2672 break; |
2675 } | 2673 } |
2676 } | 2674 } |
2677 } | 2675 } |
2678 | 2676 |
2679 // Local speech level. | 2677 // Local speech level. |
| 2678 unsigned int level = 0; |
2680 sinfo.audio_level = (engine()->voe()->volume()-> | 2679 sinfo.audio_level = (engine()->voe()->volume()-> |
2681 GetSpeechInputLevelFullRange(level) != -1) ? level : -1; | 2680 GetSpeechInputLevelFullRange(level) != -1) ? level : -1; |
2682 | 2681 |
2683 // TODO(xians): We are injecting the same APM logging to all the send | 2682 // TODO(xians): We are injecting the same APM logging to all the send |
2684 // channels here because there is no good way to know which send channel | 2683 // channels here because there is no good way to know which send channel |
2685 // is using the APM. The correct fix is to allow the send channels to have | 2684 // is using the APM. The correct fix is to allow the send channels to have |
2686 // their own APM so that we can feed the correct APM logging to different | 2685 // their own APM so that we can feed the correct APM logging to different |
2687 // send channels. See issue crbug/264611 . | 2686 // send channels. See issue crbug/264611 . |
2688 sinfo.echo_return_loss = echo_return_loss; | 2687 sinfo.echo_return_loss = echo_return_loss; |
2689 sinfo.echo_return_loss_enhancement = echo_return_loss_enhancement; | 2688 sinfo.echo_return_loss_enhancement = echo_return_loss_enhancement; |
2690 sinfo.echo_delay_median_ms = echo_delay_median_ms; | 2689 sinfo.echo_delay_median_ms = echo_delay_median_ms; |
2691 sinfo.echo_delay_std_ms = echo_delay_std_ms; | 2690 sinfo.echo_delay_std_ms = echo_delay_std_ms; |
2692 // TODO(ajm): Re-enable this metric once we have a reliable implementation. | 2691 // TODO(ajm): Re-enable this metric once we have a reliable implementation. |
2693 sinfo.aec_quality_min = -1; | 2692 sinfo.aec_quality_min = -1; |
2694 sinfo.typing_noise_detected = typing_noise_detected_; | 2693 sinfo.typing_noise_detected = typing_noise_detected_; |
2695 | 2694 |
2696 info->senders.push_back(sinfo); | 2695 info->senders.push_back(sinfo); |
2697 } | 2696 } |
2698 | 2697 |
2699 // Get the SSRC and stats for each receiver. | 2698 // Get the SSRC and stats for each receiver. |
2700 for (const auto& ch : receive_channels_) { | 2699 info->receivers.clear(); |
2701 int ch_id = ch.second->channel(); | 2700 for (const auto& stream : receive_streams_) { |
2702 memset(&cs, 0, sizeof(cs)); | 2701 webrtc::AudioReceiveStream::Stats stats = stream.second->GetStats(); |
2703 if (engine()->voe()->rtp()->GetRemoteSSRC(ch_id, ssrc) != -1 && | 2702 VoiceReceiverInfo rinfo; |
2704 engine()->voe()->rtp()->GetRTCPStatistics(ch_id, cs) != -1 && | 2703 rinfo.add_ssrc(stats.remote_ssrc); |
2705 engine()->voe()->codec()->GetRecCodec(ch_id, codec) != -1) { | 2704 rinfo.bytes_rcvd = stats.bytes_rcvd; |
2706 VoiceReceiverInfo rinfo; | 2705 rinfo.packets_rcvd = stats.packets_rcvd; |
2707 rinfo.add_ssrc(ssrc); | 2706 rinfo.packets_lost = stats.packets_lost; |
2708 rinfo.bytes_rcvd = cs.bytesReceived; | 2707 rinfo.fraction_lost = stats.fraction_lost; |
2709 rinfo.packets_rcvd = cs.packetsReceived; | 2708 rinfo.codec_name = stats.codec_name; |
2710 // The next four fields are from the most recently sent RTCP report. | 2709 rinfo.ext_seqnum = stats.ext_seqnum; |
2711 // Convert Q8 to floating point. | 2710 rinfo.jitter_ms = stats.jitter_ms; |
2712 rinfo.fraction_lost = static_cast<float>(cs.fractionLost) / (1 << 8); | 2711 rinfo.jitter_buffer_ms = stats.jitter_buffer_ms; |
2713 rinfo.packets_lost = cs.cumulativeLost; | 2712 rinfo.jitter_buffer_preferred_ms = stats.jitter_buffer_preferred_ms; |
2714 rinfo.ext_seqnum = cs.extendedMax; | 2713 rinfo.delay_estimate_ms = stats.delay_estimate_ms; |
2715 rinfo.capture_start_ntp_time_ms = cs.capture_start_ntp_time_ms_; | 2714 rinfo.audio_level = stats.audio_level; |
2716 if (codec.pltype != -1) { | 2715 rinfo.expand_rate = stats.expand_rate; |
2717 rinfo.codec_name = codec.plname; | 2716 rinfo.speech_expand_rate = stats.speech_expand_rate; |
2718 } | 2717 rinfo.secondary_decoded_rate = stats.secondary_decoded_rate; |
2719 // Convert samples to milliseconds. | 2718 rinfo.accelerate_rate = stats.accelerate_rate; |
2720 if (codec.plfreq / 1000 > 0) { | 2719 rinfo.preemptive_expand_rate = stats.preemptive_expand_rate; |
2721 rinfo.jitter_ms = cs.jitterSamples / (codec.plfreq / 1000); | 2720 rinfo.decoding_calls_to_silence_generator = |
2722 } | 2721 stats.decoding_calls_to_silence_generator; |
2723 | 2722 rinfo.decoding_calls_to_neteq = stats.decoding_calls_to_neteq; |
2724 // Get jitter buffer and total delay (alg + jitter + playout) stats. | 2723 rinfo.decoding_normal = stats.decoding_normal; |
2725 webrtc::NetworkStatistics ns; | 2724 rinfo.decoding_plc = stats.decoding_plc; |
2726 if (engine()->voe()->neteq() && | 2725 rinfo.decoding_cng = stats.decoding_cng; |
2727 engine()->voe()->neteq()->GetNetworkStatistics( | 2726 rinfo.decoding_plc_cng = stats.decoding_plc_cng; |
2728 ch_id, ns) != -1) { | 2727 rinfo.capture_start_ntp_time_ms = stats.capture_start_ntp_time_ms; |
2729 rinfo.jitter_buffer_ms = ns.currentBufferSize; | 2728 info->receivers.push_back(rinfo); |
2730 rinfo.jitter_buffer_preferred_ms = ns.preferredBufferSize; | |
2731 rinfo.expand_rate = | |
2732 static_cast<float>(ns.currentExpandRate) / (1 << 14); | |
2733 rinfo.speech_expand_rate = | |
2734 static_cast<float>(ns.currentSpeechExpandRate) / (1 << 14); | |
2735 rinfo.secondary_decoded_rate = | |
2736 static_cast<float>(ns.currentSecondaryDecodedRate) / (1 << 14); | |
2737 rinfo.accelerate_rate = | |
2738 static_cast<float>(ns.currentAccelerateRate) / (1 << 14); | |
2739 rinfo.preemptive_expand_rate = | |
2740 static_cast<float>(ns.currentPreemptiveRate) / (1 << 14); | |
2741 } | |
2742 | |
2743 webrtc::AudioDecodingCallStats ds; | |
2744 if (engine()->voe()->neteq() && | |
2745 engine()->voe()->neteq()->GetDecodingCallStatistics( | |
2746 ch_id, &ds) != -1) { | |
2747 rinfo.decoding_calls_to_silence_generator = | |
2748 ds.calls_to_silence_generator; | |
2749 rinfo.decoding_calls_to_neteq = ds.calls_to_neteq; | |
2750 rinfo.decoding_normal = ds.decoded_normal; | |
2751 rinfo.decoding_plc = ds.decoded_plc; | |
2752 rinfo.decoding_cng = ds.decoded_cng; | |
2753 rinfo.decoding_plc_cng = ds.decoded_plc_cng; | |
2754 } | |
2755 | |
2756 if (engine()->voe()->sync()) { | |
2757 int jitter_buffer_delay_ms = 0; | |
2758 int playout_buffer_delay_ms = 0; | |
2759 engine()->voe()->sync()->GetDelayEstimate( | |
2760 ch_id, &jitter_buffer_delay_ms, &playout_buffer_delay_ms); | |
2761 rinfo.delay_estimate_ms = jitter_buffer_delay_ms + | |
2762 playout_buffer_delay_ms; | |
2763 } | |
2764 | |
2765 // Get speech level. | |
2766 rinfo.audio_level = (engine()->voe()->volume()-> | |
2767 GetSpeechOutputLevelFullRange(ch_id, level) != -1) ? level : -1; | |
2768 info->receivers.push_back(rinfo); | |
2769 } | |
2770 } | 2729 } |
2771 | 2730 |
2772 return true; | 2731 return true; |
2773 } | 2732 } |
2774 | 2733 |
2775 void WebRtcVoiceMediaChannel::OnError(int error) { | 2734 void WebRtcVoiceMediaChannel::OnError(int error) { |
2776 if (send_ == SEND_NOTHING) { | 2735 if (send_ == SEND_NOTHING) { |
2777 return; | 2736 return; |
2778 } | 2737 } |
2779 if (error == VE_TYPING_NOISE_WARNING) { | 2738 if (error == VE_TYPING_NOISE_WARNING) { |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2971 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); | 2930 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); |
2972 return false; | 2931 return false; |
2973 } | 2932 } |
2974 } | 2933 } |
2975 return true; | 2934 return true; |
2976 } | 2935 } |
2977 | 2936 |
2978 } // namespace cricket | 2937 } // namespace cricket |
2979 | 2938 |
2980 #endif // HAVE_WEBRTC_VOICE | 2939 #endif // HAVE_WEBRTC_VOICE |
OLD | NEW |