Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(384)

Side by Side Diff: webrtc/modules/audio_coding/codecs/opus/opus_interface.c

Issue 1428613004: Revert of Prevent Opus DTX from generating intermittent noise during silence (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
11 #include "webrtc/modules/audio_coding/codecs/opus/include/opus_interface.h" 11 #include "webrtc/modules/audio_coding/codecs/opus/include/opus_interface.h"
12 #include "webrtc/modules/audio_coding/codecs/opus/opus_inst.h" 12 #include "webrtc/modules/audio_coding/codecs/opus/opus_inst.h"
13 13
14 #include <assert.h>
15 #include <stdlib.h> 14 #include <stdlib.h>
16 #include <string.h> 15 #include <string.h>
17 16
18 enum { 17 enum {
19 /* Maximum supported frame size in WebRTC is 60 ms. */ 18 /* Maximum supported frame size in WebRTC is 60 ms. */
20 kWebRtcOpusMaxEncodeFrameSizeMs = 60, 19 kWebRtcOpusMaxEncodeFrameSizeMs = 60,
21 20
22 /* The format allows up to 120 ms frames. Since we don't control the other 21 /* The format allows up to 120 ms frames. Since we don't control the other
23 * side, we must allow for packets of that size. NetEq is currently limited 22 * side, we must allow for packets of that size. NetEq is currently limited
24 * to 60 ms on the receive side. */ 23 * to 60 ms on the receive side. */
25 kWebRtcOpusMaxDecodeFrameSizeMs = 120, 24 kWebRtcOpusMaxDecodeFrameSizeMs = 120,
26 25
27 /* Maximum sample count per channel is 48 kHz * maximum frame size in 26 /* Maximum sample count per channel is 48 kHz * maximum frame size in
28 * milliseconds. */ 27 * milliseconds. */
29 kWebRtcOpusMaxFrameSizePerChannel = 48 * kWebRtcOpusMaxDecodeFrameSizeMs, 28 kWebRtcOpusMaxFrameSizePerChannel = 48 * kWebRtcOpusMaxDecodeFrameSizeMs,
30 29
31 /* Default frame size, 20 ms @ 48 kHz, in samples (for one channel). */ 30 /* Default frame size, 20 ms @ 48 kHz, in samples (for one channel). */
32 kWebRtcOpusDefaultFrameSize = 960, 31 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 }; 32 };
43 33
44 int16_t WebRtcOpus_EncoderCreate(OpusEncInst** inst, 34 int16_t WebRtcOpus_EncoderCreate(OpusEncInst** inst,
45 int32_t channels, 35 int32_t channels,
46 int32_t application) { 36 int32_t application) {
47 int opus_app; 37 OpusEncInst* state;
48 if (!inst) 38 if (inst != NULL) {
49 return -1; 39 state = (OpusEncInst*) calloc(1, sizeof(OpusEncInst));
40 if (state) {
41 int opus_app;
42 switch (application) {
43 case 0: {
44 opus_app = OPUS_APPLICATION_VOIP;
45 break;
46 }
47 case 1: {
48 opus_app = OPUS_APPLICATION_AUDIO;
49 break;
50 }
51 default: {
52 free(state);
53 return -1;
54 }
55 }
50 56
51 switch (application) { 57 int error;
52 case 0: 58 state->encoder = opus_encoder_create(48000, channels, opus_app,
53 opus_app = OPUS_APPLICATION_VOIP; 59 &error);
54 break; 60 state->in_dtx_mode = 0;
55 case 1: 61 if (error == OPUS_OK && state->encoder != NULL) {
56 opus_app = OPUS_APPLICATION_AUDIO; 62 *inst = state;
57 break; 63 return 0;
58 default: 64 }
59 return -1; 65 free(state);
66 }
60 } 67 }
61 68 return -1;
62 OpusEncInst* state = calloc(1, sizeof(OpusEncInst));
63 assert(state);
64
65 // Allocate zero counters.
66 state->zero_counts = calloc(channels, sizeof(size_t));
67 assert(state->zero_counts);
68
69 int error;
70 state->encoder = opus_encoder_create(48000, channels, opus_app,
71 &error);
72 if (error != OPUS_OK || !state->encoder) {
73 WebRtcOpus_EncoderFree(state);
74 return -1;
75 }
76
77 state->in_dtx_mode = 0;
78 state->channels = channels;
79
80 *inst = state;
81 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 int 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 int 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
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 }
OLDNEW
« no previous file with comments | « webrtc/modules/audio_coding/codecs/opus/opus_inst.h ('k') | webrtc/modules/audio_coding/codecs/opus/opus_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698