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 "webrtc/modules/audio_coding/neteq/timestamp_scaler.h" 12 13 #include "webrtc/modules/audio_coding/neteq/decoder_database.h" 14 #include "webrtc/modules/audio_coding/neteq/defines.h" 15 #include "webrtc/system_wrappers/include/logging.h" 16 17 namespace webrtc { 18 Reset()19void TimestampScaler::Reset() { 20 first_packet_received_ = false; 21 } 22 ToInternal(Packet * packet)23void TimestampScaler::ToInternal(Packet* packet) { 24 if (!packet) { 25 return; 26 } 27 packet->header.timestamp = ToInternal(packet->header.timestamp, 28 packet->header.payloadType); 29 } 30 ToInternal(PacketList * packet_list)31void TimestampScaler::ToInternal(PacketList* packet_list) { 32 PacketList::iterator it; 33 for (it = packet_list->begin(); it != packet_list->end(); ++it) { 34 ToInternal(*it); 35 } 36 } 37 ToInternal(uint32_t external_timestamp,uint8_t rtp_payload_type)38uint32_t TimestampScaler::ToInternal(uint32_t external_timestamp, 39 uint8_t rtp_payload_type) { 40 const DecoderDatabase::DecoderInfo* info = 41 decoder_database_.GetDecoderInfo(rtp_payload_type); 42 if (!info) { 43 // Payload type is unknown. Do not scale. 44 return external_timestamp; 45 } 46 switch (info->codec_type) { 47 case NetEqDecoder::kDecoderG722: 48 case NetEqDecoder::kDecoderG722_2ch: { 49 // Use timestamp scaling with factor 2 (two output samples per RTP 50 // timestamp). 51 numerator_ = 2; 52 denominator_ = 1; 53 break; 54 } 55 case NetEqDecoder::kDecoderAVT: 56 case NetEqDecoder::kDecoderCNGnb: 57 case NetEqDecoder::kDecoderCNGwb: 58 case NetEqDecoder::kDecoderCNGswb32kHz: 59 case NetEqDecoder::kDecoderCNGswb48kHz: { 60 // Do not change the timestamp scaling settings for DTMF or CNG. 61 break; 62 } 63 default: { 64 // Do not use timestamp scaling for any other codec. 65 numerator_ = 1; 66 denominator_ = 1; 67 break; 68 } 69 } 70 71 if (!(numerator_ == 1 && denominator_ == 1)) { 72 // We have a scale factor != 1. 73 if (!first_packet_received_) { 74 external_ref_ = external_timestamp; 75 internal_ref_ = external_timestamp; 76 first_packet_received_ = true; 77 } 78 int32_t external_diff = external_timestamp - external_ref_; 79 assert(denominator_ > 0); // Should not be possible. 80 external_ref_ = external_timestamp; 81 internal_ref_ += (external_diff * numerator_) / denominator_; 82 return internal_ref_; 83 } else { 84 // No scaling. 85 return external_timestamp; 86 } 87 } 88 89 ToExternal(uint32_t internal_timestamp) const90uint32_t TimestampScaler::ToExternal(uint32_t internal_timestamp) const { 91 if (!first_packet_received_ || (numerator_ == 1 && denominator_ == 1)) { 92 // Not initialized, or scale factor is 1. 93 return internal_timestamp; 94 } else { 95 int32_t internal_diff = internal_timestamp - internal_ref_; 96 assert(numerator_ > 0); // Should not be possible. 97 // Do not update references in this method. 98 // Switch |denominator_| and |numerator_| to convert the other way. 99 return external_ref_ + (internal_diff * denominator_) / numerator_; 100 } 101 } 102 103 } // namespace webrtc 104