1 /******************************************************************************
2  *
3  *  Copyright 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_bitstream.h"
32 #include "oi_codec_sbc_private.h"
33 
34 #define SPECIALIZE_READ_SAMPLES_JOINT
35 
36 #if __has_attribute(fallthrough)
37 #define __fallthrough __attribute__((__fallthrough__))
38 #else
39 #define __fallthrough
40 #endif
41 
42 /**
43  * Scans through a buffer looking for a codec syncword. If the decoder has been
44  * set for enhanced operation using OI_CODEC_SBC_DecoderReset(), it will search
45  * for both a standard and an enhanced syncword.
46  */
FindSyncword(OI_CODEC_SBC_DECODER_CONTEXT * context,const OI_BYTE ** frameData,uint32_t * frameBytes)47 PRIVATE OI_STATUS FindSyncword(OI_CODEC_SBC_DECODER_CONTEXT* context, const OI_BYTE** frameData,
48                                uint32_t* frameBytes) {
49   if (*frameBytes == 0) {
50     return OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA;
51   }
52 
53   if (context->mSbcEnabled) {
54     while (*frameBytes && **frameData != OI_SBC_MSBC_SYNCWORD) {
55       (*frameBytes)--;
56       (*frameData)++;
57     }
58     if (*frameBytes == 0) {
59       return OI_CODEC_SBC_NO_SYNCWORD;
60     }
61     return OI_OK;
62   }
63 
64 #ifdef SBC_ENHANCED
65   OI_BYTE search1 = OI_SBC_SYNCWORD;
66   OI_BYTE search2 = OI_SBC_ENHANCED_SYNCWORD;
67 #endif  // SBC_ENHANCED
68 
69 #ifdef SBC_ENHANCED
70   if (context->limitFrameFormat && context->enhancedEnabled) {
71     /* If the context is restricted, only search for specified SYNCWORD */
72     search1 = search2;
73   } else if (context->enhancedEnabled == FALSE) {
74     /* If enhanced is not enabled, only search for classic SBC SYNCWORD*/
75     search2 = search1;
76   }
77   while (*frameBytes && (**frameData != search1) && (**frameData != search2)) {
78     (*frameBytes)--;
79     (*frameData)++;
80   }
81   if (*frameBytes) {
82     /* Syncword found, *frameData points to it, and *frameBytes correctly
83      * reflects the number of bytes available to read, including the
84      * syncword. */
85     context->common.frameInfo.enhanced = (**frameData == OI_SBC_ENHANCED_SYNCWORD);
86     return OI_OK;
87   } else {
88     /* No syncword was found anywhere in the provided input data.
89      * *frameData points past the end of the original input, and
90      * *frameBytes is 0. */
91     return OI_CODEC_SBC_NO_SYNCWORD;
92   }
93 #else   // SBC_ENHANCED
94   while (*frameBytes && (**frameData != OI_SBC_SYNCWORD)) {
95     (*frameBytes)--;
96     (*frameData)++;
97   }
98   if (*frameBytes) {
99     /* Syncword found, *frameData points to it, and *frameBytes correctly
100      * reflects the number of bytes available to read, including the
101      * syncword. */
102     context->common.frameInfo.enhanced = FALSE;
103     return OI_OK;
104   } else {
105     /* No syncword was found anywhere in the provided input data.
106      * *frameData points past the end of the original input, and
107      * *frameBytes is 0. */
108     return OI_CODEC_SBC_NO_SYNCWORD;
109   }
110 #endif  // SBC_ENHANCED
111 }
112 
DecodeBody(OI_CODEC_SBC_DECODER_CONTEXT * context,const OI_BYTE * bodyData,int16_t * pcmData,uint32_t * pcmBytes,OI_BOOL allowPartial)113 static OI_STATUS DecodeBody(OI_CODEC_SBC_DECODER_CONTEXT* context, const OI_BYTE* bodyData,
114                             int16_t* pcmData, uint32_t* pcmBytes, OI_BOOL allowPartial) {
115   OI_BITSTREAM bs;
116   OI_UINT frameSamples =
117           context->common.frameInfo.nrof_blocks * context->common.frameInfo.nrof_subbands;
118   OI_UINT decode_block_count;
119 
120   /*
121    * Based on the header data, make sure that there is enough room to write the
122    * output samples.
123    */
124   if (*pcmBytes < (sizeof(int16_t) * 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(int16_t) * context->common.frameInfo.nrof_subbands *
130                                  context->common.pcmStride) {
131     /* Even if we're allowing partials, we can still only decode on a frame
132      * boundary */
133     return OI_CODEC_SBC_NOT_ENOUGH_AUDIO_DATA;
134   }
135 
136   if (context->bufferedBlocks == 0) {
137     TRACE(("Reading scalefactors"));
138     OI_SBC_ReadScalefactors(&context->common, bodyData, &bs);
139 
140     TRACE(("Computing bit allocation"));
141     OI_SBC_ComputeBitAllocation(&context->common);
142 
143     TRACE(("Reading samples"));
144     if (context->common.frameInfo.mode == SBC_JOINT_STEREO) {
145       OI_SBC_ReadSamplesJoint(context, &bs);
146     } else {
147       OI_SBC_ReadSamples(context, &bs);
148     }
149 
150     context->bufferedBlocks = context->common.frameInfo.nrof_blocks;
151   }
152 
153   if (allowPartial) {
154     decode_block_count = *pcmBytes / sizeof(int16_t) / context->common.pcmStride /
155                          context->common.frameInfo.nrof_subbands;
156 
157     if (decode_block_count > context->bufferedBlocks) {
158       decode_block_count = context->bufferedBlocks;
159     }
160 
161   } else {
162     decode_block_count = context->common.frameInfo.nrof_blocks;
163   }
164 
165   TRACE(("Synthesizing frame"));
166   {
167     OI_UINT start_block = context->common.frameInfo.nrof_blocks - context->bufferedBlocks;
168     OI_SBC_SynthFrame(context, pcmData, start_block, decode_block_count);
169   }
170 
171   OI_ASSERT(context->bufferedBlocks >= decode_block_count);
172   context->bufferedBlocks -= decode_block_count;
173 
174   frameSamples = decode_block_count * context->common.frameInfo.nrof_subbands;
175 
176   /*
177    * When decoding mono into a stride-2 array, copy pcm data to second channel
178    */
179   if (context->common.frameInfo.nrof_channels == 1 && context->common.pcmStride == 2) {
180     OI_UINT i;
181     for (i = 0; i < frameSamples; ++i) {
182       pcmData[2 * i + 1] = pcmData[2 * i];
183     }
184   }
185 
186   /*
187    * Return number of pcm bytes generated by the decode operation.
188    */
189   *pcmBytes = frameSamples * sizeof(int16_t) * context->common.pcmStride;
190   if (context->bufferedBlocks > 0) {
191     return OI_CODEC_SBC_PARTIAL_DECODE;
192   } else {
193     return OI_OK;
194   }
195 }
196 
internal_DecodeRaw(OI_CODEC_SBC_DECODER_CONTEXT * context,uint8_t bitpool,const OI_BYTE ** frameData,uint32_t * frameBytes,int16_t * pcmData,uint32_t * pcmBytes)197 PRIVATE OI_STATUS internal_DecodeRaw(OI_CODEC_SBC_DECODER_CONTEXT* context, uint8_t bitpool,
198                                      const OI_BYTE** frameData, uint32_t* frameBytes,
199                                      int16_t* pcmData, uint32_t* pcmBytes) {
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 
OI_CODEC_SBC_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT * context,uint32_t * decoderData,uint32_t decoderDataBytes,uint8_t maxChannels,uint8_t pcmStride,OI_BOOL enhanced)234 OI_STATUS OI_CODEC_SBC_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT* context, uint32_t* decoderData,
235                                     uint32_t decoderDataBytes, uint8_t maxChannels,
236                                     uint8_t pcmStride, OI_BOOL enhanced) {
237   return internal_DecoderReset(context, decoderData, decoderDataBytes, maxChannels, pcmStride,
238                                enhanced);
239 }
240 
OI_CODEC_SBC_DecoderConfigureMSbc(OI_CODEC_SBC_DECODER_CONTEXT * context)241 OI_STATUS OI_CODEC_SBC_DecoderConfigureMSbc(OI_CODEC_SBC_DECODER_CONTEXT* context) {
242   context->mSbcEnabled = TRUE;
243   context->common.frameInfo.enhanced = FALSE;
244   context->common.frameInfo.freqIndex = SBC_FREQ_16000;
245   context->common.frameInfo.mode = SBC_MONO;
246   context->common.frameInfo.subbands = SBC_SUBBANDS_8;
247   context->common.frameInfo.blocks = SBC_BLOCKS_15;
248   context->common.frameInfo.alloc = SBC_LOUDNESS;
249   context->common.frameInfo.bitpool = 26;
250 
251   OI_SBC_ExpandFrameFields(&context->common.frameInfo);
252 
253   return OI_OK;
254 }
255 
OI_CODEC_SBC_DecodeFrame(OI_CODEC_SBC_DECODER_CONTEXT * context,const OI_BYTE ** frameData,uint32_t * frameBytes,int16_t * pcmData,uint32_t * pcmBytes)256 OI_STATUS OI_CODEC_SBC_DecodeFrame(OI_CODEC_SBC_DECODER_CONTEXT* context, const OI_BYTE** frameData,
257                                    uint32_t* frameBytes, int16_t* pcmData, uint32_t* pcmBytes) {
258   OI_STATUS status;
259   OI_UINT framelen;
260   uint8_t crc;
261 
262   TRACE(("+OI_CODEC_SBC_DecodeFrame"));
263 
264   TRACE(("Finding syncword"));
265   status = FindSyncword(context, frameData, frameBytes);
266   if (!OI_SUCCESS(status)) {
267     return status;
268   }
269 
270   /* Make sure enough data remains to read the header. */
271   if (*frameBytes < SBC_HEADER_LEN) {
272     TRACE(("-OI_CODEC_SBC_DecodeFrame: OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA"));
273     return OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA;
274   }
275 
276   if (context->mSbcEnabled) {
277     /*
278      * There is no parameter embedded in mSBC's header as the parameters are
279      * fixed unlike the general SBC. We only need the packet's crc for mSBC.
280      */
281     context->common.frameInfo.crc = (*frameData)[3];
282   } else {
283     TRACE(("Reading Header"));
284     OI_SBC_ReadHeader(&context->common, *frameData);
285   }
286   /*
287    * Some implementations load the decoder into RAM and use overlays for 4 vs 8
288    * subbands. We need
289    * to ensure that the SBC parameters for this frame are compatible with the
290    * restrictions imposed
291    * by the loaded overlays.
292    */
293   if (context->limitFrameFormat &&
294       (context->common.frameInfo.subbands != context->restrictSubbands)) {
295     ERROR("SBC parameters incompatible with loaded overlay");
296     return OI_STATUS_INVALID_PARAMETERS;
297   }
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
311    * a false syncword,
312    * so the header data might be invalid. Make sure we have enough bytes to read
313    * in the
314    * CRC-protected header, but don't require we have the whole frame. That way,
315    * if it turns out
316    * that we're acting on bogus header data, we don't stall the decoding process
317    * by waiting for
318    * data that we don't actually need.
319    */
320   framelen = OI_CODEC_SBC_CalculateFramelen(&context->common.frameInfo);
321   if (*frameBytes < framelen) {
322     TRACE(("-OI_CODEC_SBC_DecodeFrame: OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA"));
323     return OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA;
324   }
325 
326   TRACE(("Calculating checksum"));
327 
328   crc = OI_SBC_CalculateChecksum(&context->common.frameInfo, *frameData);
329   if (crc != context->common.frameInfo.crc) {
330     TRACE(("CRC Mismatch:  calc=%02x read=%02x\n", crc, context->common.frameInfo.crc));
331     TRACE(("-OI_CODEC_SBC_DecodeFrame: OI_CODEC_SBC_CHECKSUM_MISMATCH"));
332     return OI_CODEC_SBC_CHECKSUM_MISMATCH;
333   }
334 
335   /*
336    * Make sure the bitpool values are sane.
337    */
338   if ((context->common.frameInfo.bitpool < SBC_MIN_BITPOOL) &&
339       !context->common.frameInfo.enhanced) {
340     ERROR(("Bitpool too small: %d (must be >= 2)", context->common.frameInfo.bitpool));
341     return OI_STATUS_INVALID_PARAMETERS;
342   }
343   if (context->common.frameInfo.bitpool > OI_SBC_MaxBitpool(&context->common.frameInfo)) {
344     ERROR(("Bitpool too large: %d (must be <= %ld)", context->common.frameInfo.bitpool,
345           OI_SBC_MaxBitpool(&context->common.frameInfo)));
346     return OI_STATUS_INVALID_PARAMETERS;
347   }
348 
349   /*
350    * Now decode the SBC data. Partial decode is not yet implemented for an SBC
351    * stream, so pass FALSE to decode body to have it enforce the old rule that
352    * you have to decode a whole packet at a time.
353    */
354   status = DecodeBody(context, *frameData + SBC_HEADER_LEN, pcmData, pcmBytes, FALSE);
355   if (OI_SUCCESS(status)) {
356     *frameData += framelen;
357     *frameBytes -= framelen;
358   }
359   TRACE(("-OI_CODEC_SBC_DecodeFrame: %d", status));
360 
361   /* mSBC is designed with 8 bits of zeros at the end for padding. */
362   if (context->mSbcEnabled) {
363     *frameBytes -= 1;
364   }
365 
366   return status;
367 }
368 
OI_CODEC_SBC_SkipFrame(OI_CODEC_SBC_DECODER_CONTEXT * context,const OI_BYTE ** frameData,uint32_t * frameBytes)369 OI_STATUS OI_CODEC_SBC_SkipFrame(OI_CODEC_SBC_DECODER_CONTEXT* context, const OI_BYTE** frameData,
370                                  uint32_t* frameBytes) {
371   OI_STATUS status;
372   OI_UINT framelen;
373   OI_UINT headerlen;
374   uint8_t 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 
OI_CODEC_SBC_FrameCount(OI_BYTE * frameData,uint32_t frameBytes)401 uint8_t OI_CODEC_SBC_FrameCount(OI_BYTE* frameData, uint32_t frameBytes) {
402   uint8_t mode;
403   uint8_t blocks;
404   uint8_t subbands;
405   uint8_t 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     ;
421     mode = (mode & (BIT3 | BIT2)) >> 2;
422     blocks = block_values[(blocks & (BIT5 | BIT4)) >> 4];
423     subbands = band_values[(subbands & BIT0)];
424 
425     /* Inline logic to avoid corrupting context */
426     frameLen = blocks * frameData[2];
427     switch (mode) {
428       case SBC_JOINT_STEREO:
429         frameLen += subbands + (8 * subbands);
430         break;
431 
432       case SBC_DUAL_CHANNEL:
433         frameLen *= 2;
434         __fallthrough;
435 
436       default:
437         if (mode == SBC_MONO) {
438           frameLen += 4 * subbands;
439         } else {
440           frameLen += 8 * subbands;
441         }
442     }
443 
444     frameCount++;
445     frameLen = SBC_HEADER_LEN + (frameLen + 7) / 8;
446     if (frameBytes > frameLen) {
447       frameBytes -= frameLen;
448       frameData += frameLen;
449     } else {
450       frameBytes = 0;
451     }
452   }
453   return frameCount;
454 }
455 
456 /** Read quantized subband samples from the input bitstream and expand them. */
457 
458 #ifdef SPECIALIZE_READ_SAMPLES_JOINT
459 
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,
461                                       OI_BITSTREAM* global_bs) {
462 #define NROF_SUBBANDS 4
463 #include "readsamplesjoint.inc"
464 #undef NROF_SUBBANDS
465 }
466 
OI_SBC_ReadSamplesJoint8(OI_CODEC_SBC_DECODER_CONTEXT * context,OI_BITSTREAM * global_bs)467 PRIVATE void OI_SBC_ReadSamplesJoint8(OI_CODEC_SBC_DECODER_CONTEXT* context,
468                                       OI_BITSTREAM* global_bs) {
469 #define NROF_SUBBANDS 8
470 #include "readsamplesjoint.inc"
471 #undef NROF_SUBBANDS
472 }
473 
474 typedef void (*READ_SAMPLES)(OI_CODEC_SBC_DECODER_CONTEXT* context, OI_BITSTREAM* global_bs);
475 
476 static const READ_SAMPLES SpecializedReadSamples[] = {OI_SBC_ReadSamplesJoint4,
477                                                       OI_SBC_ReadSamplesJoint8};
478 
479 #endif /* SPECIALIZE_READ_SAMPLES_JOINT */
480 
OI_SBC_ReadSamplesJoint(OI_CODEC_SBC_DECODER_CONTEXT * context,OI_BITSTREAM * global_bs)481 PRIVATE void OI_SBC_ReadSamplesJoint(OI_CODEC_SBC_DECODER_CONTEXT* context,
482                                      OI_BITSTREAM* global_bs) {
483   OI_CODEC_SBC_COMMON_CONTEXT* common = &context->common;
484   OI_UINT nrof_subbands = common->frameInfo.nrof_subbands;
485 #ifdef SPECIALIZE_READ_SAMPLES_JOINT
486   OI_ASSERT((nrof_subbands >> 3u) <= 1u);
487   SpecializedReadSamples[nrof_subbands >> 3](context, global_bs);
488 #else
489 
490 #define NROF_SUBBANDS nrof_subbands
491 #include "readsamplesjoint.inc"
492 #undef NROF_SUBBANDS
493 #endif /* SPECIALIZE_READ_SAMPLES_JOINT */
494 }
495 
496 /**@}*/
497