From: cenzhanquan1 via ffmpeg-devel <ffmpeg-devel@ffmpeg.org> To: ffmpeg-devel@ffmpeg.org Cc: cenzhanquan1 <code@ffmpeg.org> Subject: [FFmpeg-devel] [PATCH] avcodec/liblc3: add support for multiple sample formats. (PR #20601) Date: Wed, 24 Sep 2025 14:49:54 -0000 Message-ID: <175872539476.25.3289690234759195646@bf249f23a2c8> (raw) PR #20601 opened by cenzhanquan1 URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20601 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20601.patch - Decoder: - Respect request_sample_fmt if set, default to S16 instead of FLTP - Add support for S16, S16P, FLT and FLTP sample formats - Properly handle both planar and interleaved layouts - Calculate correct data pointers and stride for liblc3 - Encoder: - Add support for S16, S16P, FLT and FLTP sample formats - Remove hardcoded use of LC3_PCM_FORMAT_FLOAT - Handle both planar and interleaved input data - Update zero frame allocation to account for sample size - Update codec capabilities to include all supported sample formats - Enhance error handling for unsupported formats Signed-off-by: cenzhanquan1 <cenzhanquan1@xiaomi.com> >From 0e560e67ae62ba568b0bcf2dc10fb322cd8fff3f Mon Sep 17 00:00:00 2001 From: cenzhanquan1 <cenzhanquan1@xiaomi.com> Date: Wed, 24 Sep 2025 22:43:18 +0800 Subject: [PATCH] avcodec/liblc3: add support for multiple sample formats. - Decoder: - Respect request_sample_fmt if set, default to S16 instead of FLTP - Add support for S16, S16P, FLT and FLTP sample formats - Properly handle both planar and interleaved layouts - Calculate correct data pointers and stride for liblc3 - Encoder: - Add support for S16, S16P, FLT and FLTP sample formats - Remove hardcoded use of LC3_PCM_FORMAT_FLOAT - Handle both planar and interleaved input data - Update zero frame allocation to account for sample size - Update codec capabilities to include all supported sample formats - Enhance error handling for unsupported formats Signed-off-by: cenzhanquan1 <cenzhanquan1@xiaomi.com> --- libavcodec/liblc3dec.c | 47 ++++++++++++++++++++++++++++++++++++------ libavcodec/liblc3enc.c | 46 ++++++++++++++++++++++++++++++++++------- 2 files changed, 79 insertions(+), 14 deletions(-) diff --git a/libavcodec/liblc3dec.c b/libavcodec/liblc3dec.c index d250ace38a..50154b911b 100644 --- a/libavcodec/liblc3dec.c +++ b/libavcodec/liblc3dec.c @@ -82,7 +82,12 @@ static av_cold int liblc3_decode_init(AVCodecContext *avctx) (char *)liblc3->decoder_mem + ch * decoder_size); } - avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; + if (avctx->request_sample_fmt != AV_SAMPLE_FMT_NONE) { + avctx->sample_fmt = avctx->request_sample_fmt; + } else { + avctx->sample_fmt = AV_SAMPLE_FMT_S16; + } + avctx->delay = lc3_hr_delay_samples( liblc3->hr_mode, liblc3->frame_us, liblc3->srate_hz); avctx->internal->skip_samples = avctx->delay; @@ -104,8 +109,10 @@ static int liblc3_decode(AVCodecContext *avctx, AVFrame *frame, { LibLC3DecContext *liblc3 = avctx->priv_data; int channels = avctx->ch_layout.nb_channels; - uint8_t *in = avpkt->data; + enum lc3_pcm_format liblc3_format; int block_bytes, ret; + size_t sample_size; + int is_planar; frame->nb_samples = av_rescale( liblc3->frame_us, liblc3->srate_hz, 1000*1000); @@ -113,15 +120,43 @@ static int liblc3_decode(AVCodecContext *avctx, AVFrame *frame, return ret; block_bytes = avpkt->size; + + switch (avctx->sample_fmt) { + case AV_SAMPLE_FMT_S16: + case AV_SAMPLE_FMT_S16P: + liblc3_format = LC3_PCM_FORMAT_S16; + break; + case AV_SAMPLE_FMT_FLT: + case AV_SAMPLE_FMT_FLTP: + liblc3_format = LC3_PCM_FORMAT_FLOAT; + break; + default: + av_log(NULL, AV_LOG_ERROR, + "Unsupported sample format %s\n", + av_get_sample_fmt_name(avctx->sample_fmt)); + return AVERROR(EINVAL); + } + + is_planar = av_sample_fmt_is_planar(avctx->sample_fmt); + sample_size = av_get_bytes_per_sample(avctx->sample_fmt); + for (int ch = 0; ch < channels; ch++) { int nbytes = block_bytes / channels + (ch < block_bytes % channels); + void *pcm_data; + int stride; - ret = lc3_decode(liblc3->decoder[ch], in, nbytes, - LC3_PCM_FORMAT_FLOAT, frame->data[ch], 1); + if (is_planar) { + pcm_data = frame->extended_data[ch]; + stride = 1; + } else { + pcm_data = (uint8_t *)frame->extended_data[0] + ch * sample_size; + stride = channels; + } + + ret = lc3_decode(liblc3->decoder[ch], avpkt->data + ch * nbytes, nbytes, + liblc3_format, pcm_data, stride); if (ret < 0) return AVERROR_INVALIDDATA; - - in += nbytes; } frame->nb_samples = FFMIN(frame->nb_samples, avpkt->duration); diff --git a/libavcodec/liblc3enc.c b/libavcodec/liblc3enc.c index 66007a90f3..8aee9304b9 100644 --- a/libavcodec/liblc3enc.c +++ b/libavcodec/liblc3enc.c @@ -137,10 +137,30 @@ static int liblc3_encode(AVCodecContext *avctx, AVPacket *pkt, LibLC3EncContext *liblc3 = avctx->priv_data; int block_bytes = liblc3->block_bytes; int channels = avctx->ch_layout.nb_channels; + enum lc3_pcm_format lc3_format; void *zero_frame = NULL; - uint8_t *data_ptr; + size_t sample_size; + int is_planar; int ret; + is_planar = av_sample_fmt_is_planar(avctx->sample_fmt); + sample_size = av_get_bytes_per_sample(avctx->sample_fmt); + + switch (avctx->sample_fmt) { + case AV_SAMPLE_FMT_S16P: + case AV_SAMPLE_FMT_S16: + lc3_format = LC3_PCM_FORMAT_S16; + break; + case AV_SAMPLE_FMT_FLT: + case AV_SAMPLE_FMT_FLTP: + lc3_format = LC3_PCM_FORMAT_FLOAT; + break; + default: + av_log(avctx, AV_LOG_ERROR, "Unsupported sample format: %s\n", + av_get_sample_fmt_name(avctx->sample_fmt)); + return AVERROR(EINVAL); + } + if ((ret = ff_get_encode_buffer(avctx, pkt, block_bytes, 0)) < 0) return ret; @@ -152,20 +172,30 @@ static int liblc3_encode(AVCodecContext *avctx, AVPacket *pkt, return 0; liblc3->remaining_samples = 0; - zero_frame = av_mallocz(avctx->frame_size * sizeof(float)); + zero_frame = av_mallocz(avctx->frame_size * channels * sample_size); if (!zero_frame) return AVERROR(ENOMEM); } - data_ptr = pkt->data; for (int ch = 0; ch < channels; ch++) { - const float *pcm = zero_frame ? zero_frame : frame->data[ch]; int nbytes = block_bytes / channels + (ch < block_bytes % channels); + const void *pcm; + int stride; + + if (zero_frame) { + pcm = (uint8_t *)zero_frame + ch * (is_planar ? avctx->frame_size * sample_size : sample_size); + } else { + if (is_planar) { + pcm = frame->data[ch]; + stride = 1; + } else { + pcm = frame->data[0] + ch * sample_size; + stride = channels; + } + } lc3_encode(liblc3->encoder[ch], - LC3_PCM_FORMAT_FLOAT, pcm, 1, nbytes, data_ptr); - - data_ptr += nbytes; + lc3_format, pcm, stride, nbytes, pkt->data + ch * nbytes); } if (zero_frame) @@ -204,7 +234,7 @@ const FFCodec ff_liblc3_encoder = { .p.priv_class = &class, .p.wrapper_name = "liblc3", CODEC_SAMPLERATES(96000, 48000, 32000, 24000, 16000, 8000), - CODEC_SAMPLEFMTS(AV_SAMPLE_FMT_FLTP), + CODEC_SAMPLEFMTS(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16P), .priv_data_size = sizeof(LibLC3EncContext), .init = liblc3_encode_init, .close = liblc3_encode_close, -- 2.49.1 _______________________________________________ ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
reply other threads:[~2025-09-24 14:50 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=175872539476.25.3289690234759195646@bf249f23a2c8 \ --to=ffmpeg-devel@ffmpeg.org \ --cc=code@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror http://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ http://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git