Commit b988992c0e for ffmpeg
commit b988992c0e141597b9cc2e54e1a40d82eb0d71de
Author: Patrick Domack <patrickdk@patrickdk.com>
Date: Sun Nov 1 04:56:43 2026 -0500
avcodec/g723_1dec: track bad frames per channel
Stereo support, added in 62dbcb7ddf (2018), moved the decoding into a
loop over the channels but left bad_frame declared once for the whole
packet. Once one channel's frame fails the validity checks, every
channel after it in that packet is decoded as a lost frame too, even
when its own frame is fine, and its state then drifts away from what
its own frames would give.
Declare bad_frame inside the channel loop.
No demuxer hands the decoder a stereo G.723.1 stream, so I tested this
with a small libavcodec program. It sends 2000 packets of two 6.3
kbit/s frames to a stereo decoder, with about 10 percent of the frames
in each channel made invalid at random, and sends each channel's
frames to a mono decoder of its own. Before this change, channel 1 of
the stereo output differed from its mono decode in 1788 of the 2000
frames. Now neither channel differs in any frame.
Mono decoding does not change: all 374 test streams still match the
reference with the postfilter on and off. No FATE test reaches stereo
decoding, since the g723_1 demuxer is mono.
Signed-off-by: Patrick Domack <patrickdk@patrickdk.com>
diff --git a/libavcodec/g723_1dec.c b/libavcodec/g723_1dec.c
index a4c5bdd1d4..0cede33724 100644
--- a/libavcodec/g723_1dec.c
+++ b/libavcodec/g723_1dec.c
@@ -953,7 +953,7 @@ static int g723_1_decode_frame(AVCodecContext *avctx, AVFrame *frame,
int16_t lpc[SUBFRAMES * LPC_ORDER];
int16_t acb_vector[SUBFRAME_LEN];
int16_t *out;
- int bad_frame = 0, i, j, ret;
+ int i, j, ret;
if (buf_size < frame_size[dec_mode] * channels) {
if (buf_size)
@@ -971,6 +971,7 @@ static int g723_1_decode_frame(AVCodecContext *avctx, AVFrame *frame,
for (int ch = 0; ch < channels; ch++) {
G723_1_ChannelContext *p = &s->ch[ch];
int16_t *audio = p->audio;
+ int bad_frame = 0;
if (unpack_bitstream(p, buf + ch * (buf_size / channels),
buf_size / channels) < 0) {