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

Side by Side Diff: webrtc/modules/audio_coding/acm2/acm_receiver.cc

Issue 2348123002: Revert of AcmReceiver: Look up last decoder in NetEq's table of decoders (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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 14 matching lines...) Expand all
25 #include "webrtc/modules/audio_coding/acm2/acm_resampler.h" 25 #include "webrtc/modules/audio_coding/acm2/acm_resampler.h"
26 #include "webrtc/modules/audio_coding/acm2/call_statistics.h" 26 #include "webrtc/modules/audio_coding/acm2/call_statistics.h"
27 #include "webrtc/modules/audio_coding/neteq/include/neteq.h" 27 #include "webrtc/modules/audio_coding/neteq/include/neteq.h"
28 #include "webrtc/system_wrappers/include/clock.h" 28 #include "webrtc/system_wrappers/include/clock.h"
29 #include "webrtc/system_wrappers/include/trace.h" 29 #include "webrtc/system_wrappers/include/trace.h"
30 30
31 namespace webrtc { 31 namespace webrtc {
32 32
33 namespace acm2 { 33 namespace acm2 {
34 34
35 namespace {
36
37 // Is the given codec a CNG codec?
38 // TODO(kwiberg): Move to RentACodec.
39 bool IsCng(int codec_id) {
40 auto i = RentACodec::CodecIdFromIndex(codec_id);
41 return (i && (*i == RentACodec::CodecId::kCNNB ||
42 *i == RentACodec::CodecId::kCNWB ||
43 *i == RentACodec::CodecId::kCNSWB ||
44 *i == RentACodec::CodecId::kCNFB));
45 }
46
47 } // namespace
48
35 AcmReceiver::AcmReceiver(const AudioCodingModule::Config& config) 49 AcmReceiver::AcmReceiver(const AudioCodingModule::Config& config)
36 : last_audio_buffer_(new int16_t[AudioFrame::kMaxDataSizeSamples]), 50 : last_audio_decoder_(nullptr),
51 last_audio_buffer_(new int16_t[AudioFrame::kMaxDataSizeSamples]),
37 neteq_(NetEq::Create(config.neteq_config, config.decoder_factory)), 52 neteq_(NetEq::Create(config.neteq_config, config.decoder_factory)),
38 clock_(config.clock), 53 clock_(config.clock),
39 resampled_last_output_frame_(true) { 54 resampled_last_output_frame_(true) {
40 assert(clock_); 55 assert(clock_);
41 memset(last_audio_buffer_.get(), 0, AudioFrame::kMaxDataSizeSamples); 56 memset(last_audio_buffer_.get(), 0, AudioFrame::kMaxDataSizeSamples);
42 } 57 }
43 58
44 AcmReceiver::~AcmReceiver() { 59 AcmReceiver::~AcmReceiver() {
45 delete neteq_; 60 delete neteq_;
46 } 61 }
(...skipping 26 matching lines...) Expand all
73 } 88 }
74 89
75 int AcmReceiver::InsertPacket(const WebRtcRTPHeader& rtp_header, 90 int AcmReceiver::InsertPacket(const WebRtcRTPHeader& rtp_header,
76 rtc::ArrayView<const uint8_t> incoming_payload) { 91 rtc::ArrayView<const uint8_t> incoming_payload) {
77 uint32_t receive_timestamp = 0; 92 uint32_t receive_timestamp = 0;
78 const RTPHeader* header = &rtp_header.header; // Just a shorthand. 93 const RTPHeader* header = &rtp_header.header; // Just a shorthand.
79 94
80 { 95 {
81 rtc::CritScope lock(&crit_sect_); 96 rtc::CritScope lock(&crit_sect_);
82 97
83 const rtc::Optional<CodecInst> ci = 98 const Decoder* decoder = RtpHeaderToDecoder(*header, incoming_payload[0]);
84 RtpHeaderToDecoder(*header, incoming_payload[0]); 99 if (!decoder) {
85 if (!ci) {
86 LOG_F(LS_ERROR) << "Payload-type " 100 LOG_F(LS_ERROR) << "Payload-type "
87 << static_cast<int>(header->payloadType) 101 << static_cast<int>(header->payloadType)
88 << " is not registered."; 102 << " is not registered.";
89 return -1; 103 return -1;
90 } 104 }
91 receive_timestamp = NowInTimestamp(ci->plfreq); 105 const int sample_rate_hz = [&decoder] {
106 const auto ci = RentACodec::CodecIdFromIndex(decoder->acm_codec_id);
107 return ci ? RentACodec::CodecInstById(*ci)->plfreq : -1;
108 }();
109 receive_timestamp = NowInTimestamp(sample_rate_hz);
92 110
93 if (STR_CASE_CMP(ci->plname, "cn") == 0) { 111 // If this is a CNG while the audio codec is not mono, skip pushing in
94 if (last_audio_decoder_ && last_audio_decoder_->channels > 1) { 112 // packets into NetEq.
95 // This is a CNG and the audio codec is not mono, so skip pushing in 113 if (IsCng(decoder->acm_codec_id) && last_audio_decoder_ &&
96 // packets into NetEq. 114 last_audio_decoder_->channels > 1)
97 return 0; 115 return 0;
98 } 116 if (!IsCng(decoder->acm_codec_id) &&
99 } else { 117 decoder->acm_codec_id !=
100 last_audio_decoder_ = ci; 118 *RentACodec::CodecIndexFromId(RentACodec::CodecId::kAVT)) {
101 last_packet_sample_rate_hz_ = rtc::Optional<int>(ci->plfreq); 119 last_audio_decoder_ = decoder;
120 last_packet_sample_rate_hz_ = rtc::Optional<int>(decoder->sample_rate_hz);
102 } 121 }
103 122
104 } // |crit_sect_| is released. 123 } // |crit_sect_| is released.
105 124
106 if (neteq_->InsertPacket(rtp_header, incoming_payload, receive_timestamp) < 125 if (neteq_->InsertPacket(rtp_header, incoming_payload, receive_timestamp) <
107 0) { 126 0) {
108 LOG(LERROR) << "AcmReceiver::InsertPacket " 127 LOG(LERROR) << "AcmReceiver::InsertPacket "
109 << static_cast<int>(header->payloadType) 128 << static_cast<int>(header->payloadType)
110 << " Failed to insert packet"; 129 << " Failed to insert packet";
111 return -1; 130 return -1;
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 if (neteq_->RemovePayloadType(cur->second.payload_type) == 0) { 275 if (neteq_->RemovePayloadType(cur->second.payload_type) == 0) {
257 decoders_.erase(cur); 276 decoders_.erase(cur);
258 } else { 277 } else {
259 LOG_F(LS_ERROR) << "Cannot remove payload " 278 LOG_F(LS_ERROR) << "Cannot remove payload "
260 << static_cast<int>(cur->second.payload_type); 279 << static_cast<int>(cur->second.payload_type);
261 ret_val = -1; 280 ret_val = -1;
262 } 281 }
263 } 282 }
264 283
265 // No codec is registered, invalidate last audio decoder. 284 // No codec is registered, invalidate last audio decoder.
266 last_audio_decoder_ = rtc::Optional<CodecInst>(); 285 last_audio_decoder_ = nullptr;
267 last_packet_sample_rate_hz_ = rtc::Optional<int>(); 286 last_packet_sample_rate_hz_ = rtc::Optional<int>();
268 return ret_val; 287 return ret_val;
269 } 288 }
270 289
271 int AcmReceiver::RemoveCodec(uint8_t payload_type) { 290 int AcmReceiver::RemoveCodec(uint8_t payload_type) {
272 rtc::CritScope lock(&crit_sect_); 291 rtc::CritScope lock(&crit_sect_);
273 auto it = decoders_.find(payload_type); 292 auto it = decoders_.find(payload_type);
274 if (it == decoders_.end()) { // Such a payload-type is not registered. 293 if (it == decoders_.end()) { // Such a payload-type is not registered.
275 return 0; 294 return 0;
276 } 295 }
277 if (neteq_->RemovePayloadType(payload_type) != NetEq::kOK) { 296 if (neteq_->RemovePayloadType(payload_type) != NetEq::kOK) {
278 LOG(LERROR) << "AcmReceiver::RemoveCodec" << static_cast<int>(payload_type); 297 LOG(LERROR) << "AcmReceiver::RemoveCodec" << static_cast<int>(payload_type);
279 return -1; 298 return -1;
280 } 299 }
281 if (last_audio_decoder_ && payload_type == last_audio_decoder_->pltype) { 300 if (last_audio_decoder_ == &it->second) {
282 last_audio_decoder_ = rtc::Optional<CodecInst>(); 301 last_audio_decoder_ = nullptr;
283 last_packet_sample_rate_hz_ = rtc::Optional<int>(); 302 last_packet_sample_rate_hz_ = rtc::Optional<int>();
284 } 303 }
285 decoders_.erase(it); 304 decoders_.erase(it);
286 return 0; 305 return 0;
287 } 306 }
288 307
289 rtc::Optional<uint32_t> AcmReceiver::GetPlayoutTimestamp() { 308 rtc::Optional<uint32_t> AcmReceiver::GetPlayoutTimestamp() {
290 return neteq_->GetPlayoutTimestamp(); 309 return neteq_->GetPlayoutTimestamp();
291 } 310 }
292 311
293 int AcmReceiver::FilteredCurrentDelayMs() const { 312 int AcmReceiver::FilteredCurrentDelayMs() const {
294 return neteq_->FilteredCurrentDelayMs(); 313 return neteq_->FilteredCurrentDelayMs();
295 } 314 }
296 315
297 int AcmReceiver::LastAudioCodec(CodecInst* codec) const { 316 int AcmReceiver::LastAudioCodec(CodecInst* codec) const {
298 rtc::CritScope lock(&crit_sect_); 317 rtc::CritScope lock(&crit_sect_);
299 if (!last_audio_decoder_) { 318 if (!last_audio_decoder_) {
300 return -1; 319 return -1;
301 } 320 }
302 *codec = *last_audio_decoder_; 321 *codec = *RentACodec::CodecInstById(
322 *RentACodec::CodecIdFromIndex(last_audio_decoder_->acm_codec_id));
323 codec->pltype = last_audio_decoder_->payload_type;
324 codec->channels = last_audio_decoder_->channels;
325 codec->plfreq = last_audio_decoder_->sample_rate_hz;
303 return 0; 326 return 0;
304 } 327 }
305 328
306 void AcmReceiver::GetNetworkStatistics(NetworkStatistics* acm_stat) { 329 void AcmReceiver::GetNetworkStatistics(NetworkStatistics* acm_stat) {
307 NetEqNetworkStatistics neteq_stat; 330 NetEqNetworkStatistics neteq_stat;
308 // NetEq function always returns zero, so we don't check the return value. 331 // NetEq function always returns zero, so we don't check the return value.
309 neteq_->NetworkStatistics(&neteq_stat); 332 neteq_->NetworkStatistics(&neteq_stat);
310 333
311 acm_stat->currentBufferSize = neteq_stat.current_buffer_size_ms; 334 acm_stat->currentBufferSize = neteq_stat.current_buffer_size_ms;
312 acm_stat->preferredBufferSize = neteq_stat.preferred_buffer_size_ms; 335 acm_stat->preferredBufferSize = neteq_stat.preferred_buffer_size_ms;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 std::vector<uint16_t> AcmReceiver::GetNackList( 379 std::vector<uint16_t> AcmReceiver::GetNackList(
357 int64_t round_trip_time_ms) const { 380 int64_t round_trip_time_ms) const {
358 return neteq_->GetNackList(round_trip_time_ms); 381 return neteq_->GetNackList(round_trip_time_ms);
359 } 382 }
360 383
361 void AcmReceiver::ResetInitialDelay() { 384 void AcmReceiver::ResetInitialDelay() {
362 neteq_->SetMinimumDelay(0); 385 neteq_->SetMinimumDelay(0);
363 // TODO(turajs): Should NetEq Buffer be flushed? 386 // TODO(turajs): Should NetEq Buffer be flushed?
364 } 387 }
365 388
366 const rtc::Optional<CodecInst> AcmReceiver::RtpHeaderToDecoder( 389 const AcmReceiver::Decoder* AcmReceiver::RtpHeaderToDecoder(
367 const RTPHeader& rtp_header, 390 const RTPHeader& rtp_header,
368 uint8_t payload_type) const { 391 uint8_t payload_type) const {
369 const rtc::Optional<CodecInst> ci = 392 auto it = decoders_.find(rtp_header.payloadType);
370 neteq_->GetDecoder(rtp_header.payloadType); 393 const auto red_index =
371 if (ci && STR_CASE_CMP(ci->plname, "red") == 0) { 394 RentACodec::CodecIndexFromId(RentACodec::CodecId::kRED);
372 // This is a RED packet. Get the payload of the audio codec. 395 if (red_index && // This ensures that RED is defined in WebRTC.
373 return neteq_->GetDecoder(payload_type & 0x7f); 396 it != decoders_.end() && it->second.acm_codec_id == *red_index) {
374 } else { 397 // This is a RED packet, get the payload of the audio codec.
375 return ci; 398 it = decoders_.find(payload_type & 0x7F);
376 } 399 }
400
401 // Check if the payload is registered.
402 return it != decoders_.end() ? &it->second : nullptr;
377 } 403 }
378 404
379 uint32_t AcmReceiver::NowInTimestamp(int decoder_sampling_rate) const { 405 uint32_t AcmReceiver::NowInTimestamp(int decoder_sampling_rate) const {
380 // Down-cast the time to (32-6)-bit since we only care about 406 // Down-cast the time to (32-6)-bit since we only care about
381 // the least significant bits. (32-6) bits cover 2^(32-6) = 67108864 ms. 407 // the least significant bits. (32-6) bits cover 2^(32-6) = 67108864 ms.
382 // We masked 6 most significant bits of 32-bit so there is no overflow in 408 // We masked 6 most significant bits of 32-bit so there is no overflow in
383 // the conversion from milliseconds to timestamp. 409 // the conversion from milliseconds to timestamp.
384 const uint32_t now_in_ms = static_cast<uint32_t>( 410 const uint32_t now_in_ms = static_cast<uint32_t>(
385 clock_->TimeInMilliseconds() & 0x03ffffff); 411 clock_->TimeInMilliseconds() & 0x03ffffff);
386 return static_cast<uint32_t>( 412 return static_cast<uint32_t>(
387 (decoder_sampling_rate / 1000) * now_in_ms); 413 (decoder_sampling_rate / 1000) * now_in_ms);
388 } 414 }
389 415
390 void AcmReceiver::GetDecodingCallStatistics( 416 void AcmReceiver::GetDecodingCallStatistics(
391 AudioDecodingCallStats* stats) const { 417 AudioDecodingCallStats* stats) const {
392 rtc::CritScope lock(&crit_sect_); 418 rtc::CritScope lock(&crit_sect_);
393 *stats = call_stats_.GetDecodingStatistics(); 419 *stats = call_stats_.GetDecodingStatistics();
394 } 420 }
395 421
396 } // namespace acm2 422 } // namespace acm2
397 423
398 } // namespace webrtc 424 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/audio_coding/acm2/acm_receiver.h ('k') | webrtc/modules/audio_coding/acm2/acm_receiver_unittest_oldapi.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698