OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 12 matching lines...) Expand all Loading... |
23 * side, we must allow for packets of that size. NetEq is currently limited | 23 * side, we must allow for packets of that size. NetEq is currently limited |
24 * to 60 ms on the receive side. */ | 24 * to 60 ms on the receive side. */ |
25 kWebRtcOpusMaxDecodeFrameSizeMs = 120, | 25 kWebRtcOpusMaxDecodeFrameSizeMs = 120, |
26 | 26 |
27 /* Maximum sample count per channel is 48 kHz * maximum frame size in | 27 /* Maximum sample count per channel is 48 kHz * maximum frame size in |
28 * milliseconds. */ | 28 * milliseconds. */ |
29 kWebRtcOpusMaxFrameSizePerChannel = 48 * kWebRtcOpusMaxDecodeFrameSizeMs, | 29 kWebRtcOpusMaxFrameSizePerChannel = 48 * kWebRtcOpusMaxDecodeFrameSizeMs, |
30 | 30 |
31 /* Default frame size, 20 ms @ 48 kHz, in samples (for one channel). */ | 31 /* Default frame size, 20 ms @ 48 kHz, in samples (for one channel). */ |
32 kWebRtcOpusDefaultFrameSize = 960, | 32 kWebRtcOpusDefaultFrameSize = 960, |
33 | |
34 // Maximum number of consecutive zeros, beyond or equal to which DTX can fail. | |
35 kZeroBreakCount = 157, | |
36 | |
37 #if defined(OPUS_FIXED_POINT) | |
38 kZeroBreakValue = 10, | |
39 #else | |
40 kZeroBreakValue = 1, | |
41 #endif | |
42 }; | 33 }; |
43 | 34 |
44 int16_t WebRtcOpus_EncoderCreate(OpusEncInst** inst, | 35 int16_t WebRtcOpus_EncoderCreate(OpusEncInst** inst, |
45 size_t channels, | 36 size_t channels, |
46 int32_t application) { | 37 int32_t application) { |
47 int opus_app; | 38 int opus_app; |
48 if (!inst) | 39 if (!inst) |
49 return -1; | 40 return -1; |
50 | 41 |
51 switch (application) { | 42 switch (application) { |
52 case 0: | 43 case 0: |
53 opus_app = OPUS_APPLICATION_VOIP; | 44 opus_app = OPUS_APPLICATION_VOIP; |
54 break; | 45 break; |
55 case 1: | 46 case 1: |
56 opus_app = OPUS_APPLICATION_AUDIO; | 47 opus_app = OPUS_APPLICATION_AUDIO; |
57 break; | 48 break; |
58 default: | 49 default: |
59 return -1; | 50 return -1; |
60 } | 51 } |
61 | 52 |
62 OpusEncInst* state = calloc(1, sizeof(OpusEncInst)); | 53 OpusEncInst* state = calloc(1, sizeof(OpusEncInst)); |
63 assert(state); | 54 assert(state); |
64 | 55 |
65 // Allocate zero counters. | |
66 state->zero_counts = calloc(channels, sizeof(size_t)); | |
67 assert(state->zero_counts); | |
68 | |
69 int error; | 56 int error; |
70 state->encoder = opus_encoder_create(48000, (int)channels, opus_app, | 57 state->encoder = opus_encoder_create(48000, (int)channels, opus_app, |
71 &error); | 58 &error); |
72 if (error != OPUS_OK || !state->encoder) { | 59 if (error != OPUS_OK || !state->encoder) { |
73 WebRtcOpus_EncoderFree(state); | 60 WebRtcOpus_EncoderFree(state); |
74 return -1; | 61 return -1; |
75 } | 62 } |
76 | 63 |
77 state->in_dtx_mode = 0; | 64 state->in_dtx_mode = 0; |
78 state->channels = channels; | 65 state->channels = channels; |
79 | 66 |
80 *inst = state; | 67 *inst = state; |
81 return 0; | 68 return 0; |
82 } | 69 } |
83 | 70 |
84 int16_t WebRtcOpus_EncoderFree(OpusEncInst* inst) { | 71 int16_t WebRtcOpus_EncoderFree(OpusEncInst* inst) { |
85 if (inst) { | 72 if (inst) { |
86 opus_encoder_destroy(inst->encoder); | 73 opus_encoder_destroy(inst->encoder); |
87 free(inst->zero_counts); | |
88 free(inst); | 74 free(inst); |
89 return 0; | 75 return 0; |
90 } else { | 76 } else { |
91 return -1; | 77 return -1; |
92 } | 78 } |
93 } | 79 } |
94 | 80 |
95 int WebRtcOpus_Encode(OpusEncInst* inst, | 81 int WebRtcOpus_Encode(OpusEncInst* inst, |
96 const int16_t* audio_in, | 82 const int16_t* audio_in, |
97 size_t samples, | 83 size_t samples, |
98 size_t length_encoded_buffer, | 84 size_t length_encoded_buffer, |
99 uint8_t* encoded) { | 85 uint8_t* encoded) { |
100 int res; | 86 int res; |
101 size_t i; | |
102 size_t c; | |
103 | |
104 int16_t buffer[2 * 48 * kWebRtcOpusMaxEncodeFrameSizeMs]; | |
105 | 87 |
106 if (samples > 48 * kWebRtcOpusMaxEncodeFrameSizeMs) { | 88 if (samples > 48 * kWebRtcOpusMaxEncodeFrameSizeMs) { |
107 return -1; | 89 return -1; |
108 } | 90 } |
109 | 91 |
110 const size_t channels = inst->channels; | |
111 int use_buffer = 0; | |
112 | |
113 // Break long consecutive zeros by forcing a "1" every |kZeroBreakCount| | |
114 // samples. | |
115 if (inst->in_dtx_mode) { | |
116 for (i = 0; i < samples; ++i) { | |
117 for (c = 0; c < channels; ++c) { | |
118 if (audio_in[i * channels + c] == 0) { | |
119 ++inst->zero_counts[c]; | |
120 if (inst->zero_counts[c] == kZeroBreakCount) { | |
121 if (!use_buffer) { | |
122 memcpy(buffer, audio_in, samples * channels * sizeof(int16_t)); | |
123 use_buffer = 1; | |
124 } | |
125 buffer[i * channels + c] = kZeroBreakValue; | |
126 inst->zero_counts[c] = 0; | |
127 } | |
128 } else { | |
129 inst->zero_counts[c] = 0; | |
130 } | |
131 } | |
132 } | |
133 } | |
134 | |
135 res = opus_encode(inst->encoder, | 92 res = opus_encode(inst->encoder, |
136 use_buffer ? buffer : audio_in, | 93 (const opus_int16*)audio_in, |
137 (int)samples, | 94 (int)samples, |
138 encoded, | 95 encoded, |
139 (opus_int32)length_encoded_buffer); | 96 (opus_int32)length_encoded_buffer); |
140 | 97 |
141 if (res == 1) { | 98 if (res == 1) { |
142 // Indicates DTX since the packet has nothing but a header. In principle, | 99 // Indicates DTX since the packet has nothing but a header. In principle, |
143 // there is no need to send this packet. However, we do transmit the first | 100 // there is no need to send this packet. However, we do transmit the first |
144 // occurrence to let the decoder know that the encoder enters DTX mode. | 101 // occurrence to let the decoder know that the encoder enters DTX mode. |
145 if (inst->in_dtx_mode) { | 102 if (inst->in_dtx_mode) { |
146 return 0; | 103 return 0; |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
495 return 0; | 452 return 0; |
496 } | 453 } |
497 | 454 |
498 for (n = 0; n < channels; n++) { | 455 for (n = 0; n < channels; n++) { |
499 if (frame_data[0][0] & (0x80 >> ((n + 1) * (frames + 1) - 1))) | 456 if (frame_data[0][0] & (0x80 >> ((n + 1) * (frames + 1) - 1))) |
500 return 1; | 457 return 1; |
501 } | 458 } |
502 | 459 |
503 return 0; | 460 return 0; |
504 } | 461 } |
OLD | NEW |