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