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