From c0c7684d08d22d9b5c16c7beaf538f439d3f43bf Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 25 Sep 2026 16:37:36 +0000 Subject: [PATCH] avcodec/libspeexenc: preserve the encoded packet size ff_af_queue_remove() now returns a status code. Its return value replaced the byte count from speex_bits_write(), so every successful encode emitted an empty packet. Store the encoded byte count in the packet before updating its timing. Add generated-input FATE coverage for mono and stereo encoding, including multiple frames per packet. Check decoded frame counts instead of exact encoded bytes so the tests do not depend on libspeex's implementation. Select the PCM decoder dependency for the target endianness because lavfi exposes native-endian audio. Fixes: c31a781412a3aa801cc0997ba001177f258f4d80 Fixes: #23926 Assisted-by: Fairy --- libavcodec/libspeexenc.c | 3 +-- tests/fate/enc_external.mak | 15 +++++++++++++++ tests/ref/fate/libspeex-encode | 6 ++++++ tests/ref/fate/libspeex-encode-stereo | 6 ++++++ 4 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 tests/ref/fate/libspeex-encode create mode 100644 tests/ref/fate/libspeex-encode-stereo diff --git a/libavcodec/libspeexenc.c b/libavcodec/libspeexenc.c index 32abadcef1..6e1591b397 100644 --- a/libavcodec/libspeexenc.c +++ b/libavcodec/libspeexenc.c @@ -292,7 +292,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *avpkt, s->pkt_frame_count = 0; if ((ret = ff_alloc_packet(avctx, avpkt, speex_bits_nbytes(&s->bits))) < 0) return ret; - ret = speex_bits_write(&s->bits, avpkt->data, avpkt->size); + avpkt->size = speex_bits_write(&s->bits, avpkt->data, avpkt->size); speex_bits_reset(&s->bits); /* Get the next frame pts/duration */ @@ -301,7 +301,6 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *avpkt, if (ret < 0) return ret; - avpkt->size = ret; *got_packet_ptr = 1; return 0; } diff --git a/tests/fate/enc_external.mak b/tests/fate/enc_external.mak index 705f733db7..ec6ae83373 100644 --- a/tests/fate/enc_external.mak +++ b/tests/fate/enc_external.mak @@ -14,3 +14,18 @@ fate-libx264-hdr10: CMD = enc_external $(TARGET_SAMPLES)/hevc/hdr10_plus_h265_sa FATE_SAMPLES_FFMPEG_FFPROBE += $(FATE_ENC_EXTERNAL-yes) fate-enc-external: $(FATE_ENC_EXTERNAL-yes) + +# Check decoded frame counts without depending on libspeex's encoded bytes. +FATE_LIBSPEEX-$(call ALLYES, LIBSPEEX_ENCODER SPEEX_DECODER OGG_MUXER OGG_DEMUXER LAVFI_INDEV SINE_FILTER ARESAMPLE_FILTER \ + PCM_S16$(if $(filter yes,$(HAVE_BIGENDIAN)),BE,LE)_DECODER FILE_PROTOCOL) += fate-libspeex-encode fate-libspeex-encode-stereo +fate-libspeex-encode: SPEEX_OPTS = -ac 1 +fate-libspeex-encode-stereo: SPEEX_OPTS = -ac 2 -frames_per_packet 2 +$(FATE_LIBSPEEX-yes): CMD = run_with_temp \ + "$(FFMPEG) -nostdin -hide_banner -loglevel error \ + -f lavfi -i sine=frequency=1000:sample_rate=32000:duration=1 \ + -c:a libspeex -b:a 30k $(SPEEX_OPTS) -f ogg -y" \ + "ffprobe$(PROGSSUF)$(EXESUF) -v error -bitexact -count_frames \ + -show_entries stream=codec_name,sample_rate,channels,nb_read_frames" ogg + +FATE_FFMPEG_FFPROBE += $(FATE_LIBSPEEX-yes) +fate-enc-external: $(FATE_LIBSPEEX-yes) diff --git a/tests/ref/fate/libspeex-encode b/tests/ref/fate/libspeex-encode new file mode 100644 index 0000000000..179ea07d71 --- /dev/null +++ b/tests/ref/fate/libspeex-encode @@ -0,0 +1,6 @@ +[STREAM] +codec_name=speex +sample_rate=32000 +channels=1 +nb_read_frames=50 +[/STREAM] diff --git a/tests/ref/fate/libspeex-encode-stereo b/tests/ref/fate/libspeex-encode-stereo new file mode 100644 index 0000000000..ea01697eb4 --- /dev/null +++ b/tests/ref/fate/libspeex-encode-stereo @@ -0,0 +1,6 @@ +[STREAM] +codec_name=speex +sample_rate=32000 +channels=2 +nb_read_frames=25 +[/STREAM]