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