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