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