Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Unified Diff: webrtc/modules/audio_coding/neteq/neteq_impl.cc

Issue 2326953003: Added a ParsePayload method to AudioDecoder. (Closed)
Patch Set: Clarifications. Cleanups. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webrtc/modules/audio_coding/neteq/neteq_impl.cc
diff --git a/webrtc/modules/audio_coding/neteq/neteq_impl.cc b/webrtc/modules/audio_coding/neteq/neteq_impl.cc
index 9c4f5809068f8964ef74882c0414f184ce37eef0..ac71ea8448cda54825ec5e9c8d7d74a58cb8b289 100644
--- a/webrtc/modules/audio_coding/neteq/neteq_impl.cc
+++ b/webrtc/modules/audio_coding/neteq/neteq_impl.cc
@@ -330,8 +330,7 @@ int NetEqImpl::CurrentDelayMs() const {
// Sum up the samples in the packet buffer with the future length of the sync
// buffer, and divide the sum by the sample rate.
const size_t delay_samples =
- packet_buffer_->NumSamplesInBuffer(decoder_database_.get(),
- decoder_frame_length_) +
+ packet_buffer_->NumSamplesInBuffer(decoder_frame_length_) +
sync_buffer_->FutureLength();
// The division below will truncate.
const int delay_ms =
@@ -376,8 +375,7 @@ int NetEqImpl::NetworkStatistics(NetEqNetworkStatistics* stats) {
rtc::CritScope lock(&crit_sect_);
assert(decoder_database_.get());
const size_t total_samples_in_buffers =
- packet_buffer_->NumSamplesInBuffer(decoder_database_.get(),
- decoder_frame_length_) +
+ packet_buffer_->NumSamplesInBuffer(decoder_frame_length_) +
sync_buffer_->FutureLength();
assert(delay_manager_.get());
assert(decision_logic_.get());
@@ -662,29 +660,64 @@ int NetEqImpl::InsertPacketInternal(const WebRtcRTPHeader& rtp_header,
receive_timestamp);
}
+ PacketList parsed_packet_list;
+ while (!packet_list.empty()) {
+ std::unique_ptr<Packet> packet(packet_list.front());
+ packet_list.pop_front();
+ const DecoderDatabase::DecoderInfo* info =
+ decoder_database_->GetDecoderInfo(packet->header.payloadType);
+ if (!info) {
+ LOG(LS_WARNING) << "SplitAudio unknown payload type";
+ return kUnknownRtpPayloadType;
+ }
+
+ if (info->IsComfortNoise()) {
+ // Carry comfort noise packets along.
+ parsed_packet_list.push_back(packet.release());
+ } else {
+ std::vector<AudioDecoder::ParseResult> results =
+ info->GetDecoder()->ParsePayload(std::move(packet->payload),
+ packet->header.timestamp,
+ packet->primary);
+ const RTPHeader& original_header = packet->header;
+ for (auto& result : results) {
+ RTC_DCHECK(result.frame);
+ // Reuse the packet if possible
+ if (!packet) {
+ packet.reset(new Packet);
+ packet->header = original_header;
+ }
kwiberg-webrtc 2016/09/16 00:14:07 If you reuse |packet| here, packet->payload will s
ossu 2016/09/16 11:24:16 I think it's best: it should not be touched after
kwiberg-webrtc 2016/09/16 11:37:19 Very good.
+ packet->header.timestamp = result.timestamp;
+ // TODO(ossu): Move from primary to some sort of priority level.
+ packet->primary = result.primary;
+ packet->frame = std::move(result.frame);
+ parsed_packet_list.push_back(packet.release());
+ }
+ }
+ }
+
if (nack_enabled_) {
RTC_DCHECK(nack_);
if (update_sample_rate_and_channels) {
nack_->Reset();
}
- nack_->UpdateLastReceivedPacket(packet_list.front()->header.sequenceNumber,
- packet_list.front()->header.timestamp);
+ nack_->UpdateLastReceivedPacket(
+ parsed_packet_list.front()->header.sequenceNumber,
+ parsed_packet_list.front()->header.timestamp);
}
// Insert packets in buffer.
const size_t buffer_length_before_insert =
packet_buffer_->NumPacketsInBuffer();
ret = packet_buffer_->InsertPacketList(
- &packet_list,
- *decoder_database_,
- &current_rtp_payload_type_,
+ &parsed_packet_list, *decoder_database_, &current_rtp_payload_type_,
&current_cng_rtp_payload_type_);
if (ret == PacketBuffer::kFlushed) {
// Reset DSP timestamp etc. if packet buffer flushed.
new_codec_ = true;
update_sample_rate_and_channels = true;
} else if (ret != PacketBuffer::kOK) {
- PacketBuffer::DeleteAllPackets(&packet_list);
+ PacketBuffer::DeleteAllPackets(&parsed_packet_list);
return kOtherError;
}
@@ -1421,31 +1454,24 @@ int NetEqImpl::DecodeLoop(PacketList* packet_list, const Operations& operation,
operation == kFastAccelerate || operation == kMerge ||
operation == kPreemptiveExpand);
packet_list->pop_front();
- const size_t payload_length = packet->payload.size();
- int decode_length;
- if (!packet->primary) {
- // This is a redundant payload; call the special decoder method.
- decode_length = decoder->DecodeRedundant(
- packet->payload.data(), packet->payload.size(), fs_hz_,
- (decoded_buffer_length_ - *decoded_length) * sizeof(int16_t),
- &decoded_buffer_[*decoded_length], speech_type);
- } else {
- decode_length = decoder->Decode(
- packet->payload.data(), packet->payload.size(), fs_hz_,
- (decoded_buffer_length_ - *decoded_length) * sizeof(int16_t),
- &decoded_buffer_[*decoded_length], speech_type);
- }
-
+ auto opt_result = packet->frame->Decode(
+ rtc::ArrayView<int16_t>(&decoded_buffer_[*decoded_length],
+ decoded_buffer_length_ - *decoded_length));
delete packet;
packet = NULL;
- if (decode_length > 0) {
- *decoded_length += decode_length;
- // Update |decoder_frame_length_| with number of samples per channel.
- decoder_frame_length_ =
- static_cast<size_t>(decode_length) / decoder->Channels();
- } else if (decode_length < 0) {
+ if (opt_result) {
+ const auto& result = *opt_result;
+ *speech_type = result.speech_type;
+ if (result.num_decoded_samples > 0) {
+ *decoded_length += result.num_decoded_samples;
+ // Update |decoder_frame_length_| with number of samples per channel.
+ decoder_frame_length_ =
+ result.num_decoded_samples / decoder->Channels();
+ }
+ } else {
// Error.
- LOG(LS_WARNING) << "Decode " << decode_length << " " << payload_length;
+ // TODO(ossu): What to put here?
+ LOG(LS_WARNING) << "Decode error";
*decoded_length = -1;
PacketBuffer::DeleteAllPackets(packet_list);
break;
@@ -1908,7 +1934,7 @@ int NetEqImpl::ExtractPackets(size_t required_samples,
}
stats_.PacketsDiscarded(discard_count);
stats_.StoreWaitingTime(packet->waiting_time->ElapsedMs());
- assert(!packet->payload.empty());
+ RTC_DCHECK(!packet->empty());
packet_list->push_back(packet); // Store packet in list.
if (first_packet) {
@@ -1925,27 +1951,24 @@ int NetEqImpl::ExtractPackets(size_t required_samples,
}
// Store number of extracted samples.
- int packet_duration = 0;
- AudioDecoder* decoder = decoder_database_->GetDecoder(
- packet->header.payloadType);
- if (decoder) {
- if (packet->primary) {
- packet_duration = decoder->PacketDuration(packet->payload.data(),
- packet->payload.size());
- } else {
- packet_duration = decoder->PacketDurationRedundant(
- packet->payload.data(), packet->payload.size());
+ size_t packet_duration = 0;
+ if (packet->frame) {
+ packet_duration = packet->frame->Duration();
+ // TODO(ossu): Is this the correct way to track samples decoded from a
+ // redundant packet?
+ if (packet_duration > 0 && !packet->primary) {
stats_.SecondaryDecodedSamples(packet_duration);
}
} else if (!decoder_database_->IsComfortNoise(packet->header.payloadType)) {
LOG(LS_WARNING) << "Unknown payload type "
<< static_cast<int>(packet->header.payloadType);
- assert(false);
+ RTC_NOTREACHED();
}
- if (packet_duration <= 0) {
+
+ if (packet_duration == 0) {
// Decoder did not return a packet duration. Assume that the packet
// contains the same number of samples as the previous one.
- packet_duration = rtc::checked_cast<int>(decoder_frame_length_);
+ packet_duration = decoder_frame_length_;
}
extracted_samples = packet->header.timestamp - first_timestamp +
packet_duration;

Powered by Google App Engine
This is Rietveld 408576698