ossu 7a3776102f Removed RTPHeader from NetEq's Packet struct.
Only three items in the (rather large) header were actually used after
InsertPacket: payloadType, timestamp and sequenceNumber. They are now
put directly into Packet. This saves 129 bytes per Packet that no
longer need to be allocated and deallocated.

This also works towards decoupling NetEq from RTP. As part of that,
I've moved the NACK code earlier in InsertPacketInternal, together
with other things that directly reference the RTPHeader.

BUG=webrtc:6549

Review-Url: https://codereview.webrtc.org/2411183003
Cr-Commit-Position: refs/heads/master@{#14658}
2016-10-18 11:06:19 +00:00

88 lines
2.9 KiB
C++

/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/modules/audio_coding/neteq/timestamp_scaler.h"
#include "webrtc/modules/audio_coding/neteq/decoder_database.h"
#include "webrtc/system_wrappers/include/logging.h"
namespace webrtc {
void TimestampScaler::Reset() {
first_packet_received_ = false;
}
void TimestampScaler::ToInternal(Packet* packet) {
if (!packet) {
return;
}
packet->timestamp = ToInternal(packet->timestamp, packet->payload_type);
}
void TimestampScaler::ToInternal(PacketList* packet_list) {
PacketList::iterator it;
for (it = packet_list->begin(); it != packet_list->end(); ++it) {
ToInternal(*it);
}
}
uint32_t TimestampScaler::ToInternal(uint32_t external_timestamp,
uint8_t rtp_payload_type) {
const DecoderDatabase::DecoderInfo* info =
decoder_database_.GetDecoderInfo(rtp_payload_type);
if (!info) {
// Payload type is unknown. Do not scale.
return external_timestamp;
}
if (!(info->IsComfortNoise() || info->IsDtmf())) {
// Do not change the timestamp scaling settings for DTMF or CNG.
numerator_ = info->SampleRateHz();
if (info->GetFormat().clockrate_hz == 0) {
// If the clockrate is invalid (i.e. with an old-style external codec)
// we cannot do any timestamp scaling.
denominator_ = numerator_;
} else {
denominator_ = info->GetFormat().clockrate_hz;
}
}
if (numerator_ != denominator_) {
// We have a scale factor != 1.
if (!first_packet_received_) {
external_ref_ = external_timestamp;
internal_ref_ = external_timestamp;
first_packet_received_ = true;
}
const int64_t external_diff = int64_t{external_timestamp} - external_ref_;
assert(denominator_ > 0); // Should not be possible.
external_ref_ = external_timestamp;
internal_ref_ += (external_diff * numerator_) / denominator_;
return internal_ref_;
} else {
// No scaling.
return external_timestamp;
}
}
uint32_t TimestampScaler::ToExternal(uint32_t internal_timestamp) const {
if (!first_packet_received_ || (numerator_ == denominator_)) {
// Not initialized, or scale factor is 1.
return internal_timestamp;
} else {
const int64_t internal_diff = int64_t{internal_timestamp} - internal_ref_;
assert(numerator_ > 0); // Should not be possible.
// Do not update references in this method.
// Switch |denominator_| and |numerator_| to convert the other way.
return external_ref_ + (internal_diff * denominator_) / numerator_;
}
}
} // namespace webrtc