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, int o_len) {
117 int rc;
118
119 AVFrame* frame = av_frame_alloc();
120 if (!frame) {
121 log::error("Could not alloc frame");
122 return -ENOMEM;
123 }
124
125 frame->nb_samples = avctx_->frame_size;
126 frame->format = avctx_->sample_fmt;
127 frame->sample_rate = avctx_->sample_rate;
128
129 rc = av_channel_layout_copy(&frame->ch_layout, &avctx_->ch_layout);
130 if (rc < 0) {
131 log::error("Failed to copy channel layout: {}", rc);
132 av_frame_free(&frame);
133 return -EINVAL;
134 }
135
136 rc = av_frame_get_buffer(frame, 0);
137 if (rc < 0) {
138 log::error("Failed to get buffer for frame: {}", rc);
139 av_frame_free(&frame);
140 return -EIO;
141 }
142
143 rc = av_frame_make_writable(frame);
144 if (rc < 0) {
145 log::error("Failed to make frame writable: {}", rc);
146 av_frame_free(&frame);
147 return -EIO;
148 }
149
150 const int bit_depth = param_.bit_depth();
151 const int bytes_per_sample = bit_depth / 8;
152 const float scaling_factor = (float)1 / (1 << (bit_depth - 1));
153
154 uint8_t* buff = i_buf;
155 float* data[] = {(float*)frame->data[0], (float*)frame->data[1]};
156
157 auto read_pcm = [](uint8_t* buff, int nbits) -> int {
158 int pcm = 0;
159
160 switch (nbits) {
161 case 16:
162 pcm = *((int16_t*)buff);
163 break;
164 case 24:
165 pcm = *buff | *(buff + 1) << 8 | *(buff + 2) << 16;
166 pcm |= pcm & 0x00800000 ? 0xff000000 : 0;
167 break;
168 case 32:
169 pcm = *((int32_t*)buff);
170 break;
171 default:
172 log::fatal("Attempting to read {} bits as bit depth", nbits);
173 }
174
175 return pcm;
176 };
177
178 for (int i = 0; i < i_len / bytes_per_sample; ++i) {
179 *data[i & 1]++ = read_pcm(buff, bit_depth) * scaling_factor;
180 buff += bytes_per_sample;
181 }
182
183 AVPacket* pkt = av_packet_alloc();
184 if (!pkt) {
185 log::error("Could not alloc packet");
186 return -ENOMEM;
187 }
188
189 rc = avcodec_send_frame(avctx_, frame);
190 if (rc < 0) {
191 log::error("Failed to send frame: {}", rc);
192 av_frame_free(&frame);
193 av_packet_free(&pkt);
194 return -EIO;
195 }
196
197 rc = avcodec_receive_packet(avctx_, pkt);
198 if (rc < 0 && rc != -EAGAIN) {
199 log::error("Failed to receive packet: {}", rc);
200 av_frame_free(&frame);
201 av_packet_free(&pkt);
202 return -EIO;
203 }
204
205 uint8_t* dst = o_buf;
206
207 const uint8_t* header =
208 avctx_->sample_rate == 44100 ? A2DP_AAC_HEADER_44100 : A2DP_AAC_HEADER_48000;
209
210 std::copy(header, header + A2DP_AAC_HEADER_LEN, dst);
211
212 int written = A2DP_AAC_HEADER_LEN;
213 dst += written;
214
215 int cap = param_.effective_frame_size();
216 if (rc == -EAGAIN || cap < pkt->size + A2DP_AAC_MAX_PREFIX_SIZE) {
217 if (rc != -EAGAIN) {
218 log::warn("Dropped pkt: size={}, cap={}", pkt->size, cap);
219 }
220 static uint8_t silent_frame[7] = {
221 0x06, 0x21, 0x10, 0x04, 0x60, 0x8c, 0x1c,
222 };
223 std::copy(silent_frame, std::end(silent_frame), dst);
224 dst += sizeof(silent_frame);
225 written += sizeof(silent_frame);
226 } else {
227 int fsize = pkt->size;
228
229 while (fsize >= 255) {
230 *(dst++) = 0xff;
231 fsize -= 255;
232 ++written;
233 }
234 *(dst++) = fsize;
235 ++written;
236
237 std::copy(pkt->data, pkt->data + pkt->size, dst);
238 written += pkt->size;
239 }
240
241 av_packet_unref(pkt);
242 av_frame_free(&frame);
243 av_packet_free(&pkt);
244
245 return written;
246 }
247
248 } // namespace mmc
249