+void StreamStatisticianImpl::UpdateJitter(const RTPHeader& header,
+ uint32_t receive_time_secs,
+ uint32_t receive_time_frac) {
+ uint32_t receive_time_rtp = ModuleRTPUtility::ConvertNTPTimeToRTP(
+ receive_time_secs, receive_time_frac, header.payload_type_frequency);
+ uint32_t last_receive_time_rtp = ModuleRTPUtility::ConvertNTPTimeToRTP(
+ last_receive_time_secs_, last_receive_time_frac_,
+ header.payload_type_frequency);
+ int32_t time_diff_samples = (receive_time_rtp - last_receive_time_rtp) -
+ (header.timestamp - last_received_timestamp_);
+
+ time_diff_samples = abs(time_diff_samples);
+
+ // lib_jingle sometimes deliver crazy jumps in TS for the same stream.
+ // If this happens, don't update jitter value. Use 5 secs video frequency
+ // as the threshold.
+ if (time_diff_samples < 450000) {
+ // Note we calculate in Q4 to avoid using float.
+ int32_t jitter_diff_q4 = (time_diff_samples << 4) - jitter_q4_;
+ jitter_q4_ += ((jitter_diff_q4 + 8) >> 4);
+ }
+
+ // Extended jitter report, RFC 5450.
+ // Actual network jitter, excluding the source-introduced jitter.
+ int32_t time_diff_samples_ext =
+ (receive_time_rtp - last_receive_time_rtp) -
+ ((header.timestamp +
+ header.extension.transmissionTimeOffset) -
+ (last_received_timestamp_ +
+ last_received_transmission_time_offset_));
+
+ time_diff_samples_ext = abs(time_diff_samples_ext);
+
+ if (time_diff_samples_ext < 450000) {
+ int32_t jitter_diffQ4TransmissionTimeOffset =
+ (time_diff_samples_ext << 4) - jitter_q4_transmission_time_offset_;
+ jitter_q4_transmission_time_offset_ +=
+ ((jitter_diffQ4TransmissionTimeOffset + 8) >> 4);
+ }
+}
+
+void StreamStatisticianImpl::NotifyRtpCallback() {
+ StreamDataCounters data;
+ uint32_t ssrc;
+ {
+ CriticalSectionScoped cs(stream_lock_.get());
+ data = receive_counters_;
+ ssrc = ssrc_;
+ }
+ rtp_callback_->DataCountersUpdated(data, ssrc);
+}
+
+void StreamStatisticianImpl::NotifyRtcpCallback() {
+ RtcpStatistics data;
+ uint32_t ssrc;
+ {
+ CriticalSectionScoped cs(stream_lock_.get());
+ data = last_reported_statistics_;
+ ssrc = ssrc_;
+ }
+ rtcp_callback_->StatisticsUpdated(data, ssrc);
+}
+
+void StreamStatisticianImpl::FecPacketReceived() {
+ {
+ CriticalSectionScoped cs(stream_lock_.get());
+ ++receive_counters_.fec_packets;
+ }
+ NotifyRtpCallback();
+}
+