Commit b0879b636a for ffmpeg
commit b0879b636aaa4d144e87a1f872a7e6c27be4b52c
Author: Patrick Domack <patrickdk@patrickdk.com>
Date: Sun Nov 1 04:56:40 2026 -0500
avcodec/g723_1dec: start as if the previous frame was active
The ITU reference starts with the previous frame type set to active
(DS2-Anywhere SPEC.md section 3). FFmpeg starts with SID_FRAME, as it
has since 04fc5c6bde (2012). That changes the output when a stream
starts with something other than a good active frame:
- A SID frame: FFmpeg smooths its gain up from 0, (7 * 0 + gain) >> 3,
so the comfort noise starts at an eighth of its level. The reference
uses the gain as it is.
- A lost or invalid frame: both decode it to silence, but the
reference conceals it as an active frame and FFmpeg treats it as
untransmitted. A SID frame after it then gets the full gain in the
reference and the smoothed one in FFmpeg. FFmpeg's comfort noise
generator has also drawn 30 random numbers more by then, because
the reference resets its seed for the concealed frame.
A stream that starts with an untransmitted frame decodes the same
either way.
Start with past_frame_type set to ACTIVE_FRAME, in g723_1_reset(),
which init and the flush callback call.
Over the 35 random streams, the frames that differ from the reference
drop from 378 to 5 with the postfilter on and from 190 to 5 with it
off. The streams that differ drop from 7 to 1.
Frame 0 of cng-erasures.tco, a stream that a later commit adds to FATE,
is a SID frame. With the postfilter on and every G.723.1 fix but this
one, sample 9 is 82 where the reference gives 663, and 17 frames differ.
lost-start.tco holds 17 frames in 138 bytes: two invalid 6.3 kbit/s
frames, a SID frame, untransmitted frames, three valid 6.3 kbit/s
frames, and untransmitted frames around a second SID frame. With this
commit left out, frames 0 and 1 still match the reference, and frames
2 to 16 differ, with the postfilter on and off.
fate-g723_1-dec-13 decodes lost-start.tco with the postfilter on, and
fate-g723_1-dec-14 with it off. Their refs match the DS2-Anywhere
G.723.1 decoder frame for frame. Both tests fail with this fix or the
Annex A fix left out. fate-g723_1-dec-1 to -8 pass unchanged.
Upload the sample to fate-suite as g723_1/lost-start.tco.
Signed-off-by: Patrick Domack <patrickdk@patrickdk.com>
diff --git a/libavcodec/g723_1dec.c b/libavcodec/g723_1dec.c
index ad335dc8db..845af6a628 100644
--- a/libavcodec/g723_1dec.c
+++ b/libavcodec/g723_1dec.c
@@ -126,7 +126,7 @@ static void g723_1_reset(AVCodecContext *avctx)
memcpy(p->sid_lsp, dc_lsp, LPC_ORDER * sizeof(*p->sid_lsp));
p->cng_random_seed = CNG_RANDOM_SEED;
- p->past_frame_type = SID_FRAME;
+ p->past_frame_type = ACTIVE_FRAME;
}
}
diff --git a/tests/fate/voice.mak b/tests/fate/voice.mak
index 7b4642fc59..5acd56d178 100644
--- a/tests/fate/voice.mak
+++ b/tests/fate/voice.mak
@@ -47,6 +47,12 @@ fate-g723_1-dec-7: CMD = framecrc -postfilter 1 -i $(TARGET_SAMPLES)/g723_1/dtx6
FATE_G723_1 += fate-g723_1-dec-8
fate-g723_1-dec-8: CMD = framecrc -postfilter 1 -i $(TARGET_SAMPLES)/g723_1/dtx63e.tco -af aresample
+FATE_G723_1 += fate-g723_1-dec-13
+fate-g723_1-dec-13: CMD = framecrc -postfilter 1 -i $(TARGET_SAMPLES)/g723_1/lost-start.tco -af aresample
+
+FATE_G723_1 += fate-g723_1-dec-14
+fate-g723_1-dec-14: CMD = framecrc -postfilter 0 -i $(TARGET_SAMPLES)/g723_1/lost-start.tco -af aresample
+
FATE_VOICE-$(call FRAMECRC, G723_1, G723_1, ARESAMPLE_FILTER) += $(FATE_G723_1)
fate-g723_1: $(FATE_G723_1)
diff --git a/tests/ref/fate/g723_1-dec-13 b/tests/ref/fate/g723_1-dec-13
new file mode 100644
index 0000000000..9b8fee9cc2
--- /dev/null
+++ b/tests/ref/fate/g723_1-dec-13
@@ -0,0 +1,22 @@
+#tb 0: 1/8000
+#media_type 0: audio
+#codec_id 0: pcm_s16le
+#sample_rate 0: 8000
+#channel_layout_name 0: mono
+0, 0, 0, 240, 480, 0x00000000
+0, 240, 240, 240, 480, 0x00000000
+0, 480, 480, 240, 480, 0x9480dd02
+0, 720, 720, 240, 480, 0xb057f95f
+0, 960, 960, 240, 480, 0x33e3f142
+0, 1200, 1200, 240, 480, 0x3764efc1
+0, 1440, 1440, 240, 480, 0x160ae5b8
+0, 1680, 1680, 240, 480, 0xe2c1e2e3
+0, 1920, 1920, 240, 480, 0x34160118
+0, 2160, 2160, 240, 480, 0x381016e7
+0, 2400, 2400, 240, 480, 0xc895f248
+0, 2640, 2640, 240, 480, 0xc05feaf9
+0, 2880, 2880, 240, 480, 0xa143dc47
+0, 3120, 3120, 240, 480, 0xbe7ef523
+0, 3360, 3360, 240, 480, 0x8ed10498
+0, 3600, 3600, 240, 480, 0xf230076a
+0, 3840, 3840, 240, 480, 0x3da7f716
diff --git a/tests/ref/fate/g723_1-dec-14 b/tests/ref/fate/g723_1-dec-14
new file mode 100644
index 0000000000..17a0e82bfd
--- /dev/null
+++ b/tests/ref/fate/g723_1-dec-14
@@ -0,0 +1,22 @@
+#tb 0: 1/8000
+#media_type 0: audio
+#codec_id 0: pcm_s16le
+#sample_rate 0: 8000
+#channel_layout_name 0: mono
+0, 0, 0, 240, 480, 0x00000000
+0, 240, 240, 240, 480, 0x00000000
+0, 480, 480, 240, 480, 0xbec0dfdc
+0, 720, 720, 240, 480, 0xa7eef911
+0, 960, 960, 240, 480, 0x1c69fcf1
+0, 1200, 1200, 240, 480, 0xc554f334
+0, 1440, 1440, 240, 480, 0xbf98ea0d
+0, 1680, 1680, 240, 480, 0x6c49df70
+0, 1920, 1920, 240, 480, 0xf7810151
+0, 2160, 2160, 240, 480, 0xc4b61932
+0, 2400, 2400, 240, 480, 0x3bfff0d1
+0, 2640, 2640, 240, 480, 0xea4ce757
+0, 2880, 2880, 240, 480, 0xe463e27f
+0, 3120, 3120, 240, 480, 0x850afacf
+0, 3360, 3360, 240, 480, 0x67ddfc58
+0, 3600, 3600, 240, 480, 0xc89908b4
+0, 3840, 3840, 240, 480, 0x21fef29e