Commit 6681908349 for ffmpeg

commit 66819083494e2dbe84d413dc7c5bc252768ba0b0
Author: Patrick Domack <patrickdk@patrickdk.com>
Date:   Sun Nov 1 04:56:40 2026 -0500

    avcodec/g723_1: saturate the negated LPC coefficients like the reference

    The ITU reference computes each LPC coefficient as neg16(round16(x)),
    and neg16(-32768) saturates to 32767 (DS2-Anywhere SPEC.md section
    4.3.2, step 4). FFmpeg stores the coefficients negated, as round16(x),
    and its synthesis filter subtracts them. When round16(x) is -32768,
    FFmpeg's filter uses +32768 where the reference uses 32767. This has
    been so since the decoder was added in 2011.

    Clamp the stored value at -INT16_MAX. The encoder shares this code
    through ff_g723_1_lsp_interpolate(), and fate-acodec-g723_1 passes
    unchanged.

    The cosine step at the top of lsp2lpc() negates too. It could only
    give -32768 for an LSP of 32736 or more. The largest LSP in any of the
    test streams is 31159, at frame 690 of g723-mix.g723pk.

    Over the 35 random streams, the last 5 frames that differed from the
    reference now match, with the postfilter on and with it off. These
    streams draw their gains at random and never get loud enough to
    saturate the synthesis filter or the formant postfilter. The next
    three commits handle that.

    Frame 91 of cng-erasures.tco is a 6.3 kbit/s frame after an
    untransmitted frame. Its last subframe saturates coefficient 4. With
    the postfilter on and every G.723.1 fix but this one, the frame parts
    from the reference at sample 193 by up to 46, and 4 frames differ.

    cng-erasures.tco holds 97 frames in 1377 bytes: 35 at 6.3 kbit/s, 22
    at 5.3 kbit/s, 19 SID frames and 21 untransmitted ones. 9 active
    frames fail the validity checks. 7 of them follow an active frame and
    are concealed, and the other 2 count as untransmitted. 14
    untransmitted frames follow an active frame, so their SID frame was
    lost. The stream starts with a SID frame, loses three active frames in
    a row at frames 69 to 71, and saturates an LPC coefficient at frame
    91. Before the G.723.1 fixes, all 97 frames differ from the reference.

    fate-g723_1-dec-9 decodes cng-erasures.tco with the postfilter on, and
    fate-g723_1-dec-10 with it off. Their refs match the DS2-Anywhere
    G.723.1 decoder frame for frame. Both tests fail with this fix or any
    of the four G.723.1 fixes before it left out. fate-g723_1-dec-1 to -8
    pass unchanged.

    Upload the sample to fate-suite as g723_1/cng-erasures.tco.

    Signed-off-by: Patrick Domack <patrickdk@patrickdk.com>

diff --git a/libavcodec/g723_1.c b/libavcodec/g723_1.c
index d19d09dd89..1bd8f99770 100644
--- a/libavcodec/g723_1.c
+++ b/libavcodec/g723_1.c
@@ -1243,9 +1243,11 @@ static void lsp2lpc(int16_t *lpc)
         int64_t ff1 = f1[i + 1] + f1[i];
         int64_t ff2 = f2[i + 1] - f2[i];

-        lpc[i] = av_clipl_int32(((ff1 + ff2) * 8) + (1 << 15)) >> 16;
-        lpc[LPC_ORDER - i - 1] = av_clipl_int32(((ff1 - ff2) * 8) +
-                                                (1 << 15)) >> 16;
+        lpc[i] = FFMAX(av_clipl_int32(((ff1 + ff2) * 8) + (1 << 15)) >> 16,
+                       -INT16_MAX);
+        lpc[LPC_ORDER - i - 1] = FFMAX(av_clipl_int32(((ff1 - ff2) * 8) +
+                                                      (1 << 15)) >> 16,
+                                       -INT16_MAX);
     }
 }

diff --git a/tests/fate/voice.mak b/tests/fate/voice.mak
index 5acd56d178..d5c09c2daf 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-9
+fate-g723_1-dec-9: CMD = framecrc -postfilter 1 -i $(TARGET_SAMPLES)/g723_1/cng-erasures.tco -af aresample
+
+FATE_G723_1 += fate-g723_1-dec-10
+fate-g723_1-dec-10: CMD = framecrc -postfilter 0 -i $(TARGET_SAMPLES)/g723_1/cng-erasures.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

diff --git a/tests/ref/fate/g723_1-dec-10 b/tests/ref/fate/g723_1-dec-10
new file mode 100644
index 0000000000..6379f07528
--- /dev/null
+++ b/tests/ref/fate/g723_1-dec-10
@@ -0,0 +1,102 @@
+#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, 0x87aeebcc
+0,        240,        240,      240,      480, 0xbffe0499
+0,        480,        480,      240,      480, 0xe835ed9f
+0,        720,        720,      240,      480, 0x7265eb0a
+0,        960,        960,      240,      480, 0x651ce43c
+0,       1200,       1200,      240,      480, 0x1f0ae5f9
+0,       1440,       1440,      240,      480, 0x661cf0d2
+0,       1680,       1680,      240,      480, 0xfbddda7c
+0,       1920,       1920,      240,      480, 0xf852034c
+0,       2160,       2160,      240,      480, 0xa2beed3a
+0,       2400,       2400,      240,      480, 0x1d86e61a
+0,       2640,       2640,      240,      480, 0xf1a4eedd
+0,       2880,       2880,      240,      480, 0xaa8ff792
+0,       3120,       3120,      240,      480, 0xcad5f1e9
+0,       3360,       3360,      240,      480, 0xb868ee27
+0,       3600,       3600,      240,      480, 0x85f3f875
+0,       3840,       3840,      240,      480, 0x379ce9ab
+0,       4080,       4080,      240,      480, 0xea74f333
+0,       4320,       4320,      240,      480, 0xb0eceead
+0,       4560,       4560,      240,      480, 0x52c8d2fe
+0,       4800,       4800,      240,      480, 0x85a3c73e
+0,       5040,       5040,      240,      480, 0x9b96e38d
+0,       5280,       5280,      240,      480, 0x0856f042
+0,       5520,       5520,      240,      480, 0x5a02e9c7
+0,       5760,       5760,      240,      480, 0x9d10ea4c
+0,       6000,       6000,      240,      480, 0x3bcae0cb
+0,       6240,       6240,      240,      480, 0xef47e838
+0,       6480,       6480,      240,      480, 0x293cecb0
+0,       6720,       6720,      240,      480, 0x6409f2fb
+0,       6960,       6960,      240,      480, 0x9b83f342
+0,       7200,       7200,      240,      480, 0xa29ef241
+0,       7440,       7440,      240,      480, 0xdeaff0a8
+0,       7680,       7680,      240,      480, 0x5481ee53
+0,       7920,       7920,      240,      480, 0xf323eb4c
+0,       8160,       8160,      240,      480, 0x8613e597
+0,       8400,       8400,      240,      480, 0x1f8ce94b
+0,       8640,       8640,      240,      480, 0x29fddd40
+0,       8880,       8880,      240,      480, 0xeebde954
+0,       9120,       9120,      240,      480, 0xdd1de35c
+0,       9360,       9360,      240,      480, 0x1e78d8e4
+0,       9600,       9600,      240,      480, 0x7e76ee55
+0,       9840,       9840,      240,      480, 0x3d18de27
+0,      10080,      10080,      240,      480, 0x9364ca4e
+0,      10320,      10320,      240,      480, 0xcc9af167
+0,      10560,      10560,      240,      480, 0x65cfff58
+0,      10800,      10800,      240,      480, 0x051bee3a
+0,      11040,      11040,      240,      480, 0x218bdf5c
+0,      11280,      11280,      240,      480, 0x824befad
+0,      11520,      11520,      240,      480, 0x7edaf36e
+0,      11760,      11760,      240,      480, 0xa2ffe096
+0,      12000,      12000,      240,      480, 0xa0a4e1c1
+0,      12240,      12240,      240,      480, 0x391ef22f
+0,      12480,      12480,      240,      480, 0xeab5f8a2
+0,      12720,      12720,      240,      480, 0x5654378c
+0,      12960,      12960,      240,      480, 0xbd1be151
+0,      13200,      13200,      240,      480, 0xf34ddabd
+0,      13440,      13440,      240,      480, 0x8c8fee74
+0,      13680,      13680,      240,      480, 0xedca1919
+0,      13920,      13920,      240,      480, 0x86df3022
+0,      14160,      14160,      240,      480, 0xdadc0390
+0,      14400,      14400,      240,      480, 0x185df533
+0,      14640,      14640,      240,      480, 0xa92bf03d
+0,      14880,      14880,      240,      480, 0x5301f6a0
+0,      15120,      15120,      240,      480, 0x635df4d6
+0,      15360,      15360,      240,      480, 0xbc6ff11e
+0,      15600,      15600,      240,      480, 0xb4aef63a
+0,      15840,      15840,      240,      480, 0xbfdcf57e
+0,      16080,      16080,      240,      480, 0x2e0cdf25
+0,      16320,      16320,      240,      480, 0xf7f9ee90
+0,      16560,      16560,      240,      480, 0x62c6ee26
+0,      16800,      16800,      240,      480, 0x355ef5b5
+0,      17040,      17040,      240,      480, 0x9853367a
+0,      17280,      17280,      240,      480, 0xab5bd578
+0,      17520,      17520,      240,      480, 0xcd15f21b
+0,      17760,      17760,      240,      480, 0x7bf3ee2b
+0,      18000,      18000,      240,      480, 0x5ec2f0e3
+0,      18240,      18240,      240,      480, 0xfe0ff109
+0,      18480,      18480,      240,      480, 0xc701d5c4
+0,      18720,      18720,      240,      480, 0xbb3df7de
+0,      18960,      18960,      240,      480, 0x9715f71f
+0,      19200,      19200,      240,      480, 0x5bfef181
+0,      19440,      19440,      240,      480, 0xa3813b28
+0,      19680,      19680,      240,      480, 0x6b3745bc
+0,      19920,      19920,      240,      480, 0x8b44e88c
+0,      20160,      20160,      240,      480, 0xab94f540
+0,      20400,      20400,      240,      480, 0x773e0057
+0,      20640,      20640,      240,      480, 0x99b3f729
+0,      20880,      20880,      240,      480, 0x8fea1bb0
+0,      21120,      21120,      240,      480, 0x9d30f101
+0,      21360,      21360,      240,      480, 0x18e1fd48
+0,      21600,      21600,      240,      480, 0x46ecf14b
+0,      21840,      21840,      240,      480, 0xecd4f472
+0,      22080,      22080,      240,      480, 0x75bee0cc
+0,      22320,      22320,      240,      480, 0x99c5f819
+0,      22560,      22560,      240,      480, 0x929aec97
+0,      22800,      22800,      240,      480, 0x438be410
+0,      23040,      23040,      240,      480, 0x46e0ea5d
diff --git a/tests/ref/fate/g723_1-dec-9 b/tests/ref/fate/g723_1-dec-9
new file mode 100644
index 0000000000..5fd55ca8f8
--- /dev/null
+++ b/tests/ref/fate/g723_1-dec-9
@@ -0,0 +1,102 @@
+#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, 0x9960eb28
+0,        240,        240,      240,      480, 0x829b03b8
+0,        480,        480,      240,      480, 0x2ebce6c8
+0,        720,        720,      240,      480, 0xec07f417
+0,        960,        960,      240,      480, 0xebdddefa
+0,       1200,       1200,      240,      480, 0xa6d6ed37
+0,       1440,       1440,      240,      480, 0x18e0e491
+0,       1680,       1680,      240,      480, 0x91b2e0ed
+0,       1920,       1920,      240,      480, 0x5af805dc
+0,       2160,       2160,      240,      480, 0x821aefb4
+0,       2400,       2400,      240,      480, 0x646be254
+0,       2640,       2640,      240,      480, 0xec8ff4d3
+0,       2880,       2880,      240,      480, 0x1e75f923
+0,       3120,       3120,      240,      480, 0x3f58eb3d
+0,       3360,       3360,      240,      480, 0xa87af21b
+0,       3600,       3600,      240,      480, 0x3ee1ea42
+0,       3840,       3840,      240,      480, 0x6122ed84
+0,       4080,       4080,      240,      480, 0xda0aef9c
+0,       4320,       4320,      240,      480, 0x9c7ff1c6
+0,       4560,       4560,      240,      480, 0x3dcfdcae
+0,       4800,       4800,      240,      480, 0x54a7d65a
+0,       5040,       5040,      240,      480, 0xf6b8e44c
+0,       5280,       5280,      240,      480, 0x5b7cf4ad
+0,       5520,       5520,      240,      480, 0x6642e64e
+0,       5760,       5760,      240,      480, 0x473ee490
+0,       6000,       6000,      240,      480, 0xe867f091
+0,       6240,       6240,      240,      480, 0xd7dbea63
+0,       6480,       6480,      240,      480, 0x6792f0b1
+0,       6720,       6720,      240,      480, 0xb67aef82
+0,       6960,       6960,      240,      480, 0x3688fb2a
+0,       7200,       7200,      240,      480, 0x5c12e8be
+0,       7440,       7440,      240,      480, 0xe293ed4c
+0,       7680,       7680,      240,      480, 0x5108f3b7
+0,       7920,       7920,      240,      480, 0x469bd9fd
+0,       8160,       8160,      240,      480, 0xbc60e7f1
+0,       8400,       8400,      240,      480, 0x0b9de2cc
+0,       8640,       8640,      240,      480, 0xb073ec19
+0,       8880,       8880,      240,      480, 0x33f3ee20
+0,       9120,       9120,      240,      480, 0x1546e0a4
+0,       9360,       9360,      240,      480, 0xa7bdebc6
+0,       9600,       9600,      240,      480, 0xf096f4c4
+0,       9840,       9840,      240,      480, 0xf55de7b7
+0,      10080,      10080,      240,      480, 0x510bd374
+0,      10320,      10320,      240,      480, 0x159ee967
+0,      10560,      10560,      240,      480, 0x661b040d
+0,      10800,      10800,      240,      480, 0x523fe64c
+0,      11040,      11040,      240,      480, 0x10b5e79e
+0,      11280,      11280,      240,      480, 0x982eed92
+0,      11520,      11520,      240,      480, 0x5d52ef3f
+0,      11760,      11760,      240,      480, 0xe398d7a7
+0,      12000,      12000,      240,      480, 0xe759e4fc
+0,      12240,      12240,      240,      480, 0xa4a3f5b1
+0,      12480,      12480,      240,      480, 0x8702f703
+0,      12720,      12720,      240,      480, 0x991731f2
+0,      12960,      12960,      240,      480, 0x47e3e201
+0,      13200,      13200,      240,      480, 0x6dc3db07
+0,      13440,      13440,      240,      480, 0x86f6ef1c
+0,      13680,      13680,      240,      480, 0x869814c0
+0,      13920,      13920,      240,      480, 0x893721b5
+0,      14160,      14160,      240,      480, 0xa9b7039c
+0,      14400,      14400,      240,      480, 0x1b27f7c5
+0,      14640,      14640,      240,      480, 0x4f8deff4
+0,      14880,      14880,      240,      480, 0xced6f164
+0,      15120,      15120,      240,      480, 0x571af02e
+0,      15360,      15360,      240,      480, 0x7d93eebb
+0,      15600,      15600,      240,      480, 0x4659f6ac
+0,      15840,      15840,      240,      480, 0x51fbeaa6
+0,      16080,      16080,      240,      480, 0xd2a8e0f7
+0,      16320,      16320,      240,      480, 0xcfbae2e3
+0,      16560,      16560,      240,      480, 0xf908e9e0
+0,      16800,      16800,      240,      480, 0x06f2ed1b
+0,      17040,      17040,      240,      480, 0x402534b0
+0,      17280,      17280,      240,      480, 0x86c9d532
+0,      17520,      17520,      240,      480, 0xab65f21f
+0,      17760,      17760,      240,      480, 0xb543f0f5
+0,      18000,      18000,      240,      480, 0x4e44efbc
+0,      18240,      18240,      240,      480, 0xfe7aea43
+0,      18480,      18480,      240,      480, 0x675cdc8b
+0,      18720,      18720,      240,      480, 0x2536f58a
+0,      18960,      18960,      240,      480, 0x1064f6c6
+0,      19200,      19200,      240,      480, 0xd712ede5
+0,      19440,      19440,      240,      480, 0x6ba13597
+0,      19680,      19680,      240,      480, 0x29e143cf
+0,      19920,      19920,      240,      480, 0x3630da3f
+0,      20160,      20160,      240,      480, 0xbce7f531
+0,      20400,      20400,      240,      480, 0xdab9ee8e
+0,      20640,      20640,      240,      480, 0x534df31e
+0,      20880,      20880,      240,      480, 0x3153ff06
+0,      21120,      21120,      240,      480, 0x6dacf172
+0,      21360,      21360,      240,      480, 0x833405ee
+0,      21600,      21600,      240,      480, 0x92ffef77
+0,      21840,      21840,      240,      480, 0x307de935
+0,      22080,      22080,      240,      480, 0x4880e8cc
+0,      22320,      22320,      240,      480, 0x4aa0f6e9
+0,      22560,      22560,      240,      480, 0x76f2f2de
+0,      22800,      22800,      240,      480, 0xcdbdf36b
+0,      23040,      23040,      240,      480, 0x2a29eed8