PR #22723 opened by sohamukute
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22723
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22723.patch

Add API tests for three previously uncovered files (all at 0%):                 
                                                                                
                                                    
                                                                                
                                                                                
                             
- tests/api/api-cngdec-test.c: exercises cng_decode_frame via the uninited and 
inited (blending) branches, 0th-order SID, silence, max noise level, flush, and 
post-flush re-initialisation. Reaches 93.75% line coverage on cngdec.c.         
                                                                                
                                                               
                                                                                
                                                                                
                             
- tests/api/api-cngenc-test.c: exercises cng_encode_frame via the energy > 0 
path (qdbov computed from log10) and the energy == 0 silence path (qdbov = 
127). Reaches 89.47% line coverage on cngenc.c.                                 
                                                                                
                                                               
                                                                                
                                                                                
                             
- libavutil/tests/detection_bbox.c: exercises av_detection_bbox_alloc (zero 
boxes, multiple boxes, NULL out_size) and av_detection_bbox_create_side_data. 
Reaches 75% line coverage on detection_bbox.c. Remaining uncovered lines are 
allocation failure paths. 

Signed-off-by: Soham Kute [email protected]


>From 0e6452e119e1b692906680a5fae8e3c968dbcd1c Mon Sep 17 00:00:00 2001
From: Soham Kute <[email protected]>
Date: Sun, 5 Apr 2026 18:09:47 +0530
Subject: [PATCH 1/3] avcodec/tests: add CNG decoder API test

Exercise the main decode paths in cngdec.c without external samples.
The test sends hardcoded SID packets through avcodec_send_packet and
avcodec_receive_frame, covering the uninited and inited branches of
cng_decode_frame, the 0th-order and full-order coefficient paths, the
flush callback via avcodec_flush_buffers, and the re-initialisation
path after a flush.
---
 tests/api/Makefile          |   1 +
 tests/api/api-cngdec-test.c | 126 ++++++++++++++++++++++++++++++++++++
 tests/fate/api.mak          |   5 ++
 3 files changed, 132 insertions(+)
 create mode 100644 tests/api/api-cngdec-test.c

diff --git a/tests/api/Makefile b/tests/api/Makefile
index 899aeb1f54..22c2527c45 100644
--- a/tests/api/Makefile
+++ b/tests/api/Makefile
@@ -1,3 +1,4 @@
+APITESTPROGS-$(CONFIG_COMFORTNOISE_DECODER) += api-cngdec
 APITESTPROGS-$(call ENCDEC, FLAC, FLAC) += api-flac
 APITESTPROGS-$(call DEMDEC, H264, H264) += api-h264
 APITESTPROGS-$(call DEMDEC, H264, H264) += api-h264-slice
diff --git a/tests/api/api-cngdec-test.c b/tests/api/api-cngdec-test.c
new file mode 100644
index 0000000000..54e94d3258
--- /dev/null
+++ b/tests/api/api-cngdec-test.c
@@ -0,0 +1,126 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "libavcodec/avcodec.h"
+#include "libavutil/mem.h"
+
+static int send_sid(AVCodecContext *avctx, AVPacket *pkt, AVFrame *frame,
+                    const uint8_t *payload, int payload_size)
+{
+    int ret = av_new_packet(pkt, payload_size);
+    if (ret < 0)
+        return ret;
+    memcpy(pkt->data, payload, payload_size);
+    ret = avcodec_send_packet(avctx, pkt);
+    av_packet_unref(pkt);
+    if (ret < 0)
+        return ret;
+    ret = avcodec_receive_frame(avctx, frame);
+    av_frame_unref(frame);
+    return ret;
+}
+
+int main(void)
+{
+    /* SID packet: noise level + 12 reflection coefficients (order == 12) */
+    static const uint8_t sid_full[13] = {
+        20,
+        0x00, 0x10, 0x20, 0x30, 0x40, 0x50,
+        0x60, 0x70, 0x08, 0x18, 0x28, 0x38,
+    };
+    /* SID packet: noise level only, no coefficients (0th order) */
+    static const uint8_t sid_level_only[1] = { 30 };
+    /* SID packet: silence */
+    static const uint8_t sid_silence[1] = { 0 };
+    /* SID packet: max noise level */
+    static const uint8_t sid_max[1] = { 127 };
+
+    const AVCodec *codec;
+    AVCodecContext *avctx = NULL;
+    AVPacket *pkt = NULL;
+    AVFrame *frame = NULL;
+    int ret;
+
+    codec = avcodec_find_decoder(AV_CODEC_ID_COMFORT_NOISE);
+    if (!codec) {
+        fprintf(stderr, "CNG decoder not found\n");
+        return 1;
+    }
+
+    avctx = avcodec_alloc_context3(codec);
+    if (!avctx)
+        return 1;
+
+    ret = avcodec_open2(avctx, codec, NULL);
+    if (ret < 0) {
+        fprintf(stderr, "avcodec_open2 failed\n");
+        goto fail;
+    }
+
+    pkt   = av_packet_alloc();
+    frame = av_frame_alloc();
+    if (!pkt || !frame) {
+        ret = AVERROR(ENOMEM);
+        goto fail;
+    }
+
+    /* Full-order SID: exercises make_lpc_coefs and CELP synthesis.
+     * First call takes the uninited branch, copies target coefficients
+     * directly and sets the inited flag. */
+    ret = send_sid(avctx, pkt, frame, sid_full, sizeof(sid_full));
+    if (ret < 0) goto fail;
+
+    /* Second call takes the inited branch, blending energy and
+     * reflection coefficients toward the new target. */
+    ret = send_sid(avctx, pkt, frame, sid_full, sizeof(sid_full));
+    if (ret < 0) goto fail;
+
+    /* 0th-order SID: coefficient loop runs zero times, flat-spectrum path. */
+    ret = send_sid(avctx, pkt, frame, sid_level_only, sizeof(sid_level_only));
+    if (ret < 0) goto fail;
+
+    /* Silence level: target energy near zero. */
+    ret = send_sid(avctx, pkt, frame, sid_silence, sizeof(sid_silence));
+    if (ret < 0) goto fail;
+
+    /* Max noise level. */
+    ret = send_sid(avctx, pkt, frame, sid_max, sizeof(sid_max));
+    if (ret < 0) goto fail;
+
+    /* Flush resets the inited flag. */
+    avcodec_flush_buffers(avctx);
+
+    /* Packet after flush re-exercises the uninited branch. */
+    ret = send_sid(avctx, pkt, frame, sid_level_only, sizeof(sid_level_only));
+    if (ret < 0) goto fail;
+
+    av_packet_free(&pkt);
+    av_frame_free(&frame);
+    avcodec_free_context(&avctx);
+    return 0;
+
+fail:
+    fprintf(stderr, "error: %d\n", ret);
+    av_packet_free(&pkt);
+    av_frame_free(&frame);
+    avcodec_free_context(&avctx);
+    return 1;
+}
diff --git a/tests/fate/api.mak b/tests/fate/api.mak
index b760de5eb6..c20dfccf0e 100644
--- a/tests/fate/api.mak
+++ b/tests/fate/api.mak
@@ -1,3 +1,8 @@
+FATE_API_LIBAVCODEC-$(CONFIG_COMFORTNOISE_DECODER) += fate-api-cngdec
+fate-api-cngdec: $(APITESTSDIR)/api-cngdec-test$(EXESUF)
+fate-api-cngdec: CMD = run $(APITESTSDIR)/api-cngdec-test$(EXESUF)
+fate-api-cngdec: CMP = null
+
 FATE_API_LIBAVCODEC-$(call ENCDEC, FLAC, FLAC) += fate-api-flac
 fate-api-flac: $(APITESTSDIR)/api-flac-test$(EXESUF)
 fate-api-flac: CMD = run $(APITESTSDIR)/api-flac-test$(EXESUF)
-- 
2.52.0


>From 13395be17bf286312cf870c34045647e10e1ba73 Mon Sep 17 00:00:00 2001
From: Soham Kute <[email protected]>
Date: Sun, 5 Apr 2026 18:37:50 +0530
Subject: [PATCH 2/3] avcodec/tests: add CNG encoder API test

Exercise both branches of cng_encode_frame: the energy > 0 path
which computes qdbov via log10, and the energy == 0 silence path
which sets qdbov = 127.
---
 tests/api/Makefile          |   1 +
 tests/api/api-cngenc-test.c | 142 ++++++++++++++++++++++++++++++++++++
 tests/fate/api.mak          |   5 ++
 3 files changed, 148 insertions(+)
 create mode 100644 tests/api/api-cngenc-test.c

diff --git a/tests/api/Makefile b/tests/api/Makefile
index 22c2527c45..6978c980ac 100644
--- a/tests/api/Makefile
+++ b/tests/api/Makefile
@@ -1,4 +1,5 @@
 APITESTPROGS-$(CONFIG_COMFORTNOISE_DECODER) += api-cngdec
+APITESTPROGS-$(CONFIG_COMFORTNOISE_ENCODER) += api-cngenc
 APITESTPROGS-$(call ENCDEC, FLAC, FLAC) += api-flac
 APITESTPROGS-$(call DEMDEC, H264, H264) += api-h264
 APITESTPROGS-$(call DEMDEC, H264, H264) += api-h264-slice
diff --git a/tests/api/api-cngenc-test.c b/tests/api/api-cngenc-test.c
new file mode 100644
index 0000000000..e4a878da3d
--- /dev/null
+++ b/tests/api/api-cngenc-test.c
@@ -0,0 +1,142 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdio.h>
+
+#include "libavcodec/avcodec.h"
+#include "libavutil/channel_layout.h"
+#include "libavutil/mem.h"
+#include "libavutil/samplefmt.h"
+
+static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, AVFrame *frame,
+                        int16_t fill, int *got_packet)
+{
+    int ret;
+    int16_t *samples = (int16_t *)frame->data[0];
+
+    for (int i = 0; i < frame->nb_samples; i++)
+        samples[i] = fill;
+
+    ret = avcodec_send_frame(avctx, frame);
+    if (ret < 0)
+        return ret;
+    ret = avcodec_receive_packet(avctx, pkt);
+    if (ret == AVERROR(EAGAIN)) {
+        *got_packet = 0;
+        return 0;
+    }
+    if (ret < 0)
+        return ret;
+    *got_packet = 1;
+    return 0;
+}
+
+int main(void)
+{
+    const AVChannelLayout mono = AV_CHANNEL_LAYOUT_MONO;
+    const AVCodec *codec;
+    AVCodecContext *avctx = NULL;
+    AVPacket *pkt = NULL;
+    AVFrame *frame = NULL;
+    int ret, got_packet;
+
+    codec = avcodec_find_encoder(AV_CODEC_ID_COMFORT_NOISE);
+    if (!codec) {
+        fprintf(stderr, "CNG encoder not found\n");
+        return 1;
+    }
+
+    avctx = avcodec_alloc_context3(codec);
+    if (!avctx)
+        return 1;
+
+    avctx->sample_fmt     = AV_SAMPLE_FMT_S16;
+    avctx->sample_rate    = 8000;
+    ret = av_channel_layout_copy(&avctx->ch_layout, &mono);
+    if (ret < 0)
+        goto fail;
+
+    ret = avcodec_open2(avctx, codec, NULL);
+    if (ret < 0) {
+        fprintf(stderr, "avcodec_open2 failed\n");
+        goto fail;
+    }
+
+    pkt   = av_packet_alloc();
+    frame = av_frame_alloc();
+    if (!pkt || !frame) {
+        ret = AVERROR(ENOMEM);
+        goto fail;
+    }
+
+    frame->nb_samples     = avctx->frame_size;
+    frame->format         = avctx->sample_fmt;
+    ret = av_channel_layout_copy(&frame->ch_layout, &avctx->ch_layout);
+    if (ret < 0)
+        goto fail;
+
+    ret = av_frame_get_buffer(frame, 0);
+    if (ret < 0)
+        goto fail;
+
+    /* Non-zero samples: exercises the energy > 0 branch (qdbov from log). */
+    ret = encode_frame(avctx, pkt, frame, 1000, &got_packet);
+    if (ret < 0) goto fail;
+    if (!got_packet) {
+        fprintf(stderr, "expected packet, got none\n");
+        ret = AVERROR_INVALIDDATA;
+        goto fail;
+    }
+    /* Output must be 1 (noise level) + order (10) = 11 bytes. */
+    if (pkt->size != 11) {
+        fprintf(stderr, "unexpected packet size %d\n", pkt->size);
+        ret = AVERROR_INVALIDDATA;
+        av_packet_unref(pkt);
+        goto fail;
+    }
+    av_packet_unref(pkt);
+
+    /* All-zero samples: exercises the energy == 0 branch (qdbov = 127). */
+    ret = encode_frame(avctx, pkt, frame, 0, &got_packet);
+    if (ret < 0) goto fail;
+    if (!got_packet) {
+        fprintf(stderr, "expected packet, got none\n");
+        ret = AVERROR_INVALIDDATA;
+        goto fail;
+    }
+    if (pkt->size != 11 || pkt->data[0] != 127) {
+        fprintf(stderr, "unexpected silence packet (size=%d qdbov=%d)\n",
+                pkt->size, pkt->size > 0 ? pkt->data[0] : -1);
+        ret = AVERROR_INVALIDDATA;
+        av_packet_unref(pkt);
+        goto fail;
+    }
+    av_packet_unref(pkt);
+
+    av_packet_free(&pkt);
+    av_frame_free(&frame);
+    avcodec_free_context(&avctx);
+    return 0;
+
+fail:
+    fprintf(stderr, "error: %d\n", ret);
+    av_packet_free(&pkt);
+    av_frame_free(&frame);
+    avcodec_free_context(&avctx);
+    return 1;
+}
diff --git a/tests/fate/api.mak b/tests/fate/api.mak
index c20dfccf0e..a0c5133354 100644
--- a/tests/fate/api.mak
+++ b/tests/fate/api.mak
@@ -3,6 +3,11 @@ fate-api-cngdec: $(APITESTSDIR)/api-cngdec-test$(EXESUF)
 fate-api-cngdec: CMD = run $(APITESTSDIR)/api-cngdec-test$(EXESUF)
 fate-api-cngdec: CMP = null
 
+FATE_API_LIBAVCODEC-$(CONFIG_COMFORTNOISE_ENCODER) += fate-api-cngenc
+fate-api-cngenc: $(APITESTSDIR)/api-cngenc-test$(EXESUF)
+fate-api-cngenc: CMD = run $(APITESTSDIR)/api-cngenc-test$(EXESUF)
+fate-api-cngenc: CMP = null
+
 FATE_API_LIBAVCODEC-$(call ENCDEC, FLAC, FLAC) += fate-api-flac
 fate-api-flac: $(APITESTSDIR)/api-flac-test$(EXESUF)
 fate-api-flac: CMD = run $(APITESTSDIR)/api-flac-test$(EXESUF)
-- 
2.52.0


>From 3b3743d90a807125890498361bf38f909a269f21 Mon Sep 17 00:00:00 2001
From: Soham Kute <[email protected]>
Date: Sun, 5 Apr 2026 18:38:00 +0530
Subject: [PATCH 3/3] avutil/tests: add detection_bbox unit test

Cover av_detection_bbox_alloc (zero boxes, multiple boxes, NULL
out_size) and av_detection_bbox_create_side_data to bring
libavutil/detection_bbox.c from 0% coverage.
---
 libavutil/Makefile               |  1 +
 libavutil/tests/detection_bbox.c | 74 ++++++++++++++++++++++++++++++++
 tests/fate/libavutil.mak         |  5 +++
 3 files changed, 80 insertions(+)
 create mode 100644 libavutil/tests/detection_bbox.c

diff --git a/libavutil/Makefile b/libavutil/Makefile
index c5241895ff..92cc40873c 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -270,6 +270,7 @@ TESTPROGS = adler32                                         
            \
             cpu                                                         \
             crc                                                         \
             des                                                         \
+            detection_bbox                                              \
             dict                                                        \
             display                                                     \
             encryption_info                                             \
diff --git a/libavutil/tests/detection_bbox.c b/libavutil/tests/detection_bbox.c
new file mode 100644
index 0000000000..19e508451a
--- /dev/null
+++ b/libavutil/tests/detection_bbox.c
@@ -0,0 +1,74 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stddef.h>
+
+#include "libavutil/avassert.h"
+#include "libavutil/detection_bbox.h"
+#include "libavutil/frame.h"
+#include "libavutil/mem.h"
+
+int main(void)
+{
+    AVDetectionBBoxHeader *header;
+    AVDetectionBBox *bbox;
+    AVFrame *frame;
+    size_t out_size;
+
+    /* Allocate with zero bounding boxes: header fields must be consistent. */
+    header = av_detection_bbox_alloc(0, &out_size);
+    av_assert0(header);
+    av_assert0(header->nb_bboxes == 0);
+    av_assert0(header->bbox_size == sizeof(AVDetectionBBox));
+    av_assert0(out_size > 0);
+    av_free(header);
+
+    /* Allocate with several bounding boxes. */
+    header = av_detection_bbox_alloc(3, &out_size);
+    av_assert0(header);
+    av_assert0(header->nb_bboxes == 3);
+    av_assert0(header->bbox_size == sizeof(AVDetectionBBox));
+    av_assert0(out_size >= header->bboxes_offset + 3 * 
sizeof(AVDetectionBBox));
+
+    /* av_get_detection_bbox must return the expected element. */
+    bbox = av_get_detection_bbox(header, 0);
+    av_assert0(bbox == (AVDetectionBBox *)((uint8_t *)header + 
header->bboxes_offset));
+    bbox = av_get_detection_bbox(header, 2);
+    av_assert0(bbox == (AVDetectionBBox *)((uint8_t *)header + 
header->bboxes_offset +
+                                           2 * sizeof(AVDetectionBBox)));
+    av_free(header);
+
+    /* out_size may be NULL. */
+    header = av_detection_bbox_alloc(1, NULL);
+    av_assert0(header);
+    av_assert0(header->nb_bboxes == 1);
+    av_free(header);
+
+    /* Attach bounding boxes as frame side data. */
+    frame = av_frame_alloc();
+    av_assert0(frame);
+
+    header = av_detection_bbox_create_side_data(frame, 2);
+    av_assert0(header);
+    av_assert0(header->nb_bboxes == 2);
+    av_assert0(av_frame_get_side_data(frame, AV_FRAME_DATA_DETECTION_BBOXES));
+
+    av_frame_free(&frame);
+
+    return 0;
+}
diff --git a/tests/fate/libavutil.mak b/tests/fate/libavutil.mak
index 6bf03b2438..48b3106a4d 100644
--- a/tests/fate/libavutil.mak
+++ b/tests/fate/libavutil.mak
@@ -70,6 +70,11 @@ fate-des: libavutil/tests/des$(EXESUF)
 fate-des: CMD = run libavutil/tests/des$(EXESUF)
 fate-des: CMP = null
 
+FATE_LIBAVUTIL += fate-detection-bbox
+fate-detection-bbox: libavutil/tests/detection_bbox$(EXESUF)
+fate-detection-bbox: CMD = run libavutil/tests/detection_bbox$(EXESUF)
+fate-detection-bbox: CMP = null
+
 FATE_LIBAVUTIL += fate-dict
 fate-dict: libavutil/tests/dict$(EXESUF)
 fate-dict: CMD = run libavutil/tests/dict$(EXESUF)
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to