Coverage Report

Created: 2026-07-25 07:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ffmpeg/tools/target_swr_fuzzer.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2024 Michael Niedermayer <michael-ffmpeg@niedermayer.cc>
3
 *
4
 * This file is part of FFmpeg.
5
 *
6
 * FFmpeg is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2.1 of the License, or (at your option) any later version.
10
 *
11
 * FFmpeg is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with FFmpeg; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
 */
20
21
#include "config.h"
22
#include "libavutil/avassert.h"
23
#include "libavutil/avstring.h"
24
#include "libavutil/cpu.h"
25
#include "libavutil/imgutils.h"
26
#include "libavutil/intreadwrite.h"
27
#include "libavutil/mem.h"
28
#include "libavutil/opt.h"
29
30
#include "libavcodec/bytestream.h"
31
32
#include "libswresample/swresample.h"
33
34
#define SWR_CH_MAX 32
35
36
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
37
38
static const enum AVSampleFormat formats[] = {
39
    AV_SAMPLE_FMT_U8,
40
    AV_SAMPLE_FMT_U8P,
41
    AV_SAMPLE_FMT_S16,
42
    AV_SAMPLE_FMT_S16P,
43
    AV_SAMPLE_FMT_S32,
44
    AV_SAMPLE_FMT_S32P,
45
    AV_SAMPLE_FMT_FLT,
46
    AV_SAMPLE_FMT_FLTP,
47
    AV_SAMPLE_FMT_DBL,
48
    AV_SAMPLE_FMT_DBLP,
49
};
50
51
static const AVChannelLayout layouts[]={
52
    AV_CHANNEL_LAYOUT_MONO               ,
53
    AV_CHANNEL_LAYOUT_STEREO             ,
54
    AV_CHANNEL_LAYOUT_2_1                ,
55
    AV_CHANNEL_LAYOUT_SURROUND           ,
56
    AV_CHANNEL_LAYOUT_4POINT0            ,
57
    AV_CHANNEL_LAYOUT_2_2                ,
58
    AV_CHANNEL_LAYOUT_QUAD               ,
59
    AV_CHANNEL_LAYOUT_5POINT0            ,
60
    AV_CHANNEL_LAYOUT_5POINT1            ,
61
    AV_CHANNEL_LAYOUT_5POINT0_BACK       ,
62
    AV_CHANNEL_LAYOUT_5POINT1_BACK       ,
63
    AV_CHANNEL_LAYOUT_7POINT0            ,
64
    AV_CHANNEL_LAYOUT_7POINT1            ,
65
    AV_CHANNEL_LAYOUT_7POINT1_WIDE       ,
66
    AV_CHANNEL_LAYOUT_22POINT2           ,
67
    AV_CHANNEL_LAYOUT_5POINT1POINT2_BACK ,
68
};
69
70
3.71k
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
71
3.71k
    struct SwrContext * swr= NULL;
72
3.71k
    AVChannelLayout in_ch_layout = AV_CHANNEL_LAYOUT_MONO, out_ch_layout = AV_CHANNEL_LAYOUT_MONO;
73
3.71k
    enum AVSampleFormat  in_sample_fmt = AV_SAMPLE_FMT_S16P;
74
3.71k
    enum AVSampleFormat out_sample_fmt = AV_SAMPLE_FMT_S16P;
75
3.71k
    int  in_sample_rate = 44100;
76
3.71k
    int out_sample_rate = 44100;
77
3.71k
    int in_ch_count, out_ch_count;
78
3.71k
    char  in_layout_string[256];
79
3.71k
    char out_layout_string[256];
80
3.71k
    uint8_t * ain[SWR_CH_MAX];
81
3.71k
    uint8_t *aout[SWR_CH_MAX];
82
3.71k
    uint8_t *out_data = NULL;
83
3.71k
    int in_sample_nb;
84
3.71k
    int out_sample_nb = size;
85
3.71k
    int count;
86
3.71k
    int ret;
87
88
3.71k
    if (size > 128) {
89
3.69k
        GetByteContext gbc;
90
3.69k
        int64_t flags64;
91
92
3.69k
        size -= 128;
93
3.69k
        bytestream2_init(&gbc, data + size, 128);
94
3.69k
         in_sample_rate = bytestream2_get_le16(&gbc) + 1;
95
3.69k
        out_sample_rate = bytestream2_get_le16(&gbc) + 1;
96
3.69k
         in_sample_fmt  = formats[bytestream2_get_byte(&gbc) % FF_ARRAY_ELEMS(formats)];
97
3.69k
        out_sample_fmt  = formats[bytestream2_get_byte(&gbc) % FF_ARRAY_ELEMS(formats)];
98
3.69k
        av_channel_layout_copy(& in_ch_layout,  &layouts[bytestream2_get_byte(&gbc) % FF_ARRAY_ELEMS(layouts)]);
99
3.69k
        av_channel_layout_copy(&out_ch_layout,  &layouts[bytestream2_get_byte(&gbc) % FF_ARRAY_ELEMS(layouts)]);
100
101
3.69k
        out_sample_nb = bytestream2_get_le32(&gbc) & 0x7FFFFFFF;
102
103
3.69k
        flags64 = bytestream2_get_le64(&gbc);
104
3.69k
        if (flags64 & 0x10)
105
1.62k
            av_force_cpu_flags(0);
106
3.69k
    }
107
108
3.71k
     in_ch_count=  in_ch_layout.nb_channels;
109
3.71k
    out_ch_count= out_ch_layout.nb_channels;
110
3.71k
    av_channel_layout_describe(& in_ch_layout,  in_layout_string, sizeof( in_layout_string));
111
3.71k
    av_channel_layout_describe(&out_ch_layout, out_layout_string, sizeof(out_layout_string));
112
113
    // fprintf(stderr, "%s %d %s -> %s %d %s\n",
114
    //         av_get_sample_fmt_name( in_sample_fmt),  in_sample_rate,  in_layout_string,
115
    //         av_get_sample_fmt_name(out_sample_fmt), out_sample_rate, out_layout_string);
116
117
3.71k
    if (swr_alloc_set_opts2(&swr, &out_ch_layout, out_sample_fmt, out_sample_rate,
118
3.71k
                                  &in_ch_layout,   in_sample_fmt,  in_sample_rate,
119
3.71k
                                  0, 0) < 0) {
120
0
        fprintf(stderr, "Failed swr_alloc_set_opts2()\n");
121
0
        goto end;
122
0
    }
123
124
3.71k
    if (swr_init(swr) < 0) {
125
0
        fprintf(stderr, "Failed swr_init()\n");
126
0
        goto end;
127
0
    }
128
129
3.71k
     in_sample_nb = size / (in_ch_count * av_get_bytes_per_sample(in_sample_fmt));
130
3.71k
    out_sample_nb = out_sample_nb % (av_rescale(in_sample_nb, 2*out_sample_rate, in_sample_rate) + 1);
131
132
3.71k
    if (in_sample_nb > 1000*1000 || out_sample_nb > 1000*1000)
133
10
        goto end;
134
135
3.70k
    out_data = av_malloc(out_sample_nb * out_ch_count * av_get_bytes_per_sample(out_sample_fmt));
136
3.70k
    if (!out_data)
137
0
        goto end;
138
139
3.70k
    ret = av_samples_fill_arrays(ain , NULL,     data,  in_ch_count,  in_sample_nb,  in_sample_fmt, 1);
140
3.70k
    if (ret < 0)
141
148
        goto end;
142
3.56k
    ret = av_samples_fill_arrays(aout, NULL, out_data, out_ch_count, out_sample_nb, out_sample_fmt, 1);
143
3.56k
    if (ret < 0)
144
26
        goto end;
145
146
3.53k
    count = swr_convert(swr, aout, out_sample_nb, (const uint8_t **)ain, in_sample_nb);
147
148
3.71k
end:
149
3.71k
    av_freep(&out_data);
150
3.71k
    swr_free(&swr);
151
152
3.71k
    return 0;
153
3.53k
}