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