Repository navigation
Conversation
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>
lgirdwood
force-pushed
the
topic/ffmpeg-lossless
branch
from
November 10, 2026 11:51
f41fccf to
2a735e9
Compare
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>
lgirdwood
force-pushed
the
topic/ffmpeg-lossless
branch
from
November 11, 2026 00:00
2a735e9 to
e3da217
Compare
Contributor
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Copilot review overview
9 open issues
Thesedrules/FLAC_MAX_BLOCKSIZE/1152/greplaces the macro name everywhere, which can break… · Newcd->in_bufis used for header sniffing (memcmp/alac_read_be32) without first… · New Whenprev_len == 0, the code passesindirectly to libavcodec (pkt_data = in) without… · Newffmpeg_dec_pcm_to_frame()return value is ignored here as well. Please handle conversion failures… · Newffmpeg_dec_pcm_to_frame()returns an error code, but the result is ignored. If it fails (e.g.,… · New This relies on the internal layout of libavcodec's private ALACContext (priv_data) to read… · New This relies on the internal layout of libavcodec's private ALACContext (priv_data) to read… · Newav_log_set_level()changes a global libav* logging level, which can affect other decoder/encoder… · New These comments say encode is provided viaffmpeg_dec, but the encode path is implemented under… · New
Review effort: Lite
| if(CONFIG_FFMPEG_ENC_FLAC) | ||
| set(_ff_extra_cflags "${_ff_extra_cflags} -I${SOF_FFMPEG_SRC_DIR}/libavcodec") | ||
| set(_ff_flacenc_prep | ||
| COMMAND sh -c "sed -e 's/FLAC_MAX_BLOCKSIZE/1152/g' -e 's/rc_sums\\[32\\]/rc_sums[1]/g' -e 's/subframes\\[FLAC_MAX_CHANNELS\\]/subframes[2]/g' -e 's/channels > FLAC_MAX_CHANNELS/channels > 2/g' <SOURCE_DIR>/libavcodec/flacenc.c > <BINARY_DIR>/libavcodec/flacenc.c") |
Comment on lines
+211
to
+229
| avail = source_get_data_available(src); | ||
|
|
||
| /* Step 4: Check for the 8-byte Core Audio Format ("caff\x00\x01\x00\x00") header */ | ||
| if (memcmp(cd->in_buf, "caff", 4) == 0) { | ||
| if (avail < 8) | ||
| return -ENODATA; | ||
|
|
||
| comp_info(dev, "CAF header detected, parsing ALAC container chunks"); | ||
| source_drop_data(src, 8); | ||
| cd->alac_parsing_caf = true; | ||
| return ffmpeg_dec_alac_skip_container(mod, src); | ||
| } | ||
|
|
||
| /* Step 5: Check for an inline 36-byte QuickTime 'alac' atom prefix */ | ||
| if (avail >= 8 && | ||
| alac_read_be32(cd->in_buf) == ALAC_EXTRADATA_SIZE && | ||
| memcmp(&cd->in_buf[4], "alac", 4) == 0) { | ||
| if (avail < ALAC_EXTRADATA_SIZE) | ||
| return -ENODATA; |
Comment on lines
+325
to
+339
| } else if (prev_len == 0) { | ||
| pkt_data = in; | ||
| pkt_len = in_size; | ||
| } else { | ||
| size_t space = prev_len < cap ? cap - prev_len : 0; | ||
| size_t copy = in_size < space ? in_size : space; | ||
|
|
||
| if (copy) { | ||
| memcpy_s(ff->pktbuf + prev_len, space, in, copy); | ||
| memset(ff->pktbuf + prev_len + copy, 0, | ||
| AV_INPUT_BUFFER_PADDING_SIZE); | ||
| } | ||
| pkt_data = ff->pktbuf; | ||
| pkt_len = prev_len + copy; | ||
| } |
Comment on lines
+167
to
+168
| ffmpeg_dec_pcm_to_frame(e->pcm_in, alac->frame, | ||
| e->src_fmt, ch, e->nb); |
Comment on lines
+167
to
+168
| ffmpeg_dec_pcm_to_frame(e->pcm_in, flac->frame, | ||
| e->src_fmt, ch, e->nb); |
Comment on lines
+32
to
+38
| struct alac_priv_prefix { | ||
| const void *av_class; | ||
| void *avctx; | ||
| const uint8_t *gb_buffer; | ||
| const uint8_t *gb_buffer_end; | ||
| int gb_index; | ||
| }; |
Comment on lines
+80
to
+88
| static size_t ffmpeg_dec_alac_frame_bytes_consumed(const void *priv_data) | ||
| { | ||
| const struct alac_priv_prefix *priv = priv_data; | ||
|
|
||
| if (!priv || priv->gb_index <= 0) | ||
| return 0; | ||
|
|
||
| return (size_t)((priv->gb_index + 7) >> 3); | ||
| } |
Comment on lines
+354
to
+358
| av_log_set_level(AV_LOG_FATAL); | ||
| ret = avcodec_send_packet(ff->avctx, ff->pkt); | ||
| if (ret == 0) | ||
| ret = avcodec_receive_frame(ff->avctx, ff->frame); | ||
| av_log_set_level(AV_LOG_ERROR); |
Comment on lines
+153
to
+162
| #if defined(CONFIG_FFMPEG_ENC_FLAC) | ||
| /* FLAC encode (compress capture) via ffmpeg_dec (native libavcodec). */ | ||
| codec_info.items[codec_info.count++] = | ||
| SET_CODEC_INFO_ITEM(SND_AUDIOCODEC_FLAC, SOF_IPC_STREAM_CAPTURE); | ||
| #endif | ||
| #if defined(CONFIG_FFMPEG_ENC_ALAC) | ||
| /* ALAC encode (compress capture) via ffmpeg_dec (native libavcodec). */ | ||
| codec_info.items[codec_info.count++] = | ||
| SET_CODEC_INFO_ITEM(SND_AUDIOCODEC_ALAC, SOF_IPC_STREAM_CAPTURE); | ||
| #endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Add Phase 1 lossless compress playback and capture codecs to
ffmpeg_decusing native fixed-pointlibavcodecimplementations:CONFIG_FFMPEG_DEC_ALAC,SND_AUDIOCODEC_ALAC):.cafcontainer parser (kukichunk 36-byte ALAC magic cookie extraction anddatachunk framing) and inline 36-byte QuickTime'alac'atom header support.GetBitContextand partial-frame reassembly across LL period boundaries.CONFIG_FFMPEG_ENC_FLAC,SND_AUDIOCODEC_FLAC):libavcodecflacencoder configured with fixed integer LPC predictors (FF_LPC_TYPE_FIXED,compression_level = 1) for deterministic low-MCPS DSP encoding."fLaC"+STREAMINFOmetadata block fromavctx->extradatato produce a self-contained.flacstream.FlacEncodeContextdimensions on a build-tree copy offlacenc.c(FLAC_MAX_BLOCKSIZE=1152,rc_sums[1],FLAC_MAX_CHANNELS=2), reducing context allocation 122x from 7.35 MiB to 43.5 KiB.CONFIG_FFMPEG_ENC_ALAC,SND_AUDIOCODEC_ALAC):libavcodecalacencoder configured with fixed LPC prediction (compression_level = 1) and planar S16 input conversion.'alac'magic cookie fromavctx->extradata.SND_AUDIOCODEC_ALACplayback andSND_AUDIOCODEC_FLAC/SND_AUDIOCODEC_ALACcapture inIPC4_SOF_CODEC_INFO.sof-hda-generic-ffmpeg-alac-compr,sof-hda-generic-ffmpeg-flac-enc-compr, andsof-hda-generic-ffmpeg-alac-enc-comprdevelopment topology targets.Hardware Verification (Aphid PTL ACE 3.0 & Spider TGL CAVS 2.5)
Verified end-to-end on both Aphid (
ptl) and Spider (tgl):.cafplayback (comprC0D50,codec_id=15)comprC0D51,codec_id=10) + round-trip playback (comprC0D50)comprC0D51,codec_id=15) + round-trip playback (comprC0D50)