1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Bluetooth low-complexity, subband codec (SBC) 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * Copyright (C) 2017 Aurelien Jacobs <aurel@gnuage.org> 5cabdff1aSopenharmony_ci * Copyright (C) 2012-2013 Intel Corporation 6cabdff1aSopenharmony_ci * Copyright (C) 2008-2010 Nokia Corporation 7cabdff1aSopenharmony_ci * Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org> 8cabdff1aSopenharmony_ci * Copyright (C) 2004-2005 Henryk Ploetz <henryk@ploetzli.ch> 9cabdff1aSopenharmony_ci * Copyright (C) 2005-2008 Brad Midgley <bmidgley@xmission.com> 10cabdff1aSopenharmony_ci * 11cabdff1aSopenharmony_ci * This file is part of FFmpeg. 12cabdff1aSopenharmony_ci * 13cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 14cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 15cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 16cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 17cabdff1aSopenharmony_ci * 18cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 19cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 20cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21cabdff1aSopenharmony_ci * Lesser General Public License for more details. 22cabdff1aSopenharmony_ci * 23cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 24cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 25cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 26cabdff1aSopenharmony_ci */ 27cabdff1aSopenharmony_ci 28cabdff1aSopenharmony_ci/** 29cabdff1aSopenharmony_ci * @file 30cabdff1aSopenharmony_ci * SBC decoder implementation 31cabdff1aSopenharmony_ci */ 32cabdff1aSopenharmony_ci 33cabdff1aSopenharmony_ci#include "avcodec.h" 34cabdff1aSopenharmony_ci#include "codec_internal.h" 35cabdff1aSopenharmony_ci#include "internal.h" 36cabdff1aSopenharmony_ci#include "libavutil/channel_layout.h" 37cabdff1aSopenharmony_ci#include "libavutil/intreadwrite.h" 38cabdff1aSopenharmony_ci#include "libavutil/mem_internal.h" 39cabdff1aSopenharmony_ci#include "sbc.h" 40cabdff1aSopenharmony_ci#include "sbcdec_data.h" 41cabdff1aSopenharmony_ci 42cabdff1aSopenharmony_cistruct sbc_decoder_state { 43cabdff1aSopenharmony_ci int32_t V[2][170]; 44cabdff1aSopenharmony_ci int offset[2][16]; 45cabdff1aSopenharmony_ci}; 46cabdff1aSopenharmony_ci 47cabdff1aSopenharmony_citypedef struct SBCDecContext { 48cabdff1aSopenharmony_ci AVClass *class; 49cabdff1aSopenharmony_ci DECLARE_ALIGNED(SBC_ALIGN, struct sbc_frame, frame); 50cabdff1aSopenharmony_ci DECLARE_ALIGNED(SBC_ALIGN, struct sbc_decoder_state, dsp); 51cabdff1aSopenharmony_ci} SBCDecContext; 52cabdff1aSopenharmony_ci 53cabdff1aSopenharmony_ci/* 54cabdff1aSopenharmony_ci * Unpacks a SBC frame at the beginning of the stream in data, 55cabdff1aSopenharmony_ci * which has at most len bytes into frame. 56cabdff1aSopenharmony_ci * Returns the length in bytes of the packed frame, or a negative 57cabdff1aSopenharmony_ci * value on error. The error codes are: 58cabdff1aSopenharmony_ci * 59cabdff1aSopenharmony_ci * -1 Data stream too short 60cabdff1aSopenharmony_ci * -2 Sync byte incorrect 61cabdff1aSopenharmony_ci * -3 CRC8 incorrect 62cabdff1aSopenharmony_ci * -4 Bitpool value out of bounds 63cabdff1aSopenharmony_ci */ 64cabdff1aSopenharmony_cistatic int sbc_unpack_frame(const uint8_t *data, struct sbc_frame *frame, 65cabdff1aSopenharmony_ci size_t len) 66cabdff1aSopenharmony_ci{ 67cabdff1aSopenharmony_ci unsigned int consumed; 68cabdff1aSopenharmony_ci /* Will copy the parts of the header that are relevant to crc 69cabdff1aSopenharmony_ci * calculation here */ 70cabdff1aSopenharmony_ci uint8_t crc_header[11] = { 0 }; 71cabdff1aSopenharmony_ci int crc_pos; 72cabdff1aSopenharmony_ci int32_t temp; 73cabdff1aSopenharmony_ci 74cabdff1aSopenharmony_ci uint32_t audio_sample; 75cabdff1aSopenharmony_ci int ch, sb, blk, bit; /* channel, subband, block and bit standard 76cabdff1aSopenharmony_ci counters */ 77cabdff1aSopenharmony_ci int bits[2][8]; /* bits distribution */ 78cabdff1aSopenharmony_ci uint32_t levels[2][8]; /* levels derived from that */ 79cabdff1aSopenharmony_ci 80cabdff1aSopenharmony_ci if (len < 4) 81cabdff1aSopenharmony_ci return -1; 82cabdff1aSopenharmony_ci 83cabdff1aSopenharmony_ci if (data[0] == MSBC_SYNCWORD) { 84cabdff1aSopenharmony_ci if (data[1] != 0) 85cabdff1aSopenharmony_ci return -2; 86cabdff1aSopenharmony_ci if (data[2] != 0) 87cabdff1aSopenharmony_ci return -2; 88cabdff1aSopenharmony_ci 89cabdff1aSopenharmony_ci frame->frequency = SBC_FREQ_16000; 90cabdff1aSopenharmony_ci frame->blocks = MSBC_BLOCKS; 91cabdff1aSopenharmony_ci frame->allocation = LOUDNESS; 92cabdff1aSopenharmony_ci frame->mode = MONO; 93cabdff1aSopenharmony_ci frame->channels = 1; 94cabdff1aSopenharmony_ci frame->subbands = 8; 95cabdff1aSopenharmony_ci frame->bitpool = 26; 96cabdff1aSopenharmony_ci } else if (data[0] == SBC_SYNCWORD) { 97cabdff1aSopenharmony_ci frame->frequency = (data[1] >> 6) & 0x03; 98cabdff1aSopenharmony_ci frame->blocks = 4 * ((data[1] >> 4) & 0x03) + 4; 99cabdff1aSopenharmony_ci frame->mode = (data[1] >> 2) & 0x03; 100cabdff1aSopenharmony_ci frame->channels = frame->mode == MONO ? 1 : 2; 101cabdff1aSopenharmony_ci frame->allocation = (data[1] >> 1) & 0x01; 102cabdff1aSopenharmony_ci frame->subbands = data[1] & 0x01 ? 8 : 4; 103cabdff1aSopenharmony_ci frame->bitpool = data[2]; 104cabdff1aSopenharmony_ci 105cabdff1aSopenharmony_ci if ((frame->mode == MONO || frame->mode == DUAL_CHANNEL) && 106cabdff1aSopenharmony_ci frame->bitpool > 16 * frame->subbands) 107cabdff1aSopenharmony_ci return -4; 108cabdff1aSopenharmony_ci 109cabdff1aSopenharmony_ci if ((frame->mode == STEREO || frame->mode == JOINT_STEREO) && 110cabdff1aSopenharmony_ci frame->bitpool > 32 * frame->subbands) 111cabdff1aSopenharmony_ci return -4; 112cabdff1aSopenharmony_ci } else 113cabdff1aSopenharmony_ci return -2; 114cabdff1aSopenharmony_ci 115cabdff1aSopenharmony_ci consumed = 32; 116cabdff1aSopenharmony_ci crc_header[0] = data[1]; 117cabdff1aSopenharmony_ci crc_header[1] = data[2]; 118cabdff1aSopenharmony_ci crc_pos = 16; 119cabdff1aSopenharmony_ci 120cabdff1aSopenharmony_ci if (frame->mode == JOINT_STEREO) { 121cabdff1aSopenharmony_ci if (len * 8 < consumed + frame->subbands) 122cabdff1aSopenharmony_ci return -1; 123cabdff1aSopenharmony_ci 124cabdff1aSopenharmony_ci frame->joint = 0x00; 125cabdff1aSopenharmony_ci for (sb = 0; sb < frame->subbands - 1; sb++) 126cabdff1aSopenharmony_ci frame->joint |= ((data[4] >> (7 - sb)) & 0x01) << sb; 127cabdff1aSopenharmony_ci if (frame->subbands == 4) 128cabdff1aSopenharmony_ci crc_header[crc_pos / 8] = data[4] & 0xf0; 129cabdff1aSopenharmony_ci else 130cabdff1aSopenharmony_ci crc_header[crc_pos / 8] = data[4]; 131cabdff1aSopenharmony_ci 132cabdff1aSopenharmony_ci consumed += frame->subbands; 133cabdff1aSopenharmony_ci crc_pos += frame->subbands; 134cabdff1aSopenharmony_ci } 135cabdff1aSopenharmony_ci 136cabdff1aSopenharmony_ci if (len * 8 < consumed + (4 * frame->subbands * frame->channels)) 137cabdff1aSopenharmony_ci return -1; 138cabdff1aSopenharmony_ci 139cabdff1aSopenharmony_ci for (ch = 0; ch < frame->channels; ch++) { 140cabdff1aSopenharmony_ci for (sb = 0; sb < frame->subbands; sb++) { 141cabdff1aSopenharmony_ci /* FIXME assert(consumed % 4 == 0); */ 142cabdff1aSopenharmony_ci frame->scale_factor[ch][sb] = 143cabdff1aSopenharmony_ci (data[consumed >> 3] >> (4 - (consumed & 0x7))) & 0x0F; 144cabdff1aSopenharmony_ci crc_header[crc_pos >> 3] |= 145cabdff1aSopenharmony_ci frame->scale_factor[ch][sb] << (4 - (crc_pos & 0x7)); 146cabdff1aSopenharmony_ci 147cabdff1aSopenharmony_ci consumed += 4; 148cabdff1aSopenharmony_ci crc_pos += 4; 149cabdff1aSopenharmony_ci } 150cabdff1aSopenharmony_ci } 151cabdff1aSopenharmony_ci 152cabdff1aSopenharmony_ci if (data[3] != ff_sbc_crc8(frame->crc_ctx, crc_header, crc_pos)) 153cabdff1aSopenharmony_ci return -3; 154cabdff1aSopenharmony_ci 155cabdff1aSopenharmony_ci ff_sbc_calculate_bits(frame, bits); 156cabdff1aSopenharmony_ci 157cabdff1aSopenharmony_ci for (ch = 0; ch < frame->channels; ch++) { 158cabdff1aSopenharmony_ci for (sb = 0; sb < frame->subbands; sb++) 159cabdff1aSopenharmony_ci levels[ch][sb] = (1 << bits[ch][sb]) - 1; 160cabdff1aSopenharmony_ci } 161cabdff1aSopenharmony_ci 162cabdff1aSopenharmony_ci for (blk = 0; blk < frame->blocks; blk++) { 163cabdff1aSopenharmony_ci for (ch = 0; ch < frame->channels; ch++) { 164cabdff1aSopenharmony_ci for (sb = 0; sb < frame->subbands; sb++) { 165cabdff1aSopenharmony_ci uint32_t shift; 166cabdff1aSopenharmony_ci 167cabdff1aSopenharmony_ci if (levels[ch][sb] == 0) { 168cabdff1aSopenharmony_ci frame->sb_sample[blk][ch][sb] = 0; 169cabdff1aSopenharmony_ci continue; 170cabdff1aSopenharmony_ci } 171cabdff1aSopenharmony_ci 172cabdff1aSopenharmony_ci shift = frame->scale_factor[ch][sb] + 173cabdff1aSopenharmony_ci 1 + SBCDEC_FIXED_EXTRA_BITS; 174cabdff1aSopenharmony_ci 175cabdff1aSopenharmony_ci audio_sample = 0; 176cabdff1aSopenharmony_ci for (bit = 0; bit < bits[ch][sb]; bit++) { 177cabdff1aSopenharmony_ci if (consumed > len * 8) 178cabdff1aSopenharmony_ci return -1; 179cabdff1aSopenharmony_ci 180cabdff1aSopenharmony_ci if ((data[consumed >> 3] >> (7 - (consumed & 0x7))) & 0x01) 181cabdff1aSopenharmony_ci audio_sample |= 1 << (bits[ch][sb] - bit - 1); 182cabdff1aSopenharmony_ci 183cabdff1aSopenharmony_ci consumed++; 184cabdff1aSopenharmony_ci } 185cabdff1aSopenharmony_ci 186cabdff1aSopenharmony_ci frame->sb_sample[blk][ch][sb] = (int32_t) 187cabdff1aSopenharmony_ci (((((uint64_t) audio_sample << 1) | 1) << shift) / 188cabdff1aSopenharmony_ci levels[ch][sb]) - (1 << shift); 189cabdff1aSopenharmony_ci } 190cabdff1aSopenharmony_ci } 191cabdff1aSopenharmony_ci } 192cabdff1aSopenharmony_ci 193cabdff1aSopenharmony_ci if (frame->mode == JOINT_STEREO) { 194cabdff1aSopenharmony_ci for (blk = 0; blk < frame->blocks; blk++) { 195cabdff1aSopenharmony_ci for (sb = 0; sb < frame->subbands; sb++) { 196cabdff1aSopenharmony_ci if (frame->joint & (0x01 << sb)) { 197cabdff1aSopenharmony_ci temp = frame->sb_sample[blk][0][sb] + 198cabdff1aSopenharmony_ci frame->sb_sample[blk][1][sb]; 199cabdff1aSopenharmony_ci frame->sb_sample[blk][1][sb] = 200cabdff1aSopenharmony_ci frame->sb_sample[blk][0][sb] - 201cabdff1aSopenharmony_ci frame->sb_sample[blk][1][sb]; 202cabdff1aSopenharmony_ci frame->sb_sample[blk][0][sb] = temp; 203cabdff1aSopenharmony_ci } 204cabdff1aSopenharmony_ci } 205cabdff1aSopenharmony_ci } 206cabdff1aSopenharmony_ci } 207cabdff1aSopenharmony_ci 208cabdff1aSopenharmony_ci if ((consumed & 0x7) != 0) 209cabdff1aSopenharmony_ci consumed += 8 - (consumed & 0x7); 210cabdff1aSopenharmony_ci 211cabdff1aSopenharmony_ci return consumed >> 3; 212cabdff1aSopenharmony_ci} 213cabdff1aSopenharmony_ci 214cabdff1aSopenharmony_cistatic inline void sbc_synthesize_four(struct sbc_decoder_state *state, 215cabdff1aSopenharmony_ci struct sbc_frame *frame, 216cabdff1aSopenharmony_ci int ch, int blk, AVFrame *output_frame) 217cabdff1aSopenharmony_ci{ 218cabdff1aSopenharmony_ci int i, k, idx; 219cabdff1aSopenharmony_ci int32_t *v = state->V[ch]; 220cabdff1aSopenharmony_ci int *offset = state->offset[ch]; 221cabdff1aSopenharmony_ci 222cabdff1aSopenharmony_ci for (i = 0; i < 8; i++) { 223cabdff1aSopenharmony_ci /* Shifting */ 224cabdff1aSopenharmony_ci offset[i]--; 225cabdff1aSopenharmony_ci if (offset[i] < 0) { 226cabdff1aSopenharmony_ci offset[i] = 79; 227cabdff1aSopenharmony_ci memcpy(v + 80, v, 9 * sizeof(*v)); 228cabdff1aSopenharmony_ci } 229cabdff1aSopenharmony_ci 230cabdff1aSopenharmony_ci /* Distribute the new matrix value to the shifted position */ 231cabdff1aSopenharmony_ci v[offset[i]] = 232cabdff1aSopenharmony_ci (int)( (unsigned)ff_synmatrix4[i][0] * frame->sb_sample[blk][ch][0] + 233cabdff1aSopenharmony_ci (unsigned)ff_synmatrix4[i][1] * frame->sb_sample[blk][ch][1] + 234cabdff1aSopenharmony_ci (unsigned)ff_synmatrix4[i][2] * frame->sb_sample[blk][ch][2] + 235cabdff1aSopenharmony_ci (unsigned)ff_synmatrix4[i][3] * frame->sb_sample[blk][ch][3] ) >> 15; 236cabdff1aSopenharmony_ci } 237cabdff1aSopenharmony_ci 238cabdff1aSopenharmony_ci /* Compute the samples */ 239cabdff1aSopenharmony_ci for (idx = 0, i = 0; i < 4; i++, idx += 5) { 240cabdff1aSopenharmony_ci k = (i + 4) & 0xf; 241cabdff1aSopenharmony_ci 242cabdff1aSopenharmony_ci /* Store in output, Q0 */ 243cabdff1aSopenharmony_ci AV_WN16A(&output_frame->data[ch][blk * 8 + i * 2], av_clip_int16( 244cabdff1aSopenharmony_ci (int)( (unsigned)v[offset[i] + 0] * ff_sbc_proto_4_40m0[idx + 0] + 245cabdff1aSopenharmony_ci (unsigned)v[offset[k] + 1] * ff_sbc_proto_4_40m1[idx + 0] + 246cabdff1aSopenharmony_ci (unsigned)v[offset[i] + 2] * ff_sbc_proto_4_40m0[idx + 1] + 247cabdff1aSopenharmony_ci (unsigned)v[offset[k] + 3] * ff_sbc_proto_4_40m1[idx + 1] + 248cabdff1aSopenharmony_ci (unsigned)v[offset[i] + 4] * ff_sbc_proto_4_40m0[idx + 2] + 249cabdff1aSopenharmony_ci (unsigned)v[offset[k] + 5] * ff_sbc_proto_4_40m1[idx + 2] + 250cabdff1aSopenharmony_ci (unsigned)v[offset[i] + 6] * ff_sbc_proto_4_40m0[idx + 3] + 251cabdff1aSopenharmony_ci (unsigned)v[offset[k] + 7] * ff_sbc_proto_4_40m1[idx + 3] + 252cabdff1aSopenharmony_ci (unsigned)v[offset[i] + 8] * ff_sbc_proto_4_40m0[idx + 4] + 253cabdff1aSopenharmony_ci (unsigned)v[offset[k] + 9] * ff_sbc_proto_4_40m1[idx + 4] ) >> 15)); 254cabdff1aSopenharmony_ci } 255cabdff1aSopenharmony_ci} 256cabdff1aSopenharmony_ci 257cabdff1aSopenharmony_cistatic inline void sbc_synthesize_eight(struct sbc_decoder_state *state, 258cabdff1aSopenharmony_ci struct sbc_frame *frame, 259cabdff1aSopenharmony_ci int ch, int blk, AVFrame *output_frame) 260cabdff1aSopenharmony_ci{ 261cabdff1aSopenharmony_ci int i, k, idx; 262cabdff1aSopenharmony_ci int32_t *v = state->V[ch]; 263cabdff1aSopenharmony_ci int *offset = state->offset[ch]; 264cabdff1aSopenharmony_ci 265cabdff1aSopenharmony_ci for (i = 0; i < 16; i++) { 266cabdff1aSopenharmony_ci /* Shifting */ 267cabdff1aSopenharmony_ci offset[i]--; 268cabdff1aSopenharmony_ci if (offset[i] < 0) { 269cabdff1aSopenharmony_ci offset[i] = 159; 270cabdff1aSopenharmony_ci memcpy(v + 160, v, 9 * sizeof(*v)); 271cabdff1aSopenharmony_ci } 272cabdff1aSopenharmony_ci 273cabdff1aSopenharmony_ci /* Distribute the new matrix value to the shifted position */ 274cabdff1aSopenharmony_ci v[offset[i]] = 275cabdff1aSopenharmony_ci (int)( (unsigned)ff_synmatrix8[i][0] * frame->sb_sample[blk][ch][0] + 276cabdff1aSopenharmony_ci (unsigned)ff_synmatrix8[i][1] * frame->sb_sample[blk][ch][1] + 277cabdff1aSopenharmony_ci (unsigned)ff_synmatrix8[i][2] * frame->sb_sample[blk][ch][2] + 278cabdff1aSopenharmony_ci (unsigned)ff_synmatrix8[i][3] * frame->sb_sample[blk][ch][3] + 279cabdff1aSopenharmony_ci (unsigned)ff_synmatrix8[i][4] * frame->sb_sample[blk][ch][4] + 280cabdff1aSopenharmony_ci (unsigned)ff_synmatrix8[i][5] * frame->sb_sample[blk][ch][5] + 281cabdff1aSopenharmony_ci (unsigned)ff_synmatrix8[i][6] * frame->sb_sample[blk][ch][6] + 282cabdff1aSopenharmony_ci (unsigned)ff_synmatrix8[i][7] * frame->sb_sample[blk][ch][7] ) >> 15; 283cabdff1aSopenharmony_ci } 284cabdff1aSopenharmony_ci 285cabdff1aSopenharmony_ci /* Compute the samples */ 286cabdff1aSopenharmony_ci for (idx = 0, i = 0; i < 8; i++, idx += 5) { 287cabdff1aSopenharmony_ci k = (i + 8) & 0xf; 288cabdff1aSopenharmony_ci 289cabdff1aSopenharmony_ci /* Store in output, Q0 */ 290cabdff1aSopenharmony_ci AV_WN16A(&output_frame->data[ch][blk * 16 + i * 2], av_clip_int16( 291cabdff1aSopenharmony_ci (int)( (unsigned)v[offset[i] + 0] * ff_sbc_proto_8_80m0[idx + 0] + 292cabdff1aSopenharmony_ci (unsigned)v[offset[k] + 1] * ff_sbc_proto_8_80m1[idx + 0] + 293cabdff1aSopenharmony_ci (unsigned)v[offset[i] + 2] * ff_sbc_proto_8_80m0[idx + 1] + 294cabdff1aSopenharmony_ci (unsigned)v[offset[k] + 3] * ff_sbc_proto_8_80m1[idx + 1] + 295cabdff1aSopenharmony_ci (unsigned)v[offset[i] + 4] * ff_sbc_proto_8_80m0[idx + 2] + 296cabdff1aSopenharmony_ci (unsigned)v[offset[k] + 5] * ff_sbc_proto_8_80m1[idx + 2] + 297cabdff1aSopenharmony_ci (unsigned)v[offset[i] + 6] * ff_sbc_proto_8_80m0[idx + 3] + 298cabdff1aSopenharmony_ci (unsigned)v[offset[k] + 7] * ff_sbc_proto_8_80m1[idx + 3] + 299cabdff1aSopenharmony_ci (unsigned)v[offset[i] + 8] * ff_sbc_proto_8_80m0[idx + 4] + 300cabdff1aSopenharmony_ci (unsigned)v[offset[k] + 9] * ff_sbc_proto_8_80m1[idx + 4] ) >> 15)); 301cabdff1aSopenharmony_ci } 302cabdff1aSopenharmony_ci} 303cabdff1aSopenharmony_ci 304cabdff1aSopenharmony_cistatic void sbc_synthesize_audio(struct sbc_decoder_state *state, 305cabdff1aSopenharmony_ci struct sbc_frame *frame, AVFrame *output_frame) 306cabdff1aSopenharmony_ci{ 307cabdff1aSopenharmony_ci int ch, blk; 308cabdff1aSopenharmony_ci 309cabdff1aSopenharmony_ci switch (frame->subbands) { 310cabdff1aSopenharmony_ci case 4: 311cabdff1aSopenharmony_ci for (ch = 0; ch < frame->channels; ch++) 312cabdff1aSopenharmony_ci for (blk = 0; blk < frame->blocks; blk++) 313cabdff1aSopenharmony_ci sbc_synthesize_four(state, frame, ch, blk, output_frame); 314cabdff1aSopenharmony_ci break; 315cabdff1aSopenharmony_ci 316cabdff1aSopenharmony_ci case 8: 317cabdff1aSopenharmony_ci for (ch = 0; ch < frame->channels; ch++) 318cabdff1aSopenharmony_ci for (blk = 0; blk < frame->blocks; blk++) 319cabdff1aSopenharmony_ci sbc_synthesize_eight(state, frame, ch, blk, output_frame); 320cabdff1aSopenharmony_ci break; 321cabdff1aSopenharmony_ci } 322cabdff1aSopenharmony_ci} 323cabdff1aSopenharmony_ci 324cabdff1aSopenharmony_cistatic int sbc_decode_init(AVCodecContext *avctx) 325cabdff1aSopenharmony_ci{ 326cabdff1aSopenharmony_ci SBCDecContext *sbc = avctx->priv_data; 327cabdff1aSopenharmony_ci int i, ch; 328cabdff1aSopenharmony_ci 329cabdff1aSopenharmony_ci avctx->sample_fmt = AV_SAMPLE_FMT_S16P; 330cabdff1aSopenharmony_ci 331cabdff1aSopenharmony_ci sbc->frame.crc_ctx = av_crc_get_table(AV_CRC_8_EBU); 332cabdff1aSopenharmony_ci 333cabdff1aSopenharmony_ci memset(sbc->dsp.V, 0, sizeof(sbc->dsp.V)); 334cabdff1aSopenharmony_ci for (ch = 0; ch < 2; ch++) 335cabdff1aSopenharmony_ci for (i = 0; i < FF_ARRAY_ELEMS(sbc->dsp.offset[0]); i++) 336cabdff1aSopenharmony_ci sbc->dsp.offset[ch][i] = (10 * i + 10); 337cabdff1aSopenharmony_ci return 0; 338cabdff1aSopenharmony_ci} 339cabdff1aSopenharmony_ci 340cabdff1aSopenharmony_cistatic int sbc_decode_frame(AVCodecContext *avctx, AVFrame *frame, 341cabdff1aSopenharmony_ci int *got_frame_ptr, AVPacket *avpkt) 342cabdff1aSopenharmony_ci{ 343cabdff1aSopenharmony_ci SBCDecContext *sbc = avctx->priv_data; 344cabdff1aSopenharmony_ci int ret, frame_length; 345cabdff1aSopenharmony_ci 346cabdff1aSopenharmony_ci if (!sbc) 347cabdff1aSopenharmony_ci return AVERROR(EIO); 348cabdff1aSopenharmony_ci 349cabdff1aSopenharmony_ci frame_length = sbc_unpack_frame(avpkt->data, &sbc->frame, avpkt->size); 350cabdff1aSopenharmony_ci if (frame_length <= 0) 351cabdff1aSopenharmony_ci return frame_length; 352cabdff1aSopenharmony_ci 353cabdff1aSopenharmony_ci av_channel_layout_uninit(&avctx->ch_layout); 354cabdff1aSopenharmony_ci avctx->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC; 355cabdff1aSopenharmony_ci avctx->ch_layout.nb_channels = sbc->frame.channels; 356cabdff1aSopenharmony_ci 357cabdff1aSopenharmony_ci frame->nb_samples = sbc->frame.blocks * sbc->frame.subbands; 358cabdff1aSopenharmony_ci if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) 359cabdff1aSopenharmony_ci return ret; 360cabdff1aSopenharmony_ci 361cabdff1aSopenharmony_ci sbc_synthesize_audio(&sbc->dsp, &sbc->frame, frame); 362cabdff1aSopenharmony_ci 363cabdff1aSopenharmony_ci *got_frame_ptr = 1; 364cabdff1aSopenharmony_ci 365cabdff1aSopenharmony_ci return frame_length; 366cabdff1aSopenharmony_ci} 367cabdff1aSopenharmony_ci 368cabdff1aSopenharmony_ciconst FFCodec ff_sbc_decoder = { 369cabdff1aSopenharmony_ci .p.name = "sbc", 370cabdff1aSopenharmony_ci .p.long_name = NULL_IF_CONFIG_SMALL("SBC (low-complexity subband codec)"), 371cabdff1aSopenharmony_ci .p.type = AVMEDIA_TYPE_AUDIO, 372cabdff1aSopenharmony_ci .p.id = AV_CODEC_ID_SBC, 373cabdff1aSopenharmony_ci .priv_data_size = sizeof(SBCDecContext), 374cabdff1aSopenharmony_ci .init = sbc_decode_init, 375cabdff1aSopenharmony_ci FF_CODEC_DECODE_CB(sbc_decode_frame), 376cabdff1aSopenharmony_ci .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, 377cabdff1aSopenharmony_ci .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, 378cabdff1aSopenharmony_ci#if FF_API_OLD_CHANNEL_LAYOUT 379cabdff1aSopenharmony_ci .p.channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_MONO, 380cabdff1aSopenharmony_ci AV_CH_LAYOUT_STEREO, 0}, 381cabdff1aSopenharmony_ci#endif 382cabdff1aSopenharmony_ci .p.ch_layouts = (const AVChannelLayout[]) { AV_CHANNEL_LAYOUT_MONO, 383cabdff1aSopenharmony_ci AV_CHANNEL_LAYOUT_STEREO, 384cabdff1aSopenharmony_ci { 0 } }, 385cabdff1aSopenharmony_ci .p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P, 386cabdff1aSopenharmony_ci AV_SAMPLE_FMT_NONE }, 387cabdff1aSopenharmony_ci .p.supported_samplerates = (const int[]) { 16000, 32000, 44100, 48000, 0 }, 388cabdff1aSopenharmony_ci}; 389