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