• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/interface/logging.h"
16 
17 namespace webrtc {
18 
ToInternal(Packet * packet)19 void TimestampScaler::ToInternal(Packet* packet) {
20   if (!packet) {
21     return;
22   }
23   packet->header.timestamp = ToInternal(packet->header.timestamp,
24                                         packet->header.payloadType);
25 }
26 
ToInternal(PacketList * packet_list)27 void TimestampScaler::ToInternal(PacketList* packet_list) {
28   PacketList::iterator it;
29   for (it = packet_list->begin(); it != packet_list->end(); ++it) {
30     ToInternal(*it);
31   }
32 }
33 
ToInternal(uint32_t external_timestamp,uint8_t rtp_payload_type)34 uint32_t TimestampScaler::ToInternal(uint32_t external_timestamp,
35                                      uint8_t rtp_payload_type) {
36   const DecoderDatabase::DecoderInfo* info =
37       decoder_database_.GetDecoderInfo(rtp_payload_type);
38   if (!info) {
39     // Payload type is unknown. Do not scale.
40     return external_timestamp;
41   }
42   switch (info->codec_type) {
43     case kDecoderG722:
44     case kDecoderG722_2ch: {
45       // Use timestamp scaling with factor 2 (two output samples per RTP
46       // timestamp).
47       numerator_ = 2;
48       denominator_ = 1;
49       break;
50     }
51     case kDecoderOpus:
52     case kDecoderOpus_2ch:
53     case kDecoderISACfb:
54     case kDecoderCNGswb48kHz: {
55       // Use timestamp scaling with factor 2/3 (32 kHz sample rate, but RTP
56       // timestamps run on 48 kHz).
57       // TODO(tlegrand): Remove scaling for kDecoderCNGswb48kHz once ACM has
58       // full 48 kHz support.
59       numerator_ = 2;
60       denominator_ = 3;
61     }
62     case kDecoderAVT:
63     case kDecoderCNGnb:
64     case kDecoderCNGwb:
65     case kDecoderCNGswb32kHz: {
66       // Do not change the timestamp scaling settings for DTMF or CNG.
67       break;
68     }
69     default: {
70       // Do not use timestamp scaling for any other codec.
71       numerator_ = 1;
72       denominator_ = 1;
73       break;
74     }
75   }
76 
77   if (!(numerator_ == 1 && denominator_ == 1)) {
78     // We have a scale factor != 1.
79     if (!first_packet_received_) {
80       external_ref_ = external_timestamp;
81       internal_ref_ = external_timestamp;
82       first_packet_received_ = true;
83     }
84     int32_t external_diff = external_timestamp - external_ref_;
85     assert(denominator_ > 0);  // Should not be possible.
86     external_ref_ = external_timestamp;
87     internal_ref_ += (external_diff * numerator_) / denominator_;
88     LOG(LS_VERBOSE) << "Converting timestamp: " << external_timestamp <<
89         " -> " << internal_ref_;
90     return internal_ref_;
91   } else {
92     // No scaling.
93     return external_timestamp;
94   }
95 }
96 
97 
ToExternal(uint32_t internal_timestamp) const98 uint32_t TimestampScaler::ToExternal(uint32_t internal_timestamp) const {
99   if (!first_packet_received_ || (numerator_ == 1 && denominator_ == 1)) {
100     // Not initialized, or scale factor is 1.
101     return internal_timestamp;
102   } else {
103     int32_t internal_diff = internal_timestamp - internal_ref_;
104     assert(numerator_ > 0);  // Should not be possible.
105     // Do not update references in this method.
106     // Switch |denominator_| and |numerator_| to convert the other way.
107     return external_ref_ + (internal_diff * denominator_) / numerator_;
108   }
109 }
110 
111 }  // namespace webrtc
112