1 /*
2 * Copyright 2023 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "mmc/codec_server/a2dp_aac_mmc_encoder.h"
18
19 extern "C" {
20 #include <libavcodec/avcodec.h>
21 #include <libavutil/channel_layout.h>
22 #include <libavutil/common.h>
23 #include <libavutil/frame.h>
24 #include <libavutil/samplefmt.h>
25 }
26
27 #include <bluetooth/log.h>
28
29 #include "a2dp_aac.h"
30 #include "mmc/proto/mmc_config.pb.h"
31
32 namespace mmc {
33 namespace {
34
35 using namespace bluetooth;
36
37 const int A2DP_AAC_HEADER_LEN = 9;
38 const int A2DP_AAC_MAX_LEN_REPR = 4;
39 const int A2DP_AAC_MAX_PREFIX_SIZE =
40 AVDT_MEDIA_HDR_SIZE + A2DP_AAC_HEADER_LEN + A2DP_AAC_MAX_LEN_REPR;
41
42 constexpr uint8_t A2DP_AAC_HEADER_44100[A2DP_AAC_HEADER_LEN] = {
43 0x47, 0xfc, 0x00, 0x00, 0xb0, 0x90, 0x80, 0x03, 0x00,
44 };
45 constexpr uint8_t A2DP_AAC_HEADER_48000[A2DP_AAC_HEADER_LEN] = {
46 0x47, 0xfc, 0x00, 0x00, 0xb0, 0x8c, 0x80, 0x03, 0x00,
47 };
48 } // namespace
49
A2dpAacEncoder()50 A2dpAacEncoder::A2dpAacEncoder() : avctx_(nullptr) {}
51
~A2dpAacEncoder()52 A2dpAacEncoder::~A2dpAacEncoder() { cleanup(); }
53
init(ConfigParam config)54 int A2dpAacEncoder::init(ConfigParam config) {
55 if (!config.has_a2dp_aac_encoder_param()) {
56 log::error("A2DP AAC Encoder params are not set");
57 return -EINVAL;
58 }
59
60 const AVCodec* codec = avcodec_find_encoder(AV_CODEC_ID_AAC);
61 if (!codec) {
62 log::error("Codec not found");
63 return -ENOENT;
64 }
65
66 if (!avctx_) {
67 avctx_ = avcodec_alloc_context3(codec);
68 if (!avctx_) {
69 log::error("Cannot allocate context");
70 return -EINVAL;
71 }
72 }
73
74 param_ = config.a2dp_aac_encoder_param();
75 const int channel_count = param_.channel_count();
76 const int sample_rate = param_.sample_rate();
77 const int bit_rate = param_.bit_rate();
78
79 if (channel_count == 1) {
80 AVChannelLayout mono = AV_CHANNEL_LAYOUT_MONO;
81 av_channel_layout_copy(&avctx_->ch_layout, &mono);
82 } else if (channel_count == 2) {
83 AVChannelLayout stereo = AV_CHANNEL_LAYOUT_STEREO;
84 av_channel_layout_copy(&avctx_->ch_layout, &stereo);
85 } else {
86 log::error("Invalid number of channels: {}", channel_count);
87 return -EINVAL;
88 }
89
90 if (sample_rate != 44100 && sample_rate != 48000) {
91 log::error("Unsupported sample rate: {}", sample_rate);
92 return -EINVAL;
93 }
94
95 avctx_->sample_rate = sample_rate;
96 avctx_->bit_rate = bit_rate;
97 avctx_->bit_rate_tolerance = 0;
98 avctx_->sample_fmt = AV_SAMPLE_FMT_FLTP;
99
100 int rc = avcodec_open2(avctx_, codec, NULL);
101 if (rc < 0) {
102 log::error("Could not open context: {}", rc);
103 return -EINVAL;
104 }
105
106 return avctx_->frame_size;
107 }
108
cleanup()109 void A2dpAacEncoder::cleanup() {
110 if (avctx_) {
111 avcodec_free_context(&avctx_);
112 avctx_ = nullptr;
113 }
114 }
115
transcode(uint8_t * i_buf,int i_len,uint8_t * o_buf,int o_len)116 int A2dpAacEncoder::transcode(uint8_t* i_buf, int i_len, uint8_t* o_buf,
117 int o_len) {
118 int rc;
119
120 AVFrame* frame = av_frame_alloc();
121 if (!frame) {
122 log::error("Could not alloc frame");
123 return -ENOMEM;
124 }
125
126 frame->nb_samples = avctx_->frame_size;
127 frame->format = avctx_->sample_fmt;
128 frame->sample_rate = avctx_->sample_rate;
129
130 rc = av_channel_layout_copy(&frame->ch_layout, &avctx_->ch_layout);
131 if (rc < 0) {
132 log::error("Failed to copy channel layout: {}", rc);
133 av_frame_free(&frame);
134 return -EINVAL;
135 }
136
137 rc = av_frame_get_buffer(frame, 0);
138 if (rc < 0) {
139 log::error("Failed to get buffer for frame: {}", rc);
140 av_frame_free(&frame);
141 return -EIO;
142 }
143
144 rc = av_frame_make_writable(frame);
145 if (rc < 0) {
146 log::error("Failed to make frame writable: {}", rc);
147 av_frame_free(&frame);
148 return -EIO;
149 }
150
151 const int bit_depth = param_.bit_depth();
152 const int bytes_per_sample = bit_depth / 8;
153 const float scaling_factor = (float)1 / (1 << (bit_depth - 1));
154
155 uint8_t* buff = i_buf;
156 float* data[] = {(float*)frame->data[0], (float*)frame->data[1]};
157
158 auto read_pcm = [](uint8_t* buff, int nbits) -> int {
159 int pcm = 0;
160
161 switch (nbits) {
162 case 16:
163 pcm = *((int16_t*)buff);
164 break;
165 case 24:
166 pcm = *buff | *(buff + 1) << 8 | *(buff + 2) << 16;
167 pcm |= pcm & 0x00800000 ? 0xff000000 : 0;
168 break;
169 case 32:
170 pcm = *((int32_t*)buff);
171 break;
172 default:
173 log::fatal("Attempting to read {} bits as bit depth", nbits);
174 }
175
176 return pcm;
177 };
178
179 for (int i = 0; i < i_len / bytes_per_sample; ++i) {
180 *data[i & 1]++ = read_pcm(buff, bit_depth) * scaling_factor;
181 buff += bytes_per_sample;
182 }
183
184 AVPacket* pkt = av_packet_alloc();
185 if (!pkt) {
186 log::error("Could not alloc packet");
187 return -ENOMEM;
188 }
189
190 rc = avcodec_send_frame(avctx_, frame);
191 if (rc < 0) {
192 log::error("Failed to send frame: {}", rc);
193 av_frame_free(&frame);
194 av_packet_free(&pkt);
195 return -EIO;
196 }
197
198 rc = avcodec_receive_packet(avctx_, pkt);
199 if (rc < 0 && rc != -EAGAIN) {
200 log::error("Failed to receive packet: {}", rc);
201 av_frame_free(&frame);
202 av_packet_free(&pkt);
203 return -EIO;
204 }
205
206 uint8_t* dst = o_buf;
207
208 const uint8_t* header = avctx_->sample_rate == 44100 ? A2DP_AAC_HEADER_44100
209 : A2DP_AAC_HEADER_48000;
210
211 std::copy(header, header + A2DP_AAC_HEADER_LEN, dst);
212
213 int written = A2DP_AAC_HEADER_LEN;
214 dst += written;
215
216 int cap = param_.effective_frame_size();
217 if (rc == -EAGAIN || cap < pkt->size + A2DP_AAC_MAX_PREFIX_SIZE) {
218 if (rc != -EAGAIN) {
219 log::warn("Dropped pkt: size={}, cap={}", pkt->size, cap);
220 }
221 static uint8_t silent_frame[7] = {
222 0x06, 0x21, 0x10, 0x04, 0x60, 0x8c, 0x1c,
223 };
224 std::copy(silent_frame, std::end(silent_frame), dst);
225 dst += sizeof(silent_frame);
226 written += sizeof(silent_frame);
227 } else {
228 int fsize = pkt->size;
229
230 while (fsize >= 255) {
231 *(dst++) = 0xff;
232 fsize -= 255;
233 ++written;
234 }
235 *(dst++) = fsize;
236 ++written;
237
238 std::copy(pkt->data, pkt->data + pkt->size, dst);
239 written += pkt->size;
240 }
241
242 av_packet_unref(pkt);
243 av_frame_free(&frame);
244 av_packet_free(&pkt);
245
246 return written;
247 }
248
249 } // namespace mmc
250