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.h"
12 :
13 : #include <algorithm>
14 :
15 : #include "webrtc/modules/audio_coding/neteq/buffer_level_filter.h"
16 : #include "webrtc/modules/audio_coding/neteq/decision_logic_fax.h"
17 : #include "webrtc/modules/audio_coding/neteq/decision_logic_normal.h"
18 : #include "webrtc/modules/audio_coding/neteq/delay_manager.h"
19 : #include "webrtc/modules/audio_coding/neteq/expand.h"
20 : #include "webrtc/modules/audio_coding/neteq/packet_buffer.h"
21 : #include "webrtc/modules/audio_coding/neteq/sync_buffer.h"
22 : #include "webrtc/system_wrappers/include/logging.h"
23 :
24 : namespace webrtc {
25 :
26 0 : DecisionLogic* DecisionLogic::Create(int fs_hz,
27 : size_t output_size_samples,
28 : NetEqPlayoutMode playout_mode,
29 : DecoderDatabase* decoder_database,
30 : const PacketBuffer& packet_buffer,
31 : DelayManager* delay_manager,
32 : BufferLevelFilter* buffer_level_filter,
33 : const TickTimer* tick_timer) {
34 0 : switch (playout_mode) {
35 : case kPlayoutOn:
36 : case kPlayoutStreaming:
37 : return new DecisionLogicNormal(
38 : fs_hz, output_size_samples, playout_mode, decoder_database,
39 0 : packet_buffer, delay_manager, buffer_level_filter, tick_timer);
40 : case kPlayoutFax:
41 : case kPlayoutOff:
42 : return new DecisionLogicFax(
43 : fs_hz, output_size_samples, playout_mode, decoder_database,
44 0 : packet_buffer, delay_manager, buffer_level_filter, tick_timer);
45 : }
46 : // This line cannot be reached, but must be here to avoid compiler errors.
47 0 : assert(false);
48 : return NULL;
49 : }
50 :
51 0 : DecisionLogic::DecisionLogic(int fs_hz,
52 : size_t output_size_samples,
53 : NetEqPlayoutMode playout_mode,
54 : DecoderDatabase* decoder_database,
55 : const PacketBuffer& packet_buffer,
56 : DelayManager* delay_manager,
57 : BufferLevelFilter* buffer_level_filter,
58 0 : const TickTimer* tick_timer)
59 : : decoder_database_(decoder_database),
60 : packet_buffer_(packet_buffer),
61 : delay_manager_(delay_manager),
62 : buffer_level_filter_(buffer_level_filter),
63 : tick_timer_(tick_timer),
64 : cng_state_(kCngOff),
65 : packet_length_samples_(0),
66 : sample_memory_(0),
67 : prev_time_scale_(false),
68 : timescale_countdown_(
69 0 : tick_timer_->GetNewCountdown(kMinTimescaleInterval + 1)),
70 : num_consecutive_expands_(0),
71 0 : playout_mode_(playout_mode) {
72 0 : delay_manager_->set_streaming_mode(playout_mode_ == kPlayoutStreaming);
73 0 : SetSampleRate(fs_hz, output_size_samples);
74 0 : }
75 :
76 : DecisionLogic::~DecisionLogic() = default;
77 :
78 0 : void DecisionLogic::Reset() {
79 0 : cng_state_ = kCngOff;
80 0 : noise_fast_forward_ = 0;
81 0 : packet_length_samples_ = 0;
82 0 : sample_memory_ = 0;
83 0 : prev_time_scale_ = false;
84 0 : timescale_countdown_.reset();
85 0 : num_consecutive_expands_ = 0;
86 0 : }
87 :
88 0 : void DecisionLogic::SoftReset() {
89 0 : packet_length_samples_ = 0;
90 0 : sample_memory_ = 0;
91 0 : prev_time_scale_ = false;
92 : timescale_countdown_ =
93 0 : tick_timer_->GetNewCountdown(kMinTimescaleInterval + 1);
94 0 : }
95 :
96 0 : void DecisionLogic::SetSampleRate(int fs_hz, size_t output_size_samples) {
97 : // TODO(hlundin): Change to an enumerator and skip assert.
98 0 : assert(fs_hz == 8000 || fs_hz == 16000 || fs_hz == 32000 || fs_hz == 48000);
99 0 : fs_mult_ = fs_hz / 8000;
100 0 : output_size_samples_ = output_size_samples;
101 0 : }
102 :
103 0 : Operations DecisionLogic::GetDecision(const SyncBuffer& sync_buffer,
104 : const Expand& expand,
105 : size_t decoder_frame_length,
106 : const Packet* next_packet,
107 : Modes prev_mode,
108 : bool play_dtmf,
109 : size_t generated_noise_samples,
110 : bool* reset_decoder) {
111 : // If last mode was CNG (or Expand, since this could be covering up for
112 : // a lost CNG packet), remember that CNG is on. This is needed if comfort
113 : // noise is interrupted by DTMF.
114 0 : if (prev_mode == kModeRfc3389Cng) {
115 0 : cng_state_ = kCngRfc3389On;
116 0 : } else if (prev_mode == kModeCodecInternalCng) {
117 0 : cng_state_ = kCngInternalOn;
118 : }
119 :
120 : const size_t samples_left =
121 0 : sync_buffer.FutureLength() - expand.overlap_length();
122 : const size_t cur_size_samples =
123 0 : samples_left + packet_buffer_.NumSamplesInBuffer(decoder_frame_length);
124 :
125 0 : prev_time_scale_ = prev_time_scale_ &&
126 0 : (prev_mode == kModeAccelerateSuccess ||
127 0 : prev_mode == kModeAccelerateLowEnergy ||
128 0 : prev_mode == kModePreemptiveExpandSuccess ||
129 : prev_mode == kModePreemptiveExpandLowEnergy);
130 :
131 0 : FilterBufferLevel(cur_size_samples, prev_mode);
132 :
133 0 : return GetDecisionSpecialized(sync_buffer, expand, decoder_frame_length,
134 : next_packet, prev_mode, play_dtmf,
135 0 : reset_decoder, generated_noise_samples);
136 : }
137 :
138 0 : void DecisionLogic::ExpandDecision(Operations operation) {
139 0 : if (operation == kExpand) {
140 0 : num_consecutive_expands_++;
141 : } else {
142 0 : num_consecutive_expands_ = 0;
143 : }
144 0 : }
145 :
146 0 : void DecisionLogic::FilterBufferLevel(size_t buffer_size_samples,
147 : Modes prev_mode) {
148 : // Do not update buffer history if currently playing CNG since it will bias
149 : // the filtered buffer level.
150 0 : if ((prev_mode != kModeRfc3389Cng) && (prev_mode != kModeCodecInternalCng)) {
151 0 : buffer_level_filter_->SetTargetBufferLevel(
152 0 : delay_manager_->base_target_level());
153 :
154 0 : size_t buffer_size_packets = 0;
155 0 : if (packet_length_samples_ > 0) {
156 : // Calculate size in packets.
157 0 : buffer_size_packets = buffer_size_samples / packet_length_samples_;
158 : }
159 0 : int sample_memory_local = 0;
160 0 : if (prev_time_scale_) {
161 0 : sample_memory_local = sample_memory_;
162 : timescale_countdown_ =
163 0 : tick_timer_->GetNewCountdown(kMinTimescaleInterval);
164 : }
165 0 : buffer_level_filter_->Update(buffer_size_packets, sample_memory_local,
166 0 : packet_length_samples_);
167 0 : prev_time_scale_ = false;
168 : }
169 0 : }
170 :
171 : } // namespace webrtc
|