1 /*
2  * Copyright (C) 2016 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 #define LOG_TAG "bluetooth-a2dp"
18 
19 #include "a2dp_aac_decoder.h"
20 
21 #include <aacdecoder_lib.h>
22 #include <bluetooth/log.h>
23 
24 #include <cstddef>
25 #include <cstdint>
26 #include <cstring>
27 
28 #include "FDK_audio.h"
29 #include "a2dp_codec_api.h"
30 #include "machine_type.h"
31 #include "osi/include/allocator.h"
32 #include "stack/include/bt_hdr.h"
33 
34 #define DECODE_BUF_LEN (8 * 2 * 1024)
35 
36 using namespace bluetooth;
37 
38 typedef struct {
39   HANDLE_AACDECODER aac_handle;
40   bool has_aac_handle;  // True if aac_handle is valid
41   INT_PCM* decode_buf = nullptr;
42   decoded_data_callback_t decode_callback;
43 } tA2DP_AAC_DECODER_CB;
44 
45 static tA2DP_AAC_DECODER_CB a2dp_aac_decoder_cb;
46 
A2DP_LoadDecoderAac(void)47 bool A2DP_LoadDecoderAac(void) {
48   // Nothing to do - the library is statically linked
49   return true;
50 }
51 
A2DP_UnloadDecoderAac(void)52 void A2DP_UnloadDecoderAac(void) { a2dp_aac_decoder_cleanup(); }
53 
a2dp_aac_decoder_init(decoded_data_callback_t decode_callback)54 bool a2dp_aac_decoder_init(decoded_data_callback_t decode_callback) {
55   a2dp_aac_decoder_cleanup();
56 
57   a2dp_aac_decoder_cb.aac_handle = aacDecoder_Open(TT_MP4_LATM_MCP1, 1 /* nrOfLayers */);
58   a2dp_aac_decoder_cb.has_aac_handle = true;
59   a2dp_aac_decoder_cb.decode_buf = static_cast<INT_PCM*>(
60           osi_malloc(sizeof(a2dp_aac_decoder_cb.decode_buf[0]) * DECODE_BUF_LEN));
61   a2dp_aac_decoder_cb.decode_callback = decode_callback;
62   return true;
63 }
64 
a2dp_aac_decoder_cleanup(void)65 void a2dp_aac_decoder_cleanup(void) {
66   if (a2dp_aac_decoder_cb.has_aac_handle) {
67     aacDecoder_Close(a2dp_aac_decoder_cb.aac_handle);
68   }
69   osi_free(a2dp_aac_decoder_cb.decode_buf);
70   memset(&a2dp_aac_decoder_cb, 0, sizeof(a2dp_aac_decoder_cb));
71 }
72 
a2dp_aac_decoder_decode_packet(BT_HDR * p_buf)73 bool a2dp_aac_decoder_decode_packet(BT_HDR* p_buf) {
74   auto* pBuffer = reinterpret_cast<UCHAR*>(p_buf->data + p_buf->offset);
75   UINT bufferSize = p_buf->len;
76   UINT bytesValid = p_buf->len;
77   while (bytesValid > 0) {
78     AAC_DECODER_ERROR err =
79             aacDecoder_Fill(a2dp_aac_decoder_cb.aac_handle, &pBuffer, &bufferSize, &bytesValid);
80     if (err != AAC_DEC_OK) {
81       log::error("aacDecoder_Fill failed: 0x{:x}", static_cast<unsigned>(err));
82       return false;
83     }
84 
85     while (true) {
86       err = aacDecoder_DecodeFrame(a2dp_aac_decoder_cb.aac_handle, a2dp_aac_decoder_cb.decode_buf,
87                                    DECODE_BUF_LEN, 0 /* flags */);
88       if (err == AAC_DEC_NOT_ENOUGH_BITS) {
89         break;
90       }
91       if (err != AAC_DEC_OK) {
92         log::error("aacDecoder_DecodeFrame failed: 0x{:x}", static_cast<int>(err));
93         break;
94       }
95 
96       CStreamInfo* info = aacDecoder_GetStreamInfo(a2dp_aac_decoder_cb.aac_handle);
97       if (!info || info->sampleRate <= 0) {
98         log::error("Invalid stream info");
99         break;
100       }
101 
102       size_t frame_len =
103               info->frameSize * info->numChannels * sizeof(a2dp_aac_decoder_cb.decode_buf[0]);
104       a2dp_aac_decoder_cb.decode_callback(
105               reinterpret_cast<uint8_t*>(a2dp_aac_decoder_cb.decode_buf), frame_len);
106     }
107   }
108 
109   return true;
110 }
111