• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_fax.h"
12 
13 #include <assert.h>
14 
15 #include <algorithm>
16 
17 #include "webrtc/modules/audio_coding/neteq/decoder_database.h"
18 #include "webrtc/modules/audio_coding/neteq/sync_buffer.h"
19 
20 namespace webrtc {
21 
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)22 Operations DecisionLogicFax::GetDecisionSpecialized(
23     const SyncBuffer& sync_buffer,
24     const Expand& expand,
25     int decoder_frame_length,
26     const RTPHeader* packet_header,
27     Modes prev_mode,
28     bool play_dtmf,
29     bool* reset_decoder) {
30   assert(playout_mode_ == kPlayoutFax || playout_mode_ == kPlayoutOff);
31   uint32_t target_timestamp = sync_buffer.end_timestamp();
32   uint32_t available_timestamp = 0;
33   int is_cng_packet = 0;
34   if (packet_header) {
35     available_timestamp = packet_header->timestamp;
36     is_cng_packet =
37         decoder_database_->IsComfortNoise(packet_header->payloadType);
38   }
39   if (is_cng_packet) {
40     if (static_cast<int32_t>((generated_noise_samples_ + target_timestamp)
41         - available_timestamp) >= 0) {
42       // Time to play this packet now.
43       return kRfc3389Cng;
44     } else {
45       // Wait before playing this packet.
46       return kRfc3389CngNoPacket;
47     }
48   }
49   if (!packet_header) {
50     // No packet. If in CNG mode, play as usual. Otherwise, use other method to
51     // generate data.
52     if (cng_state_ == kCngRfc3389On) {
53       // Continue playing comfort noise.
54       return kRfc3389CngNoPacket;
55     } else if (cng_state_ == kCngInternalOn) {
56       // Continue playing codec-internal comfort noise.
57       return kCodecInternalCng;
58     } else {
59       // Nothing to play. Generate some data to play out.
60       switch (playout_mode_) {
61         case kPlayoutOff:
62           return kAlternativePlc;
63         case kPlayoutFax:
64           return kAudioRepetition;
65         default:
66           assert(false);
67           return kUndefined;
68       }
69     }
70   } else if (target_timestamp == available_timestamp) {
71     return kNormal;
72   } else {
73     if (static_cast<int32_t>((generated_noise_samples_ + target_timestamp)
74         - available_timestamp) >= 0) {
75       return kNormal;
76     } else {
77       // If currently playing comfort noise, continue with that. Do not
78       // increase the timestamp counter since generated_noise_samples_ will
79       // be increased.
80       if (cng_state_ == kCngRfc3389On) {
81         return kRfc3389CngNoPacket;
82       } else if (cng_state_ == kCngInternalOn) {
83         return kCodecInternalCng;
84       } else {
85         // Otherwise, do packet-loss concealment and increase the
86         // timestamp while waiting for the time to play this packet.
87         switch (playout_mode_) {
88           case kPlayoutOff:
89             return kAlternativePlcIncreaseTimestamp;
90           case kPlayoutFax:
91             return kAudioRepetitionIncreaseTimestamp;
92           default:
93             assert(0);
94             return kUndefined;
95         }
96       }
97     }
98   }
99 }
100 
101 
102 }  // namespace webrtc
103