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