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