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