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