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 : #ifndef WEBRTC_MODULES_AUDIO_CODING_NETEQ_DECISION_LOGIC_H_
12 : #define WEBRTC_MODULES_AUDIO_CODING_NETEQ_DECISION_LOGIC_H_
13 :
14 : #include "webrtc/base/constructormagic.h"
15 : #include "webrtc/modules/audio_coding/neteq/defines.h"
16 : #include "webrtc/modules/audio_coding/neteq/include/neteq.h"
17 : #include "webrtc/modules/audio_coding/neteq/tick_timer.h"
18 : #include "webrtc/typedefs.h"
19 :
20 : namespace webrtc {
21 :
22 : // Forward declarations.
23 : class BufferLevelFilter;
24 : class DecoderDatabase;
25 : class DelayManager;
26 : class Expand;
27 : class PacketBuffer;
28 : class SyncBuffer;
29 : struct Packet;
30 :
31 : // This is the base class for the decision tree implementations. Derived classes
32 : // must implement the method GetDecisionSpecialized().
33 0 : class DecisionLogic {
34 : public:
35 : // Static factory function which creates different types of objects depending
36 : // on the |playout_mode|.
37 : static DecisionLogic* Create(int fs_hz,
38 : size_t output_size_samples,
39 : NetEqPlayoutMode playout_mode,
40 : DecoderDatabase* decoder_database,
41 : const PacketBuffer& packet_buffer,
42 : DelayManager* delay_manager,
43 : BufferLevelFilter* buffer_level_filter,
44 : const TickTimer* tick_timer);
45 :
46 : // Constructor.
47 : DecisionLogic(int fs_hz,
48 : size_t output_size_samples,
49 : NetEqPlayoutMode playout_mode,
50 : DecoderDatabase* decoder_database,
51 : const PacketBuffer& packet_buffer,
52 : DelayManager* delay_manager,
53 : BufferLevelFilter* buffer_level_filter,
54 : const TickTimer* tick_timer);
55 :
56 : virtual ~DecisionLogic();
57 :
58 : // Resets object to a clean state.
59 : void Reset();
60 :
61 : // Resets parts of the state. Typically done when switching codecs.
62 : void SoftReset();
63 :
64 : // Sets the sample rate and the output block size.
65 : void SetSampleRate(int fs_hz, size_t output_size_samples);
66 :
67 : // Returns the operation that should be done next. |sync_buffer| and |expand|
68 : // are provided for reference. |decoder_frame_length| is the number of samples
69 : // obtained from the last decoded frame. If there is a packet available, it
70 : // should be supplied in |next_packet|; otherwise it should be NULL. The mode
71 : // resulting from the last call to NetEqImpl::GetAudio is supplied in
72 : // |prev_mode|. If there is a DTMF event to play, |play_dtmf| should be set to
73 : // true. The output variable |reset_decoder| will be set to true if a reset is
74 : // required; otherwise it is left unchanged (i.e., it can remain true if it
75 : // was true before the call). This method end with calling
76 : // GetDecisionSpecialized to get the actual return value.
77 : Operations GetDecision(const SyncBuffer& sync_buffer,
78 : const Expand& expand,
79 : size_t decoder_frame_length,
80 : const Packet* next_packet,
81 : Modes prev_mode,
82 : bool play_dtmf,
83 : size_t generated_noise_samples,
84 : bool* reset_decoder);
85 :
86 : // These methods test the |cng_state_| for different conditions.
87 0 : bool CngRfc3389On() const { return cng_state_ == kCngRfc3389On; }
88 0 : bool CngOff() const { return cng_state_ == kCngOff; }
89 :
90 : // Resets the |cng_state_| to kCngOff.
91 0 : void SetCngOff() { cng_state_ = kCngOff; }
92 :
93 : // Reports back to DecisionLogic whether the decision to do expand remains or
94 : // not. Note that this is necessary, since an expand decision can be changed
95 : // to kNormal in NetEqImpl::GetDecision if there is still enough data in the
96 : // sync buffer.
97 : virtual void ExpandDecision(Operations operation);
98 :
99 : // Adds |value| to |sample_memory_|.
100 0 : void AddSampleMemory(int32_t value) {
101 0 : sample_memory_ += value;
102 0 : }
103 :
104 : // Accessors and mutators.
105 0 : void set_sample_memory(int32_t value) { sample_memory_ = value; }
106 0 : size_t noise_fast_forward() const { return noise_fast_forward_; }
107 0 : size_t packet_length_samples() const { return packet_length_samples_; }
108 0 : void set_packet_length_samples(size_t value) {
109 0 : packet_length_samples_ = value;
110 0 : }
111 0 : void set_prev_time_scale(bool value) { prev_time_scale_ = value; }
112 : NetEqPlayoutMode playout_mode() const { return playout_mode_; }
113 :
114 : protected:
115 : // The value 5 sets maximum time-stretch rate to about 100 ms/s.
116 : static const int kMinTimescaleInterval = 5;
117 :
118 : enum CngState {
119 : kCngOff,
120 : kCngRfc3389On,
121 : kCngInternalOn
122 : };
123 :
124 : // Returns the operation that should be done next. |sync_buffer| and |expand|
125 : // are provided for reference. |decoder_frame_length| is the number of samples
126 : // obtained from the last decoded frame. If there is a packet available, it
127 : // should be supplied in |next_packet|; otherwise it should be NULL. The mode
128 : // resulting from the last call to NetEqImpl::GetAudio is supplied in
129 : // |prev_mode|. If there is a DTMF event to play, |play_dtmf| should be set to
130 : // true. The output variable |reset_decoder| will be set to true if a reset is
131 : // required; otherwise it is left unchanged (i.e., it can remain true if it
132 : // was true before the call). Should be implemented by derived classes.
133 : virtual Operations GetDecisionSpecialized(const SyncBuffer& sync_buffer,
134 : const Expand& expand,
135 : size_t decoder_frame_length,
136 : const Packet* next_packet,
137 : Modes prev_mode,
138 : bool play_dtmf,
139 : bool* reset_decoder,
140 : size_t generated_noise_samples) = 0;
141 :
142 : // Updates the |buffer_level_filter_| with the current buffer level
143 : // |buffer_size_packets|.
144 : void FilterBufferLevel(size_t buffer_size_packets, Modes prev_mode);
145 :
146 : DecoderDatabase* decoder_database_;
147 : const PacketBuffer& packet_buffer_;
148 : DelayManager* delay_manager_;
149 : BufferLevelFilter* buffer_level_filter_;
150 : const TickTimer* tick_timer_;
151 : int fs_mult_;
152 : size_t output_size_samples_;
153 : CngState cng_state_; // Remember if comfort noise is interrupted by other
154 : // event (e.g., DTMF).
155 : size_t noise_fast_forward_ = 0;
156 : size_t packet_length_samples_;
157 : int sample_memory_;
158 : bool prev_time_scale_;
159 : std::unique_ptr<TickTimer::Countdown> timescale_countdown_;
160 : int num_consecutive_expands_;
161 : const NetEqPlayoutMode playout_mode_;
162 :
163 : private:
164 : RTC_DISALLOW_COPY_AND_ASSIGN(DecisionLogic);
165 : };
166 :
167 : } // namespace webrtc
168 : #endif // WEBRTC_MODULES_AUDIO_CODING_NETEQ_DECISION_LOGIC_H_
|