| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * Bluetooth low-complexity, subband codec (SBC) | ||
| 3 | * | ||
| 4 | * Copyright (C) 2017 Aurelien Jacobs <aurel@gnuage.org> | ||
| 5 | * Copyright (C) 2012-2013 Intel Corporation | ||
| 6 | * Copyright (C) 2008-2010 Nokia Corporation | ||
| 7 | * Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org> | ||
| 8 | * Copyright (C) 2004-2005 Henryk Ploetz <henryk@ploetzli.ch> | ||
| 9 | * Copyright (C) 2005-2008 Brad Midgley <bmidgley@xmission.com> | ||
| 10 | * | ||
| 11 | * This file is part of FFmpeg. | ||
| 12 | * | ||
| 13 | * FFmpeg is free software; you can redistribute it and/or | ||
| 14 | * modify it under the terms of the GNU Lesser General Public | ||
| 15 | * License as published by the Free Software Foundation; either | ||
| 16 | * version 2.1 of the License, or (at your option) any later version. | ||
| 17 | * | ||
| 18 | * FFmpeg is distributed in the hope that it will be useful, | ||
| 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 21 | * Lesser General Public License for more details. | ||
| 22 | * | ||
| 23 | * You should have received a copy of the GNU Lesser General Public | ||
| 24 | * License along with FFmpeg; if not, write to the Free Software | ||
| 25 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 26 | */ | ||
| 27 | |||
| 28 | /** | ||
| 29 | * @file | ||
| 30 | * SBC encoder implementation | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include "libavutil/channel_layout.h" | ||
| 34 | #include "libavutil/emms.h" | ||
| 35 | #include "libavutil/opt.h" | ||
| 36 | #include "avcodec.h" | ||
| 37 | #include "codec_internal.h" | ||
| 38 | #include "encode.h" | ||
| 39 | #include "profiles.h" | ||
| 40 | #include "put_bits.h" | ||
| 41 | #include "sbc.h" | ||
| 42 | #include "sbcdsp.h" | ||
| 43 | |||
| 44 | typedef struct SBCEncContext { | ||
| 45 | AVClass *class; | ||
| 46 | int64_t max_delay; | ||
| 47 | int msbc; | ||
| 48 | DECLARE_ALIGNED(SBC_ALIGN, struct sbc_frame, frame); | ||
| 49 | DECLARE_ALIGNED(SBC_ALIGN, SBCDSPContext, dsp); | ||
| 50 | } SBCEncContext; | ||
| 51 | |||
| 52 | static const int sbc_samplerates[] = { 16000, 32000, 44100, 48000, 0 }; | ||
| 53 | |||
| 54 | ✗ | static int sbc_analyze_audio(SBCDSPContext *s, struct sbc_frame *frame) | |
| 55 | { | ||
| 56 | int ch, blk; | ||
| 57 | int16_t *x; | ||
| 58 | |||
| 59 | ✗ | switch (frame->subbands) { | |
| 60 | ✗ | case 4: | |
| 61 | ✗ | for (ch = 0; ch < frame->channels; ch++) { | |
| 62 | ✗ | x = &s->X[ch][s->position - 4 * | |
| 63 | ✗ | s->increment + frame->blocks * 4]; | |
| 64 | ✗ | for (blk = 0; blk < frame->blocks; | |
| 65 | ✗ | blk += s->increment) { | |
| 66 | ✗ | s->sbc_analyze_4s( | |
| 67 | s, x, | ||
| 68 | ✗ | frame->sb_sample_f[blk][ch], | |
| 69 | frame->sb_sample_f[blk + 1][ch] - | ||
| 70 | frame->sb_sample_f[blk][ch]); | ||
| 71 | ✗ | x -= 4 * s->increment; | |
| 72 | } | ||
| 73 | } | ||
| 74 | ✗ | return frame->blocks * 4; | |
| 75 | |||
| 76 | ✗ | case 8: | |
| 77 | ✗ | for (ch = 0; ch < frame->channels; ch++) { | |
| 78 | ✗ | x = &s->X[ch][s->position - 8 * | |
| 79 | ✗ | s->increment + frame->blocks * 8]; | |
| 80 | ✗ | for (blk = 0; blk < frame->blocks; | |
| 81 | ✗ | blk += s->increment) { | |
| 82 | ✗ | s->sbc_analyze_8s( | |
| 83 | s, x, | ||
| 84 | ✗ | frame->sb_sample_f[blk][ch], | |
| 85 | frame->sb_sample_f[blk + 1][ch] - | ||
| 86 | frame->sb_sample_f[blk][ch]); | ||
| 87 | ✗ | x -= 8 * s->increment; | |
| 88 | } | ||
| 89 | } | ||
| 90 | ✗ | return frame->blocks * 8; | |
| 91 | |||
| 92 | ✗ | default: | |
| 93 | ✗ | return AVERROR(EIO); | |
| 94 | } | ||
| 95 | } | ||
| 96 | |||
| 97 | /* | ||
| 98 | * Packs the SBC frame from frame into the memory in avpkt. | ||
| 99 | * Returns the length of the packed frame. | ||
| 100 | */ | ||
| 101 | ✗ | static size_t sbc_pack_frame(AVPacket *avpkt, struct sbc_frame *frame, | |
| 102 | int joint, int msbc) | ||
| 103 | { | ||
| 104 | PutBitContext pb; | ||
| 105 | |||
| 106 | /* Will copy the header parts for CRC-8 calculation here */ | ||
| 107 | ✗ | uint8_t crc_header[11] = { 0 }; | |
| 108 | int crc_pos; | ||
| 109 | |||
| 110 | uint32_t audio_sample; | ||
| 111 | |||
| 112 | int ch, sb, blk; /* channel, subband, block and bit counters */ | ||
| 113 | int bits[2][8]; /* bits distribution */ | ||
| 114 | uint32_t levels[2][8]; /* levels are derived from that */ | ||
| 115 | uint32_t sb_sample_delta[2][8]; | ||
| 116 | |||
| 117 | ✗ | if (msbc) { | |
| 118 | ✗ | avpkt->data[0] = MSBC_SYNCWORD; | |
| 119 | ✗ | avpkt->data[1] = 0; | |
| 120 | ✗ | avpkt->data[2] = 0; | |
| 121 | } else { | ||
| 122 | ✗ | avpkt->data[0] = SBC_SYNCWORD; | |
| 123 | |||
| 124 | ✗ | avpkt->data[1] = (frame->frequency & 0x03) << 6; | |
| 125 | ✗ | avpkt->data[1] |= (((frame->blocks >> 2) - 1) & 0x03) << 4; | |
| 126 | ✗ | avpkt->data[1] |= (frame->mode & 0x03) << 2; | |
| 127 | ✗ | avpkt->data[1] |= (frame->allocation & 0x01) << 1; | |
| 128 | ✗ | avpkt->data[1] |= ((frame->subbands == 8) & 0x01) << 0; | |
| 129 | |||
| 130 | ✗ | avpkt->data[2] = frame->bitpool; | |
| 131 | |||
| 132 | ✗ | if (frame->bitpool > frame->subbands << (4 + (frame->mode == STEREO | |
| 133 | ✗ | || frame->mode == JOINT_STEREO))) | |
| 134 | ✗ | return -5; | |
| 135 | } | ||
| 136 | |||
| 137 | /* Can't fill in crc yet */ | ||
| 138 | ✗ | crc_header[0] = avpkt->data[1]; | |
| 139 | ✗ | crc_header[1] = avpkt->data[2]; | |
| 140 | ✗ | crc_pos = 16; | |
| 141 | |||
| 142 | ✗ | init_put_bits(&pb, avpkt->data + 4, avpkt->size); | |
| 143 | |||
| 144 | ✗ | if (frame->mode == JOINT_STEREO) { | |
| 145 | ✗ | put_bits(&pb, frame->subbands, joint); | |
| 146 | ✗ | crc_header[crc_pos >> 3] = joint; | |
| 147 | ✗ | crc_pos += frame->subbands; | |
| 148 | } | ||
| 149 | |||
| 150 | ✗ | for (ch = 0; ch < frame->channels; ch++) { | |
| 151 | ✗ | for (sb = 0; sb < frame->subbands; sb++) { | |
| 152 | ✗ | put_bits(&pb, 4, frame->scale_factor[ch][sb] & 0x0F); | |
| 153 | ✗ | crc_header[crc_pos >> 3] <<= 4; | |
| 154 | ✗ | crc_header[crc_pos >> 3] |= frame->scale_factor[ch][sb] & 0x0F; | |
| 155 | ✗ | crc_pos += 4; | |
| 156 | } | ||
| 157 | } | ||
| 158 | |||
| 159 | /* align the last crc byte */ | ||
| 160 | ✗ | if (crc_pos % 8) | |
| 161 | ✗ | crc_header[crc_pos >> 3] <<= 8 - (crc_pos % 8); | |
| 162 | |||
| 163 | ✗ | avpkt->data[3] = ff_sbc_crc8(frame->crc_ctx, crc_header, crc_pos); | |
| 164 | |||
| 165 | ✗ | ff_sbc_calculate_bits(frame, bits); | |
| 166 | |||
| 167 | ✗ | for (ch = 0; ch < frame->channels; ch++) { | |
| 168 | ✗ | for (sb = 0; sb < frame->subbands; sb++) { | |
| 169 | ✗ | levels[ch][sb] = ((1 << bits[ch][sb]) - 1) << | |
| 170 | ✗ | (32 - (frame->scale_factor[ch][sb] + | |
| 171 | SCALE_OUT_BITS + 2)); | ||
| 172 | ✗ | sb_sample_delta[ch][sb] = (uint32_t) 1 << | |
| 173 | ✗ | (frame->scale_factor[ch][sb] + | |
| 174 | ✗ | SCALE_OUT_BITS + 1); | |
| 175 | } | ||
| 176 | } | ||
| 177 | |||
| 178 | ✗ | for (blk = 0; blk < frame->blocks; blk++) { | |
| 179 | ✗ | for (ch = 0; ch < frame->channels; ch++) { | |
| 180 | ✗ | for (sb = 0; sb < frame->subbands; sb++) { | |
| 181 | |||
| 182 | ✗ | if (bits[ch][sb] == 0) | |
| 183 | ✗ | continue; | |
| 184 | |||
| 185 | ✗ | audio_sample = ((uint64_t) levels[ch][sb] * | |
| 186 | ✗ | (sb_sample_delta[ch][sb] + | |
| 187 | ✗ | frame->sb_sample_f[blk][ch][sb])) >> 32; | |
| 188 | |||
| 189 | ✗ | put_bits(&pb, bits[ch][sb], audio_sample); | |
| 190 | } | ||
| 191 | } | ||
| 192 | } | ||
| 193 | |||
| 194 | ✗ | flush_put_bits(&pb); | |
| 195 | |||
| 196 | ✗ | return put_bytes_output(&pb); | |
| 197 | } | ||
| 198 | |||
| 199 | ✗ | static av_cold int sbc_encode_init(AVCodecContext *avctx) | |
| 200 | { | ||
| 201 | ✗ | SBCEncContext *sbc = avctx->priv_data; | |
| 202 | ✗ | struct sbc_frame *frame = &sbc->frame; | |
| 203 | |||
| 204 | ✗ | if (avctx->profile == AV_PROFILE_SBC_MSBC) | |
| 205 | ✗ | sbc->msbc = 1; | |
| 206 | |||
| 207 | ✗ | if (sbc->msbc) { | |
| 208 | ✗ | if (avctx->ch_layout.nb_channels != 1) { | |
| 209 | ✗ | av_log(avctx, AV_LOG_ERROR, "mSBC require mono channel.\n"); | |
| 210 | ✗ | return AVERROR(EINVAL); | |
| 211 | } | ||
| 212 | |||
| 213 | ✗ | if (avctx->sample_rate != 16000) { | |
| 214 | ✗ | av_log(avctx, AV_LOG_ERROR, "mSBC require 16 kHz samplerate.\n"); | |
| 215 | ✗ | return AVERROR(EINVAL); | |
| 216 | } | ||
| 217 | |||
| 218 | ✗ | frame->mode = SBC_MODE_MONO; | |
| 219 | ✗ | frame->subbands = 8; | |
| 220 | ✗ | frame->blocks = MSBC_BLOCKS; | |
| 221 | ✗ | frame->allocation = SBC_AM_LOUDNESS; | |
| 222 | ✗ | frame->bitpool = 26; | |
| 223 | |||
| 224 | ✗ | avctx->frame_size = 8 * MSBC_BLOCKS; | |
| 225 | } else { | ||
| 226 | int d; | ||
| 227 | |||
| 228 | ✗ | if (avctx->global_quality > 255*FF_QP2LAMBDA) { | |
| 229 | ✗ | av_log(avctx, AV_LOG_ERROR, "bitpool > 255 is not allowed.\n"); | |
| 230 | ✗ | return AVERROR(EINVAL); | |
| 231 | } | ||
| 232 | |||
| 233 | ✗ | if (avctx->ch_layout.nb_channels == 1) { | |
| 234 | ✗ | frame->mode = SBC_MODE_MONO; | |
| 235 | ✗ | if (sbc->max_delay <= 3000 || avctx->bit_rate > 270000) | |
| 236 | ✗ | frame->subbands = 4; | |
| 237 | else | ||
| 238 | ✗ | frame->subbands = 8; | |
| 239 | } else { | ||
| 240 | ✗ | if (avctx->bit_rate < 180000 || avctx->bit_rate > 420000) | |
| 241 | ✗ | frame->mode = SBC_MODE_JOINT_STEREO; | |
| 242 | else | ||
| 243 | ✗ | frame->mode = SBC_MODE_STEREO; | |
| 244 | ✗ | if (sbc->max_delay <= 4000 || avctx->bit_rate > 420000) | |
| 245 | ✗ | frame->subbands = 4; | |
| 246 | else | ||
| 247 | ✗ | frame->subbands = 8; | |
| 248 | } | ||
| 249 | /* sbc algorithmic delay is ((blocks + 10) * subbands - 2) / sample_rate */ | ||
| 250 | ✗ | frame->blocks = av_clip(((sbc->max_delay * avctx->sample_rate + 2) | |
| 251 | ✗ | / (1000000 * frame->subbands)) - 10, 4, 16) & ~3; | |
| 252 | |||
| 253 | ✗ | frame->allocation = SBC_AM_LOUDNESS; | |
| 254 | |||
| 255 | ✗ | d = frame->blocks * ((frame->mode == SBC_MODE_DUAL_CHANNEL) + 1); | |
| 256 | ✗ | frame->bitpool = (((avctx->bit_rate * frame->subbands * frame->blocks) / avctx->sample_rate) | |
| 257 | ✗ | - 4 * frame->subbands * avctx->ch_layout.nb_channels | |
| 258 | ✗ | - (frame->mode == SBC_MODE_JOINT_STEREO)*frame->subbands - 32 + d/2) / d; | |
| 259 | ✗ | if (avctx->global_quality > 0) | |
| 260 | ✗ | frame->bitpool = avctx->global_quality / FF_QP2LAMBDA; | |
| 261 | |||
| 262 | ✗ | avctx->frame_size = 4*((frame->subbands >> 3) + 1) * 4*(frame->blocks >> 2); | |
| 263 | } | ||
| 264 | |||
| 265 | ✗ | for (int i = 0; sbc_samplerates[i]; i++) | |
| 266 | ✗ | if (avctx->sample_rate == sbc_samplerates[i]) | |
| 267 | ✗ | frame->frequency = i; | |
| 268 | |||
| 269 | ✗ | frame->channels = avctx->ch_layout.nb_channels; | |
| 270 | ✗ | frame->codesize = frame->subbands * frame->blocks * avctx->ch_layout.nb_channels * 2; | |
| 271 | ✗ | frame->crc_ctx = av_crc_get_table(AV_CRC_8_EBU); | |
| 272 | |||
| 273 | ✗ | memset(&sbc->dsp.X, 0, sizeof(sbc->dsp.X)); | |
| 274 | ✗ | sbc->dsp.position = (SBC_X_BUFFER_SIZE - frame->subbands * 9) & ~7; | |
| 275 | ✗ | sbc->dsp.increment = sbc->msbc ? 1 : 4; | |
| 276 | ✗ | ff_sbcdsp_init(&sbc->dsp); | |
| 277 | |||
| 278 | ✗ | return 0; | |
| 279 | } | ||
| 280 | |||
| 281 | ✗ | static int sbc_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, | |
| 282 | const AVFrame *av_frame, int *got_packet_ptr) | ||
| 283 | { | ||
| 284 | ✗ | SBCEncContext *sbc = avctx->priv_data; | |
| 285 | ✗ | struct sbc_frame *frame = &sbc->frame; | |
| 286 | ✗ | uint8_t joint = frame->mode == SBC_MODE_JOINT_STEREO; | |
| 287 | ✗ | uint8_t dual = frame->mode == SBC_MODE_DUAL_CHANNEL; | |
| 288 | ✗ | int ret, j = 0; | |
| 289 | |||
| 290 | ✗ | int frame_length = 4 + (4 * frame->subbands * frame->channels) / 8 | |
| 291 | ✗ | + ((frame->blocks * frame->bitpool * (1 + dual) | |
| 292 | ✗ | + joint * frame->subbands) + 7) / 8; | |
| 293 | |||
| 294 | /* input must be large enough to encode a complete frame */ | ||
| 295 | ✗ | if (av_frame->nb_samples * frame->channels * 2 < frame->codesize) | |
| 296 | ✗ | return 0; | |
| 297 | |||
| 298 | ✗ | if ((ret = ff_get_encode_buffer(avctx, avpkt, frame_length, 0)) < 0) | |
| 299 | ✗ | return ret; | |
| 300 | |||
| 301 | /* Select the needed input data processing function and call it */ | ||
| 302 | ✗ | if (frame->subbands == 8) | |
| 303 | ✗ | sbc->dsp.position = sbc->dsp.sbc_enc_process_input_8s( | |
| 304 | ✗ | sbc->dsp.position, av_frame->data[0], sbc->dsp.X, | |
| 305 | ✗ | frame->subbands * frame->blocks, frame->channels); | |
| 306 | else | ||
| 307 | ✗ | sbc->dsp.position = sbc->dsp.sbc_enc_process_input_4s( | |
| 308 | ✗ | sbc->dsp.position, av_frame->data[0], sbc->dsp.X, | |
| 309 | ✗ | frame->subbands * frame->blocks, frame->channels); | |
| 310 | |||
| 311 | ✗ | sbc_analyze_audio(&sbc->dsp, &sbc->frame); | |
| 312 | |||
| 313 | ✗ | if (frame->mode == JOINT_STEREO) | |
| 314 | ✗ | j = sbc->dsp.sbc_calc_scalefactors_j(frame->sb_sample_f, | |
| 315 | ✗ | frame->scale_factor, | |
| 316 | ✗ | frame->blocks, | |
| 317 | ✗ | frame->subbands); | |
| 318 | else | ||
| 319 | ✗ | sbc->dsp.sbc_calc_scalefactors(frame->sb_sample_f, | |
| 320 | ✗ | frame->scale_factor, | |
| 321 | ✗ | frame->blocks, | |
| 322 | ✗ | frame->channels, | |
| 323 | ✗ | frame->subbands); | |
| 324 | ✗ | emms_c(); | |
| 325 | ✗ | sbc_pack_frame(avpkt, frame, j, sbc->msbc); | |
| 326 | |||
| 327 | ✗ | *got_packet_ptr = 1; | |
| 328 | ✗ | return 0; | |
| 329 | } | ||
| 330 | |||
| 331 | #define OFFSET(x) offsetof(SBCEncContext, x) | ||
| 332 | #define AE AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM | ||
| 333 | static const AVOption options[] = { | ||
| 334 | { "sbc_delay", "set maximum algorithmic latency", | ||
| 335 | OFFSET(max_delay), AV_OPT_TYPE_DURATION, {.i64 = 13000}, 1000,13000, AE }, | ||
| 336 | { "msbc", "use mSBC mode (wideband speech mono SBC)", | ||
| 337 | OFFSET(msbc), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AE }, | ||
| 338 | FF_AVCTX_PROFILE_OPTION("msbc", NULL, AUDIO, AV_PROFILE_SBC_MSBC) | ||
| 339 | { NULL }, | ||
| 340 | }; | ||
| 341 | |||
| 342 | static const AVClass sbc_class = { | ||
| 343 | .class_name = "sbc encoder", | ||
| 344 | .item_name = av_default_item_name, | ||
| 345 | .option = options, | ||
| 346 | .version = LIBAVUTIL_VERSION_INT, | ||
| 347 | }; | ||
| 348 | |||
| 349 | const FFCodec ff_sbc_encoder = { | ||
| 350 | .p.name = "sbc", | ||
| 351 | CODEC_LONG_NAME("SBC (low-complexity subband codec)"), | ||
| 352 | .p.type = AVMEDIA_TYPE_AUDIO, | ||
| 353 | .p.id = AV_CODEC_ID_SBC, | ||
| 354 | .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME | | ||
| 355 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, | ||
| 356 | .priv_data_size = sizeof(SBCEncContext), | ||
| 357 | .init = sbc_encode_init, | ||
| 358 | FF_CODEC_ENCODE_CB(sbc_encode_frame), | ||
| 359 | CODEC_CH_LAYOUTS(AV_CHANNEL_LAYOUT_MONO, AV_CHANNEL_LAYOUT_STEREO), | ||
| 360 | CODEC_SAMPLEFMTS(AV_SAMPLE_FMT_S16), | ||
| 361 | CODEC_SAMPLERATES_ARRAY(sbc_samplerates), | ||
| 362 | .p.priv_class = &sbc_class, | ||
| 363 | .p.profiles = NULL_IF_CONFIG_SMALL(ff_sbc_profiles), | ||
| 364 | }; | ||
| 365 |