LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/modules/audio_coding/neteq - decision_logic_normal.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 93 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 9 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
       3             :  *
       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
       6             :  *  tree. An additional intellectual property rights grant can be found
       7             :  *  in the file PATENTS.  All contributing project authors may
       8             :  *  be found in the AUTHORS file in the root of the source tree.
       9             :  */
      10             : 
      11             : #include "webrtc/modules/audio_coding/neteq/decision_logic_normal.h"
      12             : 
      13             : #include <assert.h>
      14             : 
      15             : #include <algorithm>
      16             : 
      17             : #include "webrtc/modules/audio_coding/neteq/buffer_level_filter.h"
      18             : #include "webrtc/modules/audio_coding/neteq/decoder_database.h"
      19             : #include "webrtc/modules/audio_coding/neteq/delay_manager.h"
      20             : #include "webrtc/modules/audio_coding/neteq/expand.h"
      21             : #include "webrtc/modules/audio_coding/neteq/packet_buffer.h"
      22             : #include "webrtc/modules/audio_coding/neteq/sync_buffer.h"
      23             : #include "webrtc/modules/include/module_common_types.h"
      24             : 
      25             : namespace webrtc {
      26             : 
      27           0 : Operations DecisionLogicNormal::GetDecisionSpecialized(
      28             :     const SyncBuffer& sync_buffer,
      29             :     const Expand& expand,
      30             :     size_t decoder_frame_length,
      31             :     const Packet* next_packet,
      32             :     Modes prev_mode,
      33             :     bool play_dtmf,
      34             :     bool* reset_decoder,
      35             :     size_t generated_noise_samples) {
      36           0 :   assert(playout_mode_ == kPlayoutOn || playout_mode_ == kPlayoutStreaming);
      37             :   // Guard for errors, to avoid getting stuck in error mode.
      38           0 :   if (prev_mode == kModeError) {
      39           0 :     if (!next_packet) {
      40           0 :       return kExpand;
      41             :     } else {
      42           0 :       return kUndefined;  // Use kUndefined to flag for a reset.
      43             :     }
      44             :   }
      45             : 
      46           0 :   uint32_t target_timestamp = sync_buffer.end_timestamp();
      47           0 :   uint32_t available_timestamp = 0;
      48           0 :   bool is_cng_packet = false;
      49           0 :   if (next_packet) {
      50           0 :     available_timestamp = next_packet->timestamp;
      51             :     is_cng_packet =
      52           0 :         decoder_database_->IsComfortNoise(next_packet->payload_type);
      53             :   }
      54             : 
      55           0 :   if (is_cng_packet) {
      56             :     return CngOperation(prev_mode, target_timestamp, available_timestamp,
      57           0 :                         generated_noise_samples);
      58             :   }
      59             : 
      60             :   // Handle the case with no packet at all available (except maybe DTMF).
      61           0 :   if (!next_packet) {
      62           0 :     return NoPacket(play_dtmf);
      63             :   }
      64             : 
      65             :   // If the expand period was very long, reset NetEQ since it is likely that the
      66             :   // sender was restarted.
      67           0 :   if (num_consecutive_expands_ > kReinitAfterExpands) {
      68           0 :     *reset_decoder = true;
      69           0 :     return kNormal;
      70             :   }
      71             : 
      72             :   const uint32_t five_seconds_samples =
      73           0 :       static_cast<uint32_t>(5 * 8000 * fs_mult_);
      74             :   // Check if the required packet is available.
      75           0 :   if (target_timestamp == available_timestamp) {
      76           0 :     return ExpectedPacketAvailable(prev_mode, play_dtmf);
      77           0 :   } else if (!PacketBuffer::IsObsoleteTimestamp(
      78             :                  available_timestamp, target_timestamp, five_seconds_samples)) {
      79           0 :     return FuturePacketAvailable(sync_buffer, expand, decoder_frame_length,
      80             :                                  prev_mode, target_timestamp,
      81             :                                  available_timestamp, play_dtmf,
      82           0 :                                  generated_noise_samples);
      83             :   } else {
      84             :     // This implies that available_timestamp < target_timestamp, which can
      85             :     // happen when a new stream or codec is received. Signal for a reset.
      86           0 :     return kUndefined;
      87             :   }
      88             : }
      89             : 
      90           0 : Operations DecisionLogicNormal::CngOperation(Modes prev_mode,
      91             :                                              uint32_t target_timestamp,
      92             :                                              uint32_t available_timestamp,
      93             :                                              size_t generated_noise_samples) {
      94             :   // Signed difference between target and available timestamp.
      95             :   int32_t timestamp_diff = static_cast<int32_t>(
      96           0 :       static_cast<uint32_t>(generated_noise_samples + target_timestamp) -
      97           0 :       available_timestamp);
      98             :   int32_t optimal_level_samp = static_cast<int32_t>(
      99           0 :       (delay_manager_->TargetLevel() * packet_length_samples_) >> 8);
     100           0 :   int32_t excess_waiting_time_samp = -timestamp_diff - optimal_level_samp;
     101             : 
     102           0 :   if (excess_waiting_time_samp > optimal_level_samp / 2) {
     103             :     // The waiting time for this packet will be longer than 1.5
     104             :     // times the wanted buffer delay. Apply fast-forward to cut the
     105             :     // waiting time down to the optimal.
     106           0 :     noise_fast_forward_ += excess_waiting_time_samp;
     107           0 :     timestamp_diff += excess_waiting_time_samp;
     108             :   }
     109             : 
     110           0 :   if (timestamp_diff < 0 && prev_mode == kModeRfc3389Cng) {
     111             :     // Not time to play this packet yet. Wait another round before using this
     112             :     // packet. Keep on playing CNG from previous CNG parameters.
     113           0 :     return kRfc3389CngNoPacket;
     114             :   } else {
     115             :     // Otherwise, go for the CNG packet now.
     116           0 :     noise_fast_forward_ = 0;
     117           0 :     return kRfc3389Cng;
     118             :   }
     119             : }
     120             : 
     121           0 : Operations DecisionLogicNormal::NoPacket(bool play_dtmf) {
     122           0 :   if (cng_state_ == kCngRfc3389On) {
     123             :     // Keep on playing comfort noise.
     124           0 :     return kRfc3389CngNoPacket;
     125           0 :   } else if (cng_state_ == kCngInternalOn) {
     126             :     // Keep on playing codec internal comfort noise.
     127           0 :     return kCodecInternalCng;
     128           0 :   } else if (play_dtmf) {
     129           0 :     return kDtmf;
     130             :   } else {
     131             :     // Nothing to play, do expand.
     132           0 :     return kExpand;
     133             :   }
     134             : }
     135             : 
     136           0 : Operations DecisionLogicNormal::ExpectedPacketAvailable(Modes prev_mode,
     137             :                                                         bool play_dtmf) {
     138           0 :   if (prev_mode != kModeExpand && !play_dtmf) {
     139             :     // Check criterion for time-stretching.
     140             :     int low_limit, high_limit;
     141           0 :     delay_manager_->BufferLimits(&low_limit, &high_limit);
     142           0 :     if (buffer_level_filter_->filtered_current_level() >= high_limit << 2)
     143           0 :       return kFastAccelerate;
     144           0 :     if (TimescaleAllowed()) {
     145           0 :       if (buffer_level_filter_->filtered_current_level() >= high_limit)
     146           0 :         return kAccelerate;
     147           0 :       if (buffer_level_filter_->filtered_current_level() < low_limit)
     148           0 :         return kPreemptiveExpand;
     149             :     }
     150             :   }
     151           0 :   return kNormal;
     152             : }
     153             : 
     154           0 : Operations DecisionLogicNormal::FuturePacketAvailable(
     155             :     const SyncBuffer& sync_buffer,
     156             :     const Expand& expand,
     157             :     size_t decoder_frame_length,
     158             :     Modes prev_mode,
     159             :     uint32_t target_timestamp,
     160             :     uint32_t available_timestamp,
     161             :     bool play_dtmf,
     162             :     size_t generated_noise_samples) {
     163             :   // Required packet is not available, but a future packet is.
     164             :   // Check if we should continue with an ongoing expand because the new packet
     165             :   // is too far into the future.
     166           0 :   uint32_t timestamp_leap = available_timestamp - target_timestamp;
     167           0 :   if ((prev_mode == kModeExpand) &&
     168           0 :       !ReinitAfterExpands(timestamp_leap) &&
     169           0 :       !MaxWaitForPacket() &&
     170           0 :       PacketTooEarly(timestamp_leap) &&
     171           0 :       UnderTargetLevel()) {
     172           0 :     if (play_dtmf) {
     173             :       // Still have DTMF to play, so do not do expand.
     174           0 :       return kDtmf;
     175             :     } else {
     176             :       // Nothing to play.
     177           0 :       return kExpand;
     178             :     }
     179             :   }
     180             : 
     181             :   const size_t samples_left =
     182           0 :       sync_buffer.FutureLength() - expand.overlap_length();
     183             :   const size_t cur_size_samples = samples_left +
     184           0 :       packet_buffer_.NumPacketsInBuffer() * decoder_frame_length;
     185             : 
     186             :   // If previous was comfort noise, then no merge is needed.
     187           0 :   if (prev_mode == kModeRfc3389Cng ||
     188             :       prev_mode == kModeCodecInternalCng) {
     189             :     // Keep the same delay as before the CNG (or maximum 70 ms in buffer as
     190             :     // safety precaution), but make sure that the number of samples in buffer
     191             :     // is no higher than 4 times the optimal level. (Note that TargetLevel()
     192             :     // is in Q8.)
     193           0 :     if (static_cast<uint32_t>(generated_noise_samples + target_timestamp) >=
     194           0 :             available_timestamp ||
     195             :         cur_size_samples >
     196           0 :             ((delay_manager_->TargetLevel() * packet_length_samples_) >> 8) *
     197             :             4) {
     198             :       // Time to play this new packet.
     199           0 :       return kNormal;
     200             :     } else {
     201             :       // Too early to play this new packet; keep on playing comfort noise.
     202           0 :       if (prev_mode == kModeRfc3389Cng) {
     203           0 :         return kRfc3389CngNoPacket;
     204             :       } else {  // prevPlayMode == kModeCodecInternalCng.
     205           0 :         return kCodecInternalCng;
     206             :       }
     207             :     }
     208             :   }
     209             :   // Do not merge unless we have done an expand before.
     210           0 :   if (prev_mode == kModeExpand) {
     211           0 :     return kMerge;
     212           0 :   } else if (play_dtmf) {
     213             :     // Play DTMF instead of expand.
     214           0 :     return kDtmf;
     215             :   } else {
     216           0 :     return kExpand;
     217             :   }
     218             : }
     219             : 
     220           0 : bool DecisionLogicNormal::UnderTargetLevel() const {
     221           0 :   return buffer_level_filter_->filtered_current_level() <=
     222           0 :       delay_manager_->TargetLevel();
     223             : }
     224             : 
     225           0 : bool DecisionLogicNormal::ReinitAfterExpands(uint32_t timestamp_leap) const {
     226           0 :   return timestamp_leap >=
     227           0 :       static_cast<uint32_t>(output_size_samples_ * kReinitAfterExpands);
     228             : }
     229             : 
     230           0 : bool DecisionLogicNormal::PacketTooEarly(uint32_t timestamp_leap) const {
     231           0 :   return timestamp_leap >
     232           0 :       static_cast<uint32_t>(output_size_samples_ * num_consecutive_expands_);
     233             : }
     234             : 
     235           0 : bool DecisionLogicNormal::MaxWaitForPacket() const {
     236           0 :   return num_consecutive_expands_ >= kMaxWaitForPacket;
     237             : }
     238             : 
     239             : }  // namespace webrtc

Generated by: LCOV version 1.13