/* * Copyright (c) 2013 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/decision_logic_fax.h" #include #include #include "webrtc/modules/audio_coding/neteq/decoder_database.h" #include "webrtc/modules/audio_coding/neteq/sync_buffer.h" namespace webrtc { Operations DecisionLogicFax::GetDecisionSpecialized( const SyncBuffer& sync_buffer, const Expand& expand, int decoder_frame_length, const RTPHeader* packet_header, Modes prev_mode, bool play_dtmf, bool* reset_decoder) { assert(playout_mode_ == kPlayoutFax || playout_mode_ == kPlayoutOff); uint32_t target_timestamp = sync_buffer.end_timestamp(); uint32_t available_timestamp = 0; int is_cng_packet = 0; if (packet_header) { available_timestamp = packet_header->timestamp; is_cng_packet = decoder_database_->IsComfortNoise(packet_header->payloadType); } if (is_cng_packet) { if (static_cast((generated_noise_samples_ + target_timestamp) - available_timestamp) >= 0) { // Time to play this packet now. return kRfc3389Cng; } else { // Wait before playing this packet. return kRfc3389CngNoPacket; } } if (!packet_header) { // No packet. If in CNG mode, play as usual. Otherwise, use other method to // generate data. if (cng_state_ == kCngRfc3389On) { // Continue playing comfort noise. return kRfc3389CngNoPacket; } else if (cng_state_ == kCngInternalOn) { // Continue playing codec-internal comfort noise. return kCodecInternalCng; } else { // Nothing to play. Generate some data to play out. switch (playout_mode_) { case kPlayoutOff: return kAlternativePlc; case kPlayoutFax: return kAudioRepetition; default: assert(false); return kUndefined; } } } else if (target_timestamp == available_timestamp) { return kNormal; } else { if (static_cast((generated_noise_samples_ + target_timestamp) - available_timestamp) >= 0) { return kNormal; } else { // If currently playing comfort noise, continue with that. Do not // increase the timestamp counter since generated_noise_samples_ will // be increased. if (cng_state_ == kCngRfc3389On) { return kRfc3389CngNoPacket; } else if (cng_state_ == kCngInternalOn) { return kCodecInternalCng; } else { // Otherwise, do packet-loss concealment and increase the // timestamp while waiting for the time to play this packet. switch (playout_mode_) { case kPlayoutOff: return kAlternativePlcIncreaseTimestamp; case kPlayoutFax: return kAudioRepetitionIncreaseTimestamp; default: assert(0); return kUndefined; } } } } } } // namespace webrtc