Make FakeDecodeFromFile handle codec-internal CNG
This implementation interprets payloads of size 1 as codec-internal SID frames, marking the start of a CNG period. Changes were made to other parts of the test payload chain, since it had to make use of the virtual payload size in the case of header-only RTP files. BUG=webrtc:2692 Review-Url: https://codereview.webrtc.org/2275903002 Cr-Commit-Position: refs/heads/master@{#13901}
This commit is contained in:
committed by
Commit bot
parent
f02207dde9
commit
d1a10a0f77
@ -19,14 +19,37 @@ namespace test {
|
|||||||
|
|
||||||
int FakeDecodeFromFile::DecodeInternal(const uint8_t* encoded,
|
int FakeDecodeFromFile::DecodeInternal(const uint8_t* encoded,
|
||||||
size_t encoded_len,
|
size_t encoded_len,
|
||||||
int /*sample_rate_hz*/,
|
int sample_rate_hz,
|
||||||
int16_t* decoded,
|
int16_t* decoded,
|
||||||
SpeechType* speech_type) {
|
SpeechType* speech_type) {
|
||||||
RTC_CHECK_GE(encoded_len, 8u);
|
if (encoded_len == 0) {
|
||||||
|
// Decoder is asked to produce codec-internal comfort noise.
|
||||||
|
RTC_DCHECK(!encoded); // NetEq always sends nullptr in this case.
|
||||||
|
RTC_DCHECK(cng_mode_);
|
||||||
|
RTC_DCHECK_GT(last_decoded_length_, 0u);
|
||||||
|
std::fill_n(decoded, last_decoded_length_, 0);
|
||||||
|
*speech_type = kComfortNoise;
|
||||||
|
return last_decoded_length_;
|
||||||
|
}
|
||||||
|
|
||||||
|
RTC_CHECK_GE(encoded_len, 12u);
|
||||||
uint32_t timestamp_to_decode =
|
uint32_t timestamp_to_decode =
|
||||||
ByteReader<uint32_t>::ReadLittleEndian(encoded);
|
ByteReader<uint32_t>::ReadLittleEndian(encoded);
|
||||||
uint32_t samples_to_decode =
|
uint32_t samples_to_decode =
|
||||||
ByteReader<uint32_t>::ReadLittleEndian(&encoded[4]);
|
ByteReader<uint32_t>::ReadLittleEndian(&encoded[4]);
|
||||||
|
if (samples_to_decode == 0) {
|
||||||
|
// Number of samples in packet is unknown.
|
||||||
|
if (last_decoded_length_ > 0) {
|
||||||
|
// Use length of last decoded packet, but since this is the total for all
|
||||||
|
// channels, we have to divide by 2 in the stereo case.
|
||||||
|
samples_to_decode = rtc::CheckedDivExact(
|
||||||
|
last_decoded_length_, static_cast<size_t>(stereo_ ? 2uL : 1uL));
|
||||||
|
} else {
|
||||||
|
// This is the first packet to decode, and we do not know the length of
|
||||||
|
// it. Set it to 10 ms.
|
||||||
|
samples_to_decode = rtc::CheckedDivExact(sample_rate_hz, 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (next_timestamp_from_input_ &&
|
if (next_timestamp_from_input_ &&
|
||||||
timestamp_to_decode != *next_timestamp_from_input_) {
|
timestamp_to_decode != *next_timestamp_from_input_) {
|
||||||
@ -36,10 +59,23 @@ int FakeDecodeFromFile::DecodeInternal(const uint8_t* encoded,
|
|||||||
RTC_CHECK(input_->Seek(jump));
|
RTC_CHECK(input_->Seek(jump));
|
||||||
}
|
}
|
||||||
|
|
||||||
RTC_CHECK(input_->Read(static_cast<size_t>(samples_to_decode), decoded));
|
|
||||||
next_timestamp_from_input_ =
|
next_timestamp_from_input_ =
|
||||||
rtc::Optional<uint32_t>(timestamp_to_decode + samples_to_decode);
|
rtc::Optional<uint32_t>(timestamp_to_decode + samples_to_decode);
|
||||||
|
|
||||||
|
uint32_t original_payload_size_bytes =
|
||||||
|
ByteReader<uint32_t>::ReadLittleEndian(&encoded[8]);
|
||||||
|
if (original_payload_size_bytes == 1) {
|
||||||
|
// This is a comfort noise payload.
|
||||||
|
RTC_DCHECK_GT(last_decoded_length_, 0u);
|
||||||
|
std::fill_n(decoded, last_decoded_length_, 0);
|
||||||
|
*speech_type = kComfortNoise;
|
||||||
|
cng_mode_ = true;
|
||||||
|
return last_decoded_length_;
|
||||||
|
}
|
||||||
|
|
||||||
|
cng_mode_ = false;
|
||||||
|
RTC_CHECK(input_->Read(static_cast<size_t>(samples_to_decode), decoded));
|
||||||
|
|
||||||
if (stereo_) {
|
if (stereo_) {
|
||||||
InputAudioFile::DuplicateInterleaved(decoded, samples_to_decode, 2,
|
InputAudioFile::DuplicateInterleaved(decoded, samples_to_decode, 2,
|
||||||
decoded);
|
decoded);
|
||||||
@ -47,16 +83,19 @@ int FakeDecodeFromFile::DecodeInternal(const uint8_t* encoded,
|
|||||||
}
|
}
|
||||||
|
|
||||||
*speech_type = kSpeech;
|
*speech_type = kSpeech;
|
||||||
return samples_to_decode;
|
return last_decoded_length_ = samples_to_decode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeDecodeFromFile::PrepareEncoded(uint32_t timestamp,
|
void FakeDecodeFromFile::PrepareEncoded(uint32_t timestamp,
|
||||||
size_t samples,
|
size_t samples,
|
||||||
|
size_t original_payload_size_bytes,
|
||||||
rtc::ArrayView<uint8_t> encoded) {
|
rtc::ArrayView<uint8_t> encoded) {
|
||||||
RTC_CHECK_GE(encoded.size(), 8u);
|
RTC_CHECK_GE(encoded.size(), 12u);
|
||||||
ByteWriter<uint32_t>::WriteLittleEndian(&encoded[0], timestamp);
|
ByteWriter<uint32_t>::WriteLittleEndian(&encoded[0], timestamp);
|
||||||
ByteWriter<uint32_t>::WriteLittleEndian(&encoded[4],
|
ByteWriter<uint32_t>::WriteLittleEndian(&encoded[4],
|
||||||
rtc::checked_cast<uint32_t>(samples));
|
rtc::checked_cast<uint32_t>(samples));
|
||||||
|
ByteWriter<uint32_t>::WriteLittleEndian(
|
||||||
|
&encoded[8], rtc::checked_cast<uint32_t>(original_payload_size_bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace test
|
} // namespace test
|
||||||
|
|||||||
@ -50,11 +50,13 @@ class FakeDecodeFromFile : public AudioDecoder {
|
|||||||
int16_t* decoded,
|
int16_t* decoded,
|
||||||
SpeechType* speech_type) override;
|
SpeechType* speech_type) override;
|
||||||
|
|
||||||
// Helper method. Writes |timestamp| and |samples| to |encoded| in a format
|
// Helper method. Writes |timestamp|, |samples| and
|
||||||
// that the FakeDecpdeFromFile decoder will understand. |encoded| must be at
|
// |original_payload_size_bytes| to |encoded| in a format that the
|
||||||
// least 8 bytes long.
|
// FakeDecodeFromFile decoder will understand. |encoded| must be at least 12
|
||||||
|
// bytes long.
|
||||||
static void PrepareEncoded(uint32_t timestamp,
|
static void PrepareEncoded(uint32_t timestamp,
|
||||||
size_t samples,
|
size_t samples,
|
||||||
|
size_t original_payload_size_bytes,
|
||||||
rtc::ArrayView<uint8_t> encoded);
|
rtc::ArrayView<uint8_t> encoded);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -62,6 +64,8 @@ class FakeDecodeFromFile : public AudioDecoder {
|
|||||||
rtc::Optional<uint32_t> next_timestamp_from_input_;
|
rtc::Optional<uint32_t> next_timestamp_from_input_;
|
||||||
const int sample_rate_hz_;
|
const int sample_rate_hz_;
|
||||||
const bool stereo_;
|
const bool stereo_;
|
||||||
|
size_t last_decoded_length_ = 0;
|
||||||
|
bool cng_mode_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace test
|
} // namespace test
|
||||||
|
|||||||
@ -43,8 +43,16 @@ std::unique_ptr<NetEqInput::PacketData> NetEqPacketSourceInput::PopPacket() {
|
|||||||
}
|
}
|
||||||
std::unique_ptr<PacketData> packet_data(new PacketData);
|
std::unique_ptr<PacketData> packet_data(new PacketData);
|
||||||
packet_->ConvertHeader(&packet_data->header);
|
packet_->ConvertHeader(&packet_data->header);
|
||||||
|
if (packet_->payload_length_bytes() == 0 &&
|
||||||
|
packet_->virtual_payload_length_bytes() > 0) {
|
||||||
|
// This is a header-only "dummy" packet. Set the payload to all zeros, with
|
||||||
|
// length according to the virtual length.
|
||||||
|
packet_data->payload.SetSize(packet_->virtual_payload_length_bytes());
|
||||||
|
std::fill_n(packet_data->payload.data(), packet_data->payload.size(), 0);
|
||||||
|
} else {
|
||||||
packet_data->payload.SetData(packet_->payload(),
|
packet_data->payload.SetData(packet_->payload(),
|
||||||
packet_->payload_length_bytes());
|
packet_->payload_length_bytes());
|
||||||
|
}
|
||||||
packet_data->time_ms = packet_->time_ms();
|
packet_data->time_ms = packet_->time_ms();
|
||||||
|
|
||||||
LoadNextPacket();
|
LoadNextPacket();
|
||||||
|
|||||||
@ -84,11 +84,17 @@ void NetEqReplacementInput::ReplacePacket() {
|
|||||||
|
|
||||||
rtc::Optional<RTPHeader> next_hdr = source_->NextHeader();
|
rtc::Optional<RTPHeader> next_hdr = source_->NextHeader();
|
||||||
RTC_DCHECK(next_hdr);
|
RTC_DCHECK(next_hdr);
|
||||||
uint8_t payload[8];
|
uint8_t payload[12];
|
||||||
uint32_t input_frame_size_timestamps =
|
uint32_t input_frame_size_timestamps =
|
||||||
next_hdr->timestamp - packet_->header.header.timestamp;
|
next_hdr->timestamp - packet_->header.header.timestamp;
|
||||||
|
if (next_hdr->sequenceNumber != packet_->header.header.sequenceNumber + 1) {
|
||||||
|
// Gap in packet sequence. Cannot estimate payload length based on timestamp
|
||||||
|
// difference.
|
||||||
|
input_frame_size_timestamps = 0;
|
||||||
|
}
|
||||||
FakeDecodeFromFile::PrepareEncoded(packet_->header.header.timestamp,
|
FakeDecodeFromFile::PrepareEncoded(packet_->header.header.timestamp,
|
||||||
input_frame_size_timestamps, payload);
|
input_frame_size_timestamps,
|
||||||
|
packet_->payload.size(), payload);
|
||||||
packet_->payload.SetData(payload);
|
packet_->payload.SetData(payload);
|
||||||
packet_->header.header.payloadType = replacement_payload_type_;
|
packet_->header.header.payloadType = replacement_payload_type_;
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#include "webrtc/base/checks.h"
|
||||||
#include "webrtc/modules/include/module_common_types.h"
|
#include "webrtc/modules/include/module_common_types.h"
|
||||||
#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
|
#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
|
||||||
|
|
||||||
@ -142,6 +143,7 @@ bool Packet::ParseHeader(const RtpHeaderParser& parser) {
|
|||||||
payload_ = &payload_memory_[header_.headerLength];
|
payload_ = &payload_memory_[header_.headerLength];
|
||||||
assert(packet_length_bytes_ >= header_.headerLength);
|
assert(packet_length_bytes_ >= header_.headerLength);
|
||||||
payload_length_bytes_ = packet_length_bytes_ - header_.headerLength;
|
payload_length_bytes_ = packet_length_bytes_ - header_.headerLength;
|
||||||
|
RTC_CHECK_GE(virtual_packet_length_bytes_, packet_length_bytes_);
|
||||||
assert(virtual_packet_length_bytes_ >= header_.headerLength);
|
assert(virtual_packet_length_bytes_ >= header_.headerLength);
|
||||||
virtual_payload_length_bytes_ =
|
virtual_payload_length_bytes_ =
|
||||||
virtual_packet_length_bytes_ - header_.headerLength;
|
virtual_packet_length_bytes_ - header_.headerLength;
|
||||||
|
|||||||
Reference in New Issue
Block a user