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_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 */
41PRIVATE 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
98static 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
189PRIVATE 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
228OI_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
237OI_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#ifdef OI_DEBUG
315  /*
316   * Make sure the bitpool values are sane.
317   */
318  if ((context->common.frameInfo.bitpool < SBC_MIN_BITPOOL) &&
319      !context->common.frameInfo.enhanced) {
320    ERROR(("Bitpool too small: %d (must be >= 2)",
321           context->common.frameInfo.bitpool));
322    return OI_STATUS_INVALID_PARAMETERS;
323  }
324  if (context->common.frameInfo.bitpool >
325      OI_SBC_MaxBitpool(&context->common.frameInfo)) {
326    ERROR(("Bitpool too large: %d (must be <= %ld)",
327           context->common.frameInfo.bitpool,
328           OI_SBC_MaxBitpool(&context->common.frameInfo)));
329    return OI_STATUS_INVALID_PARAMETERS;
330  }
331#endif
332
333  /*
334   * Now decode the SBC data. Partial decode is not yet implemented for an SBC
335   * stream, so pass FALSE to decode body to have it enforce the old rule that
336   * you have to decode a whole packet at a time.
337   */
338  status = DecodeBody(context, *frameData + SBC_HEADER_LEN, pcmData, pcmBytes,
339                      FALSE);
340  if (OI_SUCCESS(status)) {
341    *frameData += framelen;
342    *frameBytes -= framelen;
343  }
344  TRACE(("-OI_CODEC_SBC_DecodeFrame: %d", status));
345
346  return status;
347}
348
349OI_STATUS OI_CODEC_SBC_SkipFrame(OI_CODEC_SBC_DECODER_CONTEXT* context,
350                                 const OI_BYTE** frameData,
351                                 uint32_t* frameBytes) {
352  OI_STATUS status;
353  OI_UINT framelen;
354  OI_UINT headerlen;
355  uint8_t crc;
356
357  status = FindSyncword(context, frameData, frameBytes);
358  if (!OI_SUCCESS(status)) {
359    return status;
360  }
361  if (*frameBytes < SBC_HEADER_LEN) {
362    return OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA;
363  }
364  OI_SBC_ReadHeader(&context->common, *frameData);
365  framelen =
366      OI_SBC_CalculateFrameAndHeaderlen(&context->common.frameInfo, &headerlen);
367  if (*frameBytes < headerlen) {
368    return OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA;
369  }
370  crc = OI_SBC_CalculateChecksum(&context->common.frameInfo, *frameData);
371  if (crc != context->common.frameInfo.crc) {
372    return OI_CODEC_SBC_CHECKSUM_MISMATCH;
373  }
374  if (*frameBytes < framelen) {
375    return OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA;
376  }
377  context->bufferedBlocks = 0;
378  *frameData += framelen;
379  *frameBytes -= framelen;
380  return OI_OK;
381}
382
383uint8_t OI_CODEC_SBC_FrameCount(OI_BYTE* frameData, uint32_t frameBytes) {
384  uint8_t mode;
385  uint8_t blocks;
386  uint8_t subbands;
387  uint8_t frameCount = 0;
388  OI_UINT frameLen;
389
390  while (frameBytes) {
391    while (frameBytes && ((frameData[0] & 0xFE) != 0x9C)) {
392      frameData++;
393      frameBytes--;
394    }
395
396    if (frameBytes < SBC_HEADER_LEN) {
397      return frameCount;
398    }
399
400    /* Extract and translate required fields from Header */
401    subbands = mode = blocks = frameData[1];
402    ;
403    mode = (mode & (BIT3 | BIT2)) >> 2;
404    blocks = block_values[(blocks & (BIT5 | BIT4)) >> 4];
405    subbands = band_values[(subbands & BIT0)];
406
407    /* Inline logic to avoid corrupting context */
408    frameLen = blocks * frameData[2];
409    switch (mode) {
410      case SBC_JOINT_STEREO:
411        frameLen += subbands + (8 * subbands);
412        break;
413
414      case SBC_DUAL_CHANNEL:
415        frameLen *= 2;
416      /* fall through */
417
418      default:
419        if (mode == SBC_MONO) {
420          frameLen += 4 * subbands;
421        } else {
422          frameLen += 8 * subbands;
423        }
424    }
425
426    frameCount++;
427    frameLen = SBC_HEADER_LEN + (frameLen + 7) / 8;
428    if (frameBytes > frameLen) {
429      frameBytes -= frameLen;
430      frameData += frameLen;
431    } else {
432      frameBytes = 0;
433    }
434  }
435  return frameCount;
436}
437
438/** Read quantized subband samples from the input bitstream and expand them. */
439
440#ifdef SPECIALIZE_READ_SAMPLES_JOINT
441
442PRIVATE void OI_SBC_ReadSamplesJoint4(OI_CODEC_SBC_DECODER_CONTEXT* context,
443                                      OI_BITSTREAM* global_bs) {
444#define NROF_SUBBANDS 4
445#include "readsamplesjoint.inc"
446#undef NROF_SUBBANDS
447}
448
449PRIVATE void OI_SBC_ReadSamplesJoint8(OI_CODEC_SBC_DECODER_CONTEXT* context,
450                                      OI_BITSTREAM* global_bs) {
451#define NROF_SUBBANDS 8
452#include "readsamplesjoint.inc"
453#undef NROF_SUBBANDS
454}
455
456typedef void (*READ_SAMPLES)(OI_CODEC_SBC_DECODER_CONTEXT* context,
457                             OI_BITSTREAM* global_bs);
458
459static const READ_SAMPLES SpecializedReadSamples[] = {OI_SBC_ReadSamplesJoint4,
460                                                      OI_SBC_ReadSamplesJoint8};
461
462#endif /* SPECIALIZE_READ_SAMPLES_JOINT */
463
464PRIVATE void OI_SBC_ReadSamplesJoint(OI_CODEC_SBC_DECODER_CONTEXT* context,
465                                     OI_BITSTREAM* global_bs) {
466  OI_CODEC_SBC_COMMON_CONTEXT* common = &context->common;
467  OI_UINT nrof_subbands = common->frameInfo.nrof_subbands;
468#ifdef SPECIALIZE_READ_SAMPLES_JOINT
469  OI_ASSERT((nrof_subbands >> 3u) <= 1u);
470  SpecializedReadSamples[nrof_subbands >> 3](context, global_bs);
471#else
472
473#define NROF_SUBBANDS nrof_subbands
474#include "readsamplesjoint.inc"
475#undef NROF_SUBBANDS
476#endif /* SPECIALIZE_READ_SAMPLES_JOINT */
477}
478
479/**@}*/
480