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