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