1 // Copyright 2018 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 // https://github.com/google/opuscpp
16
17 #include <iterator>
18 #include <memory>
19 #include <string>
20 #include <vector>
21
22 #include <android-base/logging.h>
23 #include "host/frontend/stream_audio/opuscpp/opus_wrapper.h"
24
ErrorToString(int error)25 std::string opus::ErrorToString(int error) {
26 switch (error) {
27 case OPUS_OK:
28 return "OK";
29 case OPUS_BAD_ARG:
30 return "One or more invalid/out of range arguments.";
31 case OPUS_BUFFER_TOO_SMALL:
32 return "The mode struct passed is invalid.";
33 case OPUS_INTERNAL_ERROR:
34 return "An internal error was detected.";
35 case OPUS_INVALID_PACKET:
36 return "The compressed data passed is corrupted.";
37 case OPUS_UNIMPLEMENTED:
38 return "Invalid/unsupported request number.";
39 case OPUS_INVALID_STATE:
40 return "An encoder or decoder structure is invalid or already freed.";
41 default:
42 return "Unknown error code: " + std::to_string(error);
43 }
44 }
45
operator ()(OpusEncoder * encoder) const46 void opus::internal::OpusDestroyer::operator()(OpusEncoder* encoder) const
47 noexcept {
48 opus_encoder_destroy(encoder);
49 }
50
operator ()(OpusDecoder * decoder) const51 void opus::internal::OpusDestroyer::operator()(OpusDecoder* decoder) const
52 noexcept {
53 opus_decoder_destroy(decoder);
54 }
55
Encoder(opus_int32 sample_rate,int num_channels,int application,int expected_loss_percent)56 opus::Encoder::Encoder(opus_int32 sample_rate, int num_channels,
57 int application, int expected_loss_percent)
58 : num_channels_{num_channels} {
59 int error{};
60 encoder_.reset(
61 opus_encoder_create(sample_rate, num_channels, application, &error));
62 valid_ = error == OPUS_OK;
63 if (!valid()) {
64 LOG(INFO) << "Could not construct encoder. Error: " << ErrorToString(error);
65 return;
66 }
67 if (expected_loss_percent > 0) {
68 LOG(INFO) << "Enabling FEC in the encoder.";
69 Ctl(OPUS_SET_INBAND_FEC(1));
70 Ctl(OPUS_SET_PACKET_LOSS_PERC(expected_loss_percent));
71 }
72 }
73
ResetState()74 bool opus::Encoder::ResetState() {
75 valid_ = Ctl(OPUS_RESET_STATE) == OPUS_OK;
76 return valid_;
77 }
78
SetBitrate(int bitrate)79 bool opus::Encoder::SetBitrate(int bitrate) {
80 valid_ = Ctl(OPUS_SET_BITRATE(bitrate)) == OPUS_OK;
81 return valid_;
82 }
83
SetVariableBitrate(int vbr)84 bool opus::Encoder::SetVariableBitrate(int vbr) {
85 valid_ = Ctl(OPUS_SET_VBR(vbr)) == OPUS_OK;
86 return valid_;
87 }
88
SetComplexity(int complexity)89 bool opus::Encoder::SetComplexity(int complexity) {
90 valid_ = Ctl(OPUS_SET_COMPLEXITY(complexity)) == OPUS_OK;
91 return valid_;
92 }
93
GetLookahead()94 int opus::Encoder::GetLookahead() {
95 opus_int32 skip{};
96 valid_ = Ctl(OPUS_GET_LOOKAHEAD(&skip)) == OPUS_OK;
97 return skip;
98 }
99
Encode(const std::vector<opus_int16> & pcm,int frame_size)100 std::vector<std::vector<unsigned char>> opus::Encoder::Encode(
101 const std::vector<opus_int16>& pcm, int frame_size) {
102 constexpr auto sample_size = sizeof(pcm[0]);
103 const auto frame_length = frame_size * num_channels_ * sample_size;
104 auto data_length = pcm.size() * sample_size;
105 if (data_length % frame_length != 0u) {
106 LOG(WARNING) << "PCM samples contain an incomplete frame. Ignoring the "
107 "incomplete frame.";
108 data_length -= (data_length % frame_length);
109 }
110
111 std::vector<std::vector<unsigned char>> encoded;
112 for (std::size_t i{}; i < data_length; i += frame_length) {
113 encoded.push_back(EncodeFrame(pcm.begin() + (i / sample_size), frame_size));
114 }
115 return encoded;
116 }
117
EncodeFrame(const std::vector<opus_int16>::const_iterator & frame_start,int frame_size)118 std::vector<unsigned char> opus::Encoder::EncodeFrame(
119 const std::vector<opus_int16>::const_iterator& frame_start,
120 int frame_size) {
121 const auto frame_length = (frame_size * num_channels_ * sizeof(*frame_start));
122 std::vector<unsigned char> encoded(frame_length);
123 auto num_bytes = opus_encode(encoder_.get(), &*frame_start, frame_size,
124 encoded.data(), encoded.size());
125 if (num_bytes < 0) {
126 LOG(ERROR) << "Encode error: " << opus::ErrorToString(num_bytes);
127 return {};
128 }
129 encoded.resize(num_bytes);
130 return encoded;
131 }
132
Decoder(opus_uint32 sample_rate,int num_channels)133 opus::Decoder::Decoder(opus_uint32 sample_rate, int num_channels)
134 : num_channels_(num_channels) {
135 int error{};
136 decoder_.reset(opus_decoder_create(sample_rate, num_channels, &error));
137 valid_ = error == OPUS_OK;
138 }
139
Decode(const std::vector<std::vector<unsigned char>> & packets,int frame_size,bool decode_fec)140 std::vector<opus_int16> opus::Decoder::Decode(
141 const std::vector<std::vector<unsigned char>>& packets, int frame_size,
142 bool decode_fec) {
143 std::vector<opus_int16> decoded;
144 for (const auto& enc : packets) {
145 auto just_decoded = Decode(enc, frame_size, decode_fec);
146 decoded.insert(std::end(decoded), std::begin(just_decoded),
147 std::end(just_decoded));
148 }
149 return decoded;
150 }
151
Decode(const std::vector<unsigned char> & packet,int frame_size,bool decode_fec)152 std::vector<opus_int16> opus::Decoder::Decode(
153 const std::vector<unsigned char>& packet, int frame_size, bool decode_fec) {
154 const auto frame_length = (frame_size * num_channels_ * sizeof(opus_int16));
155 std::vector<opus_int16> decoded(frame_length);
156 auto num_samples = opus_decode(decoder_.get(), packet.data(), packet.size(),
157 decoded.data(), frame_size, decode_fec);
158 if (num_samples < 0) {
159 LOG(ERROR) << "Decode error: " << opus::ErrorToString(num_samples);
160 return {};
161 }
162 decoded.resize(num_samples * num_channels_);
163 return decoded;
164 }
165
DecodeDummy(int frame_size)166 std::vector<opus_int16> opus::Decoder::DecodeDummy(int frame_size) {
167 const auto frame_length = (frame_size * num_channels_ * sizeof(opus_int16));
168 std::vector<opus_int16> decoded(frame_length);
169 auto num_samples =
170 opus_decode(decoder_.get(), nullptr, 0, decoded.data(), frame_size, true);
171 if (num_samples < 0) {
172 LOG(ERROR) << "Decode error: " << opus::ErrorToString(num_samples);
173 return {};
174 }
175 decoded.resize(num_samples * num_channels_);
176 return decoded;
177 }
178