blob: 538bee87d9336bfe186e7ba407bcaec8d3ba9657 [file] [log] [blame]
Cody Schuffelen134ff032019-11-22 00:25:32 -08001// 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
25std::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
46void opus::internal::OpusDestroyer::operator()(OpusEncoder* encoder) const
47 noexcept {
48 opus_encoder_destroy(encoder);
49}
50
51void opus::internal::OpusDestroyer::operator()(OpusDecoder* decoder) const
52 noexcept {
53 opus_decoder_destroy(decoder);
54}
55
56opus::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
74bool opus::Encoder::ResetState() {
75 valid_ = Ctl(OPUS_RESET_STATE) == OPUS_OK;
76 return valid_;
77}
78
79bool opus::Encoder::SetBitrate(int bitrate) {
80 valid_ = Ctl(OPUS_SET_BITRATE(bitrate)) == OPUS_OK;
81 return valid_;
82}
83
84bool opus::Encoder::SetVariableBitrate(int vbr) {
85 valid_ = Ctl(OPUS_SET_VBR(vbr)) == OPUS_OK;
86 return valid_;
87}
88
89bool opus::Encoder::SetComplexity(int complexity) {
90 valid_ = Ctl(OPUS_SET_COMPLEXITY(complexity)) == OPUS_OK;
91 return valid_;
92}
93
94int opus::Encoder::GetLookahead() {
95 opus_int32 skip{};
96 valid_ = Ctl(OPUS_GET_LOOKAHEAD(&skip)) == OPUS_OK;
97 return skip;
98}
99
100std::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
118std::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
133opus::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
140std::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
152std::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
166std::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}