Skip to content

ffmpeg_dec: add Bluetooth SBC/mSBC, G.722, and aptX decode and encode support - #11431

Draft
lgirdwood wants to merge 12 commits into
thesofproject:mainfrom
lgirdwood:topic/ffmpeg-bt-voice
Draft

lgirdwood wants to merge 12 commits into
thesofproject:mainfrom
lgirdwood:topic/ffmpeg-bt-voice

Conversation

@lgirdwood

Copy link
Copy Markdown
Member

Summary

Add Phase 2 Bluetooth & Voice Offload codec support to ffmpeg_dec / ffmpeg_enc (stacked on top of Phase 1 lossless support in #11427):

  • Bluetooth A2DP SBC & HFP Wideband Speech mSBC (SND_AUDIOCODEC_SBC = 0x12):
    • CONFIG_FFMPEG_DEC_SBC: native libavcodec sbc decoder + parser (--enable-decoder=sbc --enable-parser=sbc), handling both A2DP SBC (0x9c syncword) and HFP mSBC (0xad syncword) bitstreams.
    • CONFIG_FFMPEG_ENC_SBC: native libavcodec sbc encoder (--enable-encoder=sbc), supporting both standard A2DP SBC and HFP Wideband Speech mSBC (profile = 1, FF_PROFILE_SBC_MSBC, 16 kHz mono with 3:1 decimation from 48 kHz capture pipelines).
  • ITU-T G.722 Wideband Speech ADPCM (SND_AUDIOCODEC_G722 = 0x13):
    • CONFIG_FFMPEG_DEC_G722: native libavcodec adpcm_g722 integer QMF + 2-band ADPCM decoder (--enable-decoder=adpcm_g722), with mono-to-stereo upmixing in ffmpeg_dec_convert_frame() when the downstream sink is stereo.
    • CONFIG_FFMPEG_ENC_G722: native libavcodec adpcm_g722 encoder (--enable-encoder=adpcm_g722), extracting mono S16 samples via ffmpeg_enc_pcm_to_s16_mono().
  • Bluetooth aptX (SND_AUDIOCODEC_APTX = 0x14):
    • CONFIG_FFMPEG_DEC_APTX: native libavcodec aptx integer 4-band QMF + ADPCM decoder (--enable-decoder=aptx) with 4-byte block_align packet clamping.
    • CONFIG_FFMPEG_ENC_APTX: native libavcodec aptx encoder (--enable-encoder=aptx) with planar S32 conversion via ffmpeg_enc_pcm_to_s32_planar().
  • Development Topologies:
    • Added sof-hda-generic-ffmpeg-{sbc,g722,aptx}-compr and sof-hda-generic-ffmpeg-{sbc,g722,aptx}-enc-compr targets in tools/topology/topology2/development/tplg-targets.cmake.

All 6 codecs are pure integer / fixed-point in libavcodec with zero floating-point math dependency and ~32–36 KB total image footprint when all 6 are enabled together.

Hardware Verification

Verified encode + round-trip decode on both Panther Lake (ptl / ACE 3.0, Clang) and Tiger Lake (tgl / CAVS 2.5, GCC) hardware:

  • SBC encode (comprC0D51) & round-trip decode (comprC0D50)
  • mSBC (profile = 1) encode (comprC0D51) & round-trip decode (comprC0D50)
  • G.722 encode (comprC0D51) & round-trip decode (comprC0D50)
  • aptX encode (comprC0D51) & round-trip decode (comprC0D50)
  • All DSP-encoded bitstreams verified with ffmpeg -v error on host.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved critical defects in codec configuration, sample-rate handling, and buffering can produce incorrect audio, silently discard frames, or stall playback indefinitely.

11 open issues
What changed in this PR

Extends SOF’s FFmpeg-based compressed playback and capture with SBC/mSBC, G.722, and aptX support, building on the Phase 1 lossless work in #11427.

Changes:

  • Adds codec implementations, PCM conversion helpers, and unparsed-stream handling.
  • Integrates codec selection into Kconfig, built-in and loadable-module builds, and firmware capability reporting.
  • Adds development topology targets for Bluetooth, voice, and lossless codecs.
File Description
tools/​topology/​topology2/​development/​tplg-targets.cmake Adds compressed playback and capture targets.
src/​kernel/​audio/​base_fw.c Advertises added codec capabilities and BESPOKE aliases.
src/​include/​ipc/​compress_params.h Defines SBC, G.722, and aptX codec IDs.
src/​audio/​ffmpeg_dec/​llext/​CMakeLists.txt Includes added codecs in loadable-module builds.
src/​audio/​ffmpeg_dec/​Kconfig Adds decoder and encoder configuration options.
src/​audio/​ffmpeg_dec/​ffmpeg.cmake Enables native codecs and reduces FLAC encoder allocations.
src/​audio/​ffmpeg_dec/​ffmpeg-encode.c Extends encoder dispatch, conversion, and parameter handling.
src/​audio/​ffmpeg_dec/​ffmpeg-enc-sbc.c Implements SBC/mSBC encoding and capture conversion.
src/​audio/​ffmpeg_dec/​ffmpeg-enc-mp3.c Keeps MP3 rate-control validation codec-specific.
src/​audio/​ffmpeg_dec/​ffmpeg-enc-g722.c Implements mono G.722 encoding.
src/​audio/​ffmpeg_dec/​ffmpeg-enc-flac.c Implements FLAC encoding with a stream header.
src/​audio/​ffmpeg_dec/​ffmpeg-enc-aptx.c Implements stereo aptX encoding.
src/​audio/​ffmpeg_dec/​ffmpeg-enc-alac.c Implements ALAC encoding with a setup cookie.
src/​audio/​ffmpeg_dec/​ffmpeg-enc-aac.c Keeps AAC rate-control validation codec-specific.
src/​audio/​ffmpeg_dec/​ffmpeg_dec.h Extends codec interfaces and stream state.
src/​audio/​ffmpeg_dec/​ffmpeg_dec.c Registers codecs and handles selection and reset state.
src/​audio/​ffmpeg_dec/​ffmpeg_dec-sbc.c Defines SBC/mSBC decoder frame sizing.
src/​audio/​ffmpeg_dec/​ffmpeg_dec-g722.c Bounds G.722 decode packet sizes.
src/​audio/​ffmpeg_dec/​ffmpeg_dec-ffmpeg.c Adds codec mappings and unparsed-packet buffering.
src/​audio/​ffmpeg_dec/​ffmpeg_dec-convert.c Supports mono output duplication across sink channels.
src/​audio/​ffmpeg_dec/​ffmpeg_dec-aptx.c Defines aptX packet alignment and size limits.
src/​audio/​ffmpeg_dec/​ffmpeg_dec-alac.c Parses ALAC containers, cookies, and frame consumption.
src/​audio/​ffmpeg_dec/​CMakeLists.txt Includes added codecs in built-in builds.

Review effort: Balanced

Comment thread src/audio/ffmpeg_dec/ffmpeg-enc-alac.c Resolved
Comment thread src/audio/ffmpeg_dec/ffmpeg-enc-g722.c Resolved
Comment thread src/audio/ffmpeg_dec/ffmpeg-enc-sbc.c Resolved
Comment thread src/audio/ffmpeg_dec/ffmpeg-enc-sbc.c Resolved
Comment thread src/audio/ffmpeg_dec/ffmpeg_dec-alac.c Resolved
Comment thread src/audio/ffmpeg_dec/ffmpeg_dec-g722.c Resolved
Comment thread src/audio/ffmpeg_dec/ffmpeg-enc-sbc.c Resolved
Comment thread src/audio/ffmpeg_dec/ffmpeg-enc-sbc.c Resolved
Comment thread src/audio/ffmpeg_dec/ffmpeg-encode.c Resolved
Advertise SND_AUDIOCODEC_ALAC decode and SND_AUDIOCODEC_FLAC /
SND_AUDIOCODEC_ALAC encode capabilities in base_fw when the
corresponding FFmpeg Kconfig options are enabled.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Extend the FFmpeg decode and encode adapter infrastructure to support
container-framed and variable-blocksize lossless codecs:
- Add frame_bytes_consumed hook and unparsed packet reassembly buffer
  handling in ffmpeg_dec-ffmpeg.c for codecs without a standalone
  AVCodecParser (such as ALAC).
- Extend ffmpeg_dec_pcm_to_frame() in ffmpeg_dec-convert.c to support
  AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S32, and
  AV_SAMPLE_FMT_S32P sample formats.
- Add an optional encoder flush() hook in struct ffmpeg_enc_codec_ops
  and support native libavcodec encoders in ffmpeg.cmake.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Add Apple Lossless Audio Codec (ALAC, SND_AUDIOCODEC_ALAC) decoder
support via libavcodec's integer alac decoder:
- Support raw ALAC packets with 36-byte out-of-band magic cookie
  extradata as well as self-contained Core Audio Format (.caf) streams.
- Resize the PCM output staging buffer if the magic cookie's
  max_samples per frame exceeds the initial allocation.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Add native libavcodec FLAC lossless encoder (SND_AUDIOCODEC_FLAC)
support for compress capture streams:
- Use fixed integer LPC predictors (FF_LPC_TYPE_FIXED,
  compression_level 1) with 1152-sample blocks and zero floating-point
  instructions in the per-frame encode path.
- Prepend the 42-byte "fLaC" + STREAMINFO header on stream start and
  convert input PCM via ffmpeg_dec_pcm_to_frame().

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Add native libavcodec ALAC lossless encoder (SND_AUDIOCODEC_ALAC)
support for 1..2 channel compress capture streams:
- Configure 1024-sample frame size using pure integer prediction and
  adaptive Rice coding.
- Prepend a 64-byte Core Audio Format (.caf) header ("caff" + "desc" +
  "kuki" + "data") so captured streams are directly decodable.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Add development topology targets for ALAC compress playback and
FLAC/ALAC compress capture on CAVS 2.5 and ACE 3.0.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Add SND_AUDIOCODEC_SBC (0x12), SND_AUDIOCODEC_G722 (0x13), and
SND_AUDIOCODEC_APTX (0x14) definitions to compress_params.h and
advertise them in base_fw.c alongside SND_AUDIOCODEC_BESPOKE when
their corresponding Kconfig symbols are enabled.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Extend the FFmpeg decode and encode adapter infrastructure for
Bluetooth and wideband voice codecs:
- Support SND_AUDIOCODEC_BESPOKE sub-codec dispatch via reserved[0],
  requested bitrate propagation, and encoder profile selection.
- Add limit_packet_size hook in struct ffmpeg_dec_codec_ops and
  explicit decoder sample rate / G.722 bits_per_codeword initialization
  in ffmpeg_dec-ffmpeg.c.
- Add stateful 13-tap FIR low-pass anti-aliased 3:1 (48->16 kHz) mono
  decimation helper ffmpeg_dec_pcm_decimate_3to1_s16_mono() in
  ffmpeg_dec-convert.c.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Add Bluetooth A2DP Subband Codec (SBC) and HFP Wideband Speech (mSBC)
decode and encode support (SND_AUDIOCODEC_SBC) via libavcodec's integer
sbc codec and parser:
- Support standard A2DP SBC (16/32/44.1/48 kHz, 1..2 channels) and
  HFP mSBC (profile == AV_PROFILE_SBC_MSBC, 16 kHz mono, 120-sample
  57-byte frames).
- Support 48->16 kHz anti-aliased decimation when capturing 48 kHz
  pipeline audio into a 16 kHz mSBC stream.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Add ITU-T G.722 7 kHz wideband speech ADPCM decode and encode support
(SND_AUDIOCODEC_G722) via libavcodec's integer adpcm_g722 codec:
- Support 64/56/48 kbps G.722 playback with 160-byte (320-sample,
  20 ms) packet clamping.
- Support 16 kHz mono G.722 encoding at 64 kbps, including
  anti-aliased 3:1 decimation when fed by a 48 kHz capture pipeline.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Add Bluetooth classic aptX stereo audio decode and encode support
(SND_AUDIOCODEC_APTX) via libavcodec's integer aptx codec:
- Clamp incoming aptX packets to 4-byte codeword boundaries (<= 512
  bytes, <= 512 stereo samples per decode call).
- Encode 256-sample stereo S32P blocks into 256-byte aptX packets
  using ffmpeg_dec_pcm_to_frame().

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Add development topology targets for SBC, G.722, and aptX compress
playback and capture.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return -ENOTSUP;
}

return 0;
Comment on lines +260 to +263
ff->pktbuf_sz = cd->out_frame_bytes ?
(size_t)cd->out_frame_bytes * 4096 : 65536;
if (ff->pktbuf_sz < 65536)
ff->pktbuf_sz = 65536;
ff->pktbuf_len = 0;
return 0;
}
if (pkt_len >= cap) {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants