timestamp_scaler.cc (2986B)
1 /* 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "modules/audio_coding/neteq/timestamp_scaler.h" 12 13 #include <cstdint> 14 15 #include "api/audio_codecs/audio_format.h" 16 #include "modules/audio_coding/neteq/decoder_database.h" 17 #include "modules/audio_coding/neteq/packet.h" 18 #include "rtc_base/checks.h" 19 20 namespace webrtc { 21 22 void TimestampScaler::Reset() { 23 first_packet_received_ = false; 24 } 25 26 void TimestampScaler::ToInternal(Packet* packet) { 27 if (!packet) { 28 return; 29 } 30 packet->timestamp = ToInternal(packet->timestamp, packet->payload_type); 31 } 32 33 void TimestampScaler::ToInternal(PacketList* packet_list) { 34 PacketList::iterator it; 35 for (it = packet_list->begin(); it != packet_list->end(); ++it) { 36 ToInternal(&(*it)); 37 } 38 } 39 40 uint32_t TimestampScaler::ToInternal(uint32_t external_timestamp, 41 uint8_t rtp_payload_type) { 42 const DecoderDatabase::DecoderInfo* info = 43 decoder_database_.GetDecoderInfo(rtp_payload_type); 44 if (!info) { 45 // Payload type is unknown. Do not scale. 46 return external_timestamp; 47 } 48 if (!(info->IsComfortNoise() || info->IsDtmf())) { 49 // Do not change the timestamp scaling settings for DTMF or CNG. 50 numerator_ = info->SampleRateHz(); 51 if (info->GetFormat().clockrate_hz == 0) { 52 // If the clockrate is invalid (i.e. with an old-style external codec) 53 // we cannot do any timestamp scaling. 54 denominator_ = numerator_; 55 } else { 56 denominator_ = info->GetFormat().clockrate_hz; 57 } 58 } 59 if (numerator_ != denominator_) { 60 // We have a scale factor != 1. 61 if (!first_packet_received_) { 62 external_ref_ = external_timestamp; 63 internal_ref_ = external_timestamp; 64 first_packet_received_ = true; 65 } 66 const int64_t external_diff = int64_t{external_timestamp} - external_ref_; 67 RTC_DCHECK_GT(denominator_, 0); 68 external_ref_ = external_timestamp; 69 internal_ref_ += (external_diff * numerator_) / denominator_; 70 return internal_ref_; 71 } else { 72 // No scaling. 73 return external_timestamp; 74 } 75 } 76 77 uint32_t TimestampScaler::ToExternal(uint32_t internal_timestamp) const { 78 if (!first_packet_received_ || (numerator_ == denominator_)) { 79 // Not initialized, or scale factor is 1. 80 return internal_timestamp; 81 } else { 82 const int64_t internal_diff = int64_t{internal_timestamp} - internal_ref_; 83 RTC_DCHECK_GT(numerator_, 0); 84 // Do not update references in this method. 85 // Switch `denominator_` and `numerator_` to convert the other way. 86 return external_ref_ + (internal_diff * denominator_) / numerator_; 87 } 88 } 89 90 } // namespace webrtc