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

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

Issue 2326953003: Added a ParsePayload method to AudioDecoder. (Closed)
Patch Set: 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..308d0090e251213ac98ab2cb93b3974574f75344 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,74 @@ int NetEqImpl::InsertPacketInternal(const WebRtcRTPHeader& rtp_header,
receive_timestamp);
}
+ PacketList parsed_packet_list;
+ while (!packet_list.empty()) {
+ Packet* packet = packet_list.front();
kwiberg-webrtc 2016/09/10 07:34:59 unique_ptr?
ossu 2016/09/12 10:31:37 Acknowledged.
+ 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);
+ } else {
+ std::vector<AudioDecoder::ParseResult> results =
+ info->GetDecoder()->ParsePayload(&packet->payload,
+ packet->header.timestamp,
+ packet->primary);
+
+ // Reuse the packet if possible
+ if (results.size() == 1) {
+ auto& result = results[0];
+ RTC_DCHECK(result.frame);
+ packet->header.timestamp = result.timestamp;
+ packet->primary = result.primary;
+ packet->frame = std::move(result.frame);
+ parsed_packet_list.push_back(packet);
+ } else {
+ for (auto& result : results) {
+ // If you can't parse, return an empty list instead!
+ RTC_DCHECK(result.frame);
+ Packet* parsed_packet = new Packet;
kwiberg-webrtc 2016/09/10 07:34:59 unique_ptr?
ossu 2016/09/12 10:31:37 Acknowledged.
+ parsed_packet->header = packet->header;
+ parsed_packet->header.timestamp = result.timestamp;
+ // TODO(ossu): Move from primary to some sort of priority level.
+ parsed_packet->primary = result.primary;
+ parsed_packet->frame = std::move(result.frame);
+ parsed_packet_list.push_back(parsed_packet);
+ }
+
+ delete packet;
kwiberg-webrtc 2016/09/10 07:34:59 unique_ptr!
hlundin-webrtc 2016/09/15 08:12:16 FTW!
+ }
+ }
+ }
+
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 +1464,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 AudioDecoder::Frame::DecodeResult& 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 +1944,7 @@ int NetEqImpl::ExtractPackets(size_t required_samples,
}
stats_.PacketsDiscarded(discard_count);
stats_.StoreWaitingTime(packet->waiting_time->ElapsedMs());
- assert(!packet->payload.empty());
+ assert(packet->frame || !packet->payload.empty());
hlundin-webrtc 2016/09/09 12:11:50 Switch to DCHECK while you're at it.
ossu 2016/09/12 10:31:37 Acknowledged.
packet_list->push_back(packet); // Store packet in list.
if (first_packet) {
@@ -1925,27 +1961,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
hlundin-webrtc 2016/09/09 12:11:50 Good question.
ossu 2016/09/12 10:31:37 What does the SecondaryDecodedSamples stat mean? I
hlundin-webrtc 2016/09/15 08:12:16 It was added to track how often Opus FEC saved the
+ // 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_DCHECK(false);
kwiberg-webrtc 2016/09/10 07:34:59 RTC_NOTREACHED();
ossu 2016/09/12 10:31:37 Ah, yes, of course!
}
- 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