xref: /btstack/3rd-party/bluedroid/decoder/srce/decoder-sbc.c (revision 435e3c4e0d833cf29306bcbe25c84a0f767a8539)
1 /******************************************************************************
2  *
3  *  Copyright (C) 2014 The Android Open Source Project
4  *  Copyright 2006 Open Interface North America, Inc. All rights reserved.
5  *
6  *  Licensed under the Apache License, Version 2.0 (the "License");
7  *  you may not use this file except in compliance with the License.
8  *  You may obtain a copy of the License at:
9  *
10  *  http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *  Unless required by applicable law or agreed to in writing, software
13  *  distributed under the License is distributed on an "AS IS" BASIS,
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *  See the License for the specific language governing permissions and
16  *  limitations under the License.
17  *
18  ******************************************************************************/
19 
20 /**********************************************************************************
21   $Revision: #1 $
22  ***********************************************************************************/
23 
24 /** @file
25 @ingroup codec_internal
26 */
27 
28 /**@addtogroup codec_internal */
29 /**@{*/
30 
31 #include "oi_codec_sbc_private.h"
32 #include "oi_bitstream.h"
33 
34 #define SPECIALIZE_READ_SAMPLES_JOINT
35 
36 /**
37  * Scans through a buffer looking for a codec syncword. If the decoder has been
38  * set for enhanced operation using OI_CODEC_SBC_DecoderReset(), it will search
39  * for both a standard and an enhanced syncword.
40  */
41 PRIVATE OI_STATUS FindSyncword(OI_CODEC_SBC_DECODER_CONTEXT *context,
42                                const OI_BYTE **frameData,
43                                OI_UINT32 *frameBytes)
44 {
45 #ifdef SBC_ENHANCED
46     OI_BYTE search1 = OI_SBC_SYNCWORD;
47     OI_BYTE search2 = OI_SBC_ENHANCED_SYNCWORD;
48 #endif // SBC_ENHANCED
49 
50     if (*frameBytes == 0) {
51         return OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA;
52     }
53 
54 #ifdef SBC_ENHANCED
55     if (context->limitFrameFormat && context->enhancedEnabled){
56         /* If the context is restricted, only search for specified SYNCWORD */
57         search1 = search2;
58     } else if (context->enhancedEnabled == FALSE) {
59         /* If enhanced is not enabled, only search for classic SBC SYNCWORD*/
60         search2 = search1;
61     }
62     while (*frameBytes && (**frameData != search1) && (**frameData != search2)) {
63         (*frameBytes)--;
64         (*frameData)++;
65     }
66     if (*frameBytes) {
67         /* Syncword found, *frameData points to it, and *frameBytes correctly
68          * reflects the number of bytes available to read, including the
69          * syncword. */
70         context->common.frameInfo.enhanced = (**frameData == OI_SBC_ENHANCED_SYNCWORD);
71         return OI_OK;
72     } else {
73         /* No syncword was found anywhere in the provided input data.
74          * *frameData points past the end of the original input, and
75          * *frameBytes is 0. */
76         return OI_CODEC_SBC_NO_SYNCWORD;
77     }
78 #else  // SBC_ENHANCED
79     /* BK4BTSTACK_CHANGE START */
80     OI_UINT8 syncword = OI_SBC_SYNCWORD;
81     if (context->common.mSBCEnabled){
82         syncword = OI_mSBC_SYNCWORD;
83     }
84     /* BK4BTSTACK_CHANGE END */
85     while (*frameBytes && (**frameData != syncword)) {
86         (*frameBytes)--;
87         (*frameData)++;
88     }
89 
90     if (*frameBytes) {
91         /* Syncword found, *frameData points to it, and *frameBytes correctly
92          * reflects the number of bytes available to read, including the
93          * syncword. */
94         context->common.frameInfo.enhanced = FALSE;
95         return OI_OK;
96     } else {
97         /* No syncword was found anywhere in the provided input data.
98          * *frameData points past the end of the original input, and
99          * *frameBytes is 0. */
100         return OI_CODEC_SBC_NO_SYNCWORD;
101     }
102 #endif // SBC_ENHANCED
103 }
104 
105 
106 static OI_STATUS DecodeBody(OI_CODEC_SBC_DECODER_CONTEXT *context,
107                             const OI_BYTE *bodyData,
108                             OI_INT16 *pcmData,
109                             OI_UINT32 *pcmBytes,
110                             OI_BOOL allowPartial)
111 {
112     OI_BITSTREAM bs;
113     OI_UINT frameSamples = context->common.frameInfo.nrof_blocks * context->common.frameInfo.nrof_subbands;
114     OI_UINT decode_block_count;
115 
116     /*
117      * Based on the header data, make sure that there is enough room to write the output samples.
118      */
119     if (*pcmBytes < (sizeof(OI_INT16) * frameSamples * context->common.pcmStride) && !allowPartial) {
120         /* If we're not allowing partial decodes, we need room for the entire
121          * codec frame */
122         TRACE(("-OI_CODEC_SBC_Decode: OI_CODEC_SBC_NOT_ENOUGH_AUDIO_DATA"));
123         return OI_CODEC_SBC_NOT_ENOUGH_AUDIO_DATA;
124     } else if (*pcmBytes < sizeof (OI_INT16) * context->common.frameInfo.nrof_subbands * context->common.pcmStride) {
125         /* Even if we're allowing partials, we can still only decode on a frame
126          * boundary */
127         return OI_CODEC_SBC_NOT_ENOUGH_AUDIO_DATA;
128     }
129 
130     if (context->bufferedBlocks == 0) {
131         TRACE(("Reading scalefactors"));
132         OI_SBC_ReadScalefactors(&context->common, bodyData, &bs);
133 
134         TRACE(("Computing bit allocation"));
135         OI_SBC_ComputeBitAllocation(&context->common);
136 
137         TRACE(("Reading samples"));
138         if (context->common.frameInfo.mode == SBC_JOINT_STEREO) {
139             OI_SBC_ReadSamplesJoint(context, &bs);
140         } else {
141             OI_SBC_ReadSamples(context, &bs);
142         }
143 
144         context->bufferedBlocks = context->common.frameInfo.nrof_blocks;
145     }
146 
147     if (allowPartial) {
148         decode_block_count = *pcmBytes / sizeof(OI_INT16) / context->common.pcmStride / context->common.frameInfo.nrof_subbands;
149 
150         if (decode_block_count > context->bufferedBlocks) {
151             decode_block_count = context->bufferedBlocks;
152         }
153 
154     } else {
155         decode_block_count = context->common.frameInfo.nrof_blocks;
156     }
157 
158     TRACE(("Synthesizing frame"));
159     {
160         OI_UINT start_block = context->common.frameInfo.nrof_blocks - context->bufferedBlocks;
161         OI_SBC_SynthFrame(context, pcmData, start_block, decode_block_count);
162     }
163 
164     OI_ASSERT(context->bufferedBlocks >= decode_block_count);
165     context->bufferedBlocks -= decode_block_count;
166 
167     frameSamples = decode_block_count * context->common.frameInfo.nrof_subbands;
168 
169     /*
170      * When decoding mono into a stride-2 array, copy pcm data to second channel
171      */
172     if (context->common.frameInfo.nrof_channels == 1 && context->common.pcmStride == 2) {
173         OI_UINT i;
174         for (i = 0; i < frameSamples; ++i) {
175             pcmData[2*i+1] = pcmData[2*i];
176         }
177     }
178 
179     /*
180      * Return number of pcm bytes generated by the decode operation.
181      */
182     *pcmBytes = frameSamples * sizeof(OI_INT16) * context->common.pcmStride;
183 
184     if (context->bufferedBlocks > 0) {
185         return OI_CODEC_SBC_PARTIAL_DECODE;
186     } else {
187         return OI_OK;
188     }
189 }
190 
191 PRIVATE OI_STATUS internal_DecodeRaw(OI_CODEC_SBC_DECODER_CONTEXT *context,
192                                      OI_UINT8 bitpool,
193                                      const OI_BYTE **frameData,
194                                      OI_UINT32 *frameBytes,
195                                      OI_INT16 *pcmData,
196                                      OI_UINT32 *pcmBytes)
197 {
198     OI_STATUS status;
199     OI_UINT bodyLen;
200 
201     TRACE(("+OI_CODEC_SBC_DecodeRaw"));
202 
203     if (context->bufferedBlocks == 0) {
204         /*
205          * The bitallocator needs to know the bitpool value.
206          */
207         context->common.frameInfo.bitpool = bitpool;
208         /*
209          * Compute the frame length and check we have enough frame data to proceed
210          */
211         bodyLen = OI_CODEC_SBC_CalculateFramelen(&context->common.frameInfo) - SBC_HEADER_LEN;
212         if (*frameBytes < bodyLen) {
213             TRACE(("-OI_CODEC_SBC_Decode: OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA"));
214             return OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA;
215         }
216     } else {
217         bodyLen = 0;
218     }
219     /*
220      * Decode the SBC data. Pass TRUE to DecodeBody to allow partial decoding of
221      * tones.
222      */
223     status = DecodeBody(context, *frameData, pcmData, pcmBytes, TRUE);
224     if (OI_SUCCESS(status) || status == OI_CODEC_SBC_PARTIAL_DECODE) {
225         *frameData += bodyLen;
226         *frameBytes -= bodyLen;
227     }
228     TRACE(("-OI_CODEC_SBC_DecodeRaw: %d", status));
229     return status;
230 }
231 
232 
233 OI_STATUS OI_CODEC_SBC_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT *context,
234                                     OI_UINT32 *decoderData,
235                                     OI_UINT32 decoderDataBytes,
236                                     OI_UINT8 maxChannels,
237                                     OI_UINT8 pcmStride,
238                                     OI_BOOL enhanced)
239 {
240     return internal_DecoderReset(context, decoderData, decoderDataBytes, maxChannels, pcmStride, enhanced);
241 }
242 
243 /* BK4BTSTACK_CHANGE START */
244 OI_STATUS OI_CODEC_mSBC_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT *context,
245                                     OI_UINT32 *decoderData,
246                                     OI_UINT32 decoderDataBytes)
247 {
248     OI_STATUS status = OI_CODEC_SBC_DecoderReset(context, decoderData, decoderDataBytes, 1, 1, FALSE);
249     context->common.mSBCEnabled = TRUE;
250     return status;
251 }
252 /* BK4BTSTACK_CHANGE END */
253 
254 OI_STATUS OI_CODEC_SBC_DecodeFrame(OI_CODEC_SBC_DECODER_CONTEXT *context,
255                                    const OI_BYTE **frameData,
256                                    OI_UINT32 *frameBytes,
257                                    OI_INT16 *pcmData,
258                                    OI_UINT32 *pcmBytes)
259 {
260     OI_STATUS status;
261     OI_UINT framelen;
262     OI_UINT8 crc;
263 
264     TRACE(("+OI_CODEC_SBC_DecodeFrame"));
265 
266     TRACE(("Finding syncword"));
267 
268     status = FindSyncword(context, frameData, frameBytes);
269     if (!OI_SUCCESS(status)) {
270         return status;
271     }
272     /* Make sure enough data remains to read the header. */
273     if (*frameBytes < SBC_HEADER_LEN) {
274         TRACE(("-OI_CODEC_SBC_DecodeFrame: OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA"));
275         return OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA;
276     }
277 
278     TRACE(("Reading Header"));
279     OI_SBC_ReadHeader(&context->common, *frameData);
280 
281     /*
282      * Some implementations load the decoder into RAM and use overlays for 4 vs 8 subbands. We need
283      * to ensure that the SBC parameters for this frame are compatible with the restrictions imposed
284      * by the loaded overlays.
285      */
286     if (context->limitFrameFormat && (context->common.frameInfo.subbands != context->restrictSubbands)) {
287         ERROR(("SBC parameters incompatible with loaded overlay"));
288         return OI_STATUS_INVALID_PARAMETERS;
289     }
290     TRACE(("Frame: "));
291 
292     if (context->common.frameInfo.nrof_channels > context->common.maxChannels) {
293         ERROR(("SBC parameters incompatible with number of channels specified during reset"));
294         return OI_STATUS_INVALID_PARAMETERS;
295     }
296 
297     if (context->common.pcmStride < 1 || context->common.pcmStride > 2) {
298         ERROR(("PCM stride not set correctly during reset"));
299         return OI_STATUS_INVALID_PARAMETERS;
300     }
301 
302     /*
303      * At this point a header has been read. However, it's possible that we found a false syncword,
304      * so the header data might be invalid. Make sure we have enough bytes to read in the
305      * CRC-protected header, but don't require we have the whole frame. That way, if it turns out
306      * that we're acting on bogus header data, we don't stall the decoding process by waiting for
307      * data that we don't actually need.
308      */
309     framelen = OI_CODEC_SBC_CalculateFramelen(&context->common.frameInfo);
310     if (*frameBytes < framelen) {
311         TRACE(("-OI_CODEC_SBC_DecodeFrame: OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA"));
312         return OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA;
313     }
314     TRACE(("frame len %d\n", framelen));
315 
316     TRACE(("Calculating checksum"));
317 
318     crc = OI_SBC_CalculateChecksum(&context->common.frameInfo, *frameData);
319     if (crc != context->common.frameInfo.crc) {
320         TRACE(("CRC Mismatch:  calc=%02x read=%02x\n", crc, context->common.frameInfo.crc));
321         TRACE(("-OI_CODEC_SBC_DecodeFrame: OI_CODEC_SBC_CHECKSUM_MISMATCH"));
322         return OI_CODEC_SBC_CHECKSUM_MISMATCH;
323     }
324 
325 #ifdef OI_DEBUG
326     /*
327      * Make sure the bitpool values are sane.
328      */
329     if ((context->common.frameInfo.bitpool < SBC_MIN_BITPOOL) && !context->common.frameInfo.enhanced) {
330         ERROR(("Bitpool too small: %d (must be >= 2)", context->common.frameInfo.bitpool));
331         return OI_STATUS_INVALID_PARAMETERS;
332     }
333     if (context->common.frameInfo.bitpool > OI_SBC_MaxBitpool(&context->common.frameInfo)) {
334         ERROR(("Bitpool too large: %d (must be <= %ld)", context->common.frameInfo.bitpool, OI_SBC_MaxBitpool(&context->common.frameInfo)));
335         return OI_STATUS_INVALID_PARAMETERS;
336     }
337 #endif
338 
339     /*
340      * Now decode the SBC data. Partial decode is not yet implemented for an SBC
341      * stream, so pass FALSE to decode body to have it enforce the old rule that
342      * you have to decode a whole packet at a time.
343      */
344     status = DecodeBody(context, *frameData + SBC_HEADER_LEN, pcmData, pcmBytes, FALSE);
345     if (OI_SUCCESS(status)) {
346         *frameData += framelen;
347         *frameBytes -= framelen;
348     }
349     TRACE(("-OI_CODEC_SBC_DecodeFrame: %d", status));
350 
351     return status;
352 }
353 
354 OI_STATUS OI_CODEC_SBC_SkipFrame(OI_CODEC_SBC_DECODER_CONTEXT *context,
355                                  const OI_BYTE **frameData,
356                                  OI_UINT32 *frameBytes)
357 {
358     OI_STATUS status;
359     OI_UINT framelen;
360     OI_UINT headerlen;
361     OI_UINT8 crc;
362 
363     status = FindSyncword(context, frameData, frameBytes);
364     if (!OI_SUCCESS(status)) {
365         return status;
366     }
367     if (*frameBytes < SBC_HEADER_LEN) {
368         return OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA;
369     }
370     OI_SBC_ReadHeader(&context->common, *frameData);
371     framelen = OI_SBC_CalculateFrameAndHeaderlen(&context->common.frameInfo, &headerlen);
372     if (*frameBytes < headerlen) {
373         return OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA;
374     }
375     crc = OI_SBC_CalculateChecksum(&context->common.frameInfo, *frameData);
376     if (crc != context->common.frameInfo.crc) {
377         return OI_CODEC_SBC_CHECKSUM_MISMATCH;
378     }
379     if (*frameBytes < framelen) {
380         return OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA;
381     }
382     context->bufferedBlocks = 0;
383     *frameData += framelen;
384     *frameBytes -= framelen;
385     return OI_OK;
386 }
387 
388 OI_UINT8 OI_CODEC_SBC_FrameCount(OI_BYTE  *frameData,
389                                  OI_UINT32 frameBytes)
390 {
391     OI_UINT8 mode;
392     OI_UINT8 blocks;
393     OI_UINT8 subbands;
394     OI_UINT8 frameCount = 0;
395     OI_UINT  frameLen;
396 
397     while (frameBytes){
398         while (frameBytes && ((frameData[0] & 0xFE) != 0x9C)){
399             frameData++;
400             frameBytes--;
401         }
402 
403         if (frameBytes < SBC_HEADER_LEN) {
404             return frameCount;
405         }
406 
407         /* Extract and translate required fields from Header */
408         subbands = mode = blocks = frameData[1];;
409         mode = (mode & (BIT3 | BIT2)) >> 2;
410         blocks = block_values[(blocks & (BIT5 | BIT4)) >> 4];
411         subbands = band_values[(subbands & BIT0)];
412 
413         /* Inline logic to avoid corrupting context */
414         frameLen = blocks * frameData[2];
415         switch (mode){
416             case SBC_JOINT_STEREO:
417                 frameLen += subbands + (8 * subbands);
418                 break;
419 
420             case SBC_DUAL_CHANNEL:
421                 frameLen *= 2;
422                 /* fall through */
423 
424             default:
425                 if (mode == SBC_MONO){
426                     frameLen += 4*subbands;
427                 } else {
428                     frameLen += 8*subbands;
429                 }
430         }
431 
432         frameCount++;
433         frameLen = SBC_HEADER_LEN + (frameLen + 7) / 8;
434         if (frameBytes > frameLen){
435             frameBytes -= frameLen;
436             frameData += frameLen;
437         } else {
438             frameBytes = 0;
439         }
440     }
441     return frameCount;
442 }
443 
444 /** Read quantized subband samples from the input bitstream and expand them. */
445 
446 #ifdef SPECIALIZE_READ_SAMPLES_JOINT
447 
448 PRIVATE void OI_SBC_ReadSamplesJoint4(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_BITSTREAM *global_bs)
449 {
450 #define NROF_SUBBANDS 4
451 #include "readsamplesjoint.inc"
452 #undef NROF_SUBBANDS
453 }
454 
455 PRIVATE void OI_SBC_ReadSamplesJoint8(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_BITSTREAM *global_bs)
456 {
457 #define NROF_SUBBANDS 8
458 #include "readsamplesjoint.inc"
459 #undef NROF_SUBBANDS
460 }
461 
462 typedef void (*READ_SAMPLES)(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_BITSTREAM *global_bs);
463 
464 static const READ_SAMPLES SpecializedReadSamples[] = {
465     OI_SBC_ReadSamplesJoint4,
466     OI_SBC_ReadSamplesJoint8
467 };
468 
469 #endif /* SPECIALIZE_READ_SAMPLES_JOINT */
470 
471 
472 PRIVATE void OI_SBC_ReadSamplesJoint(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_BITSTREAM *global_bs)
473 {
474     OI_CODEC_SBC_COMMON_CONTEXT *common = &context->common;
475     OI_UINT nrof_subbands = common->frameInfo.nrof_subbands;
476 #ifdef SPECIALIZE_READ_SAMPLES_JOINT
477     OI_ASSERT((nrof_subbands >> 3u) <= 1u);
478     SpecializedReadSamples[nrof_subbands >> 3](context, global_bs);
479 #else
480 
481 #define NROF_SUBBANDS nrof_subbands
482 #include "readsamplesjoint.inc"
483 #undef NROF_SUBBANDS
484 #endif /* SPECIALIZE_READ_SAMPLES_JOINT */
485 }
486 
487 /**@}*/
488 
489