FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libswresample/swresample.c
Date: 2026-10-15 02:05:40
Exec Total Coverage
Lines: 485 638 76.0%
Functions: 23 24 95.8%
Branches: 375 555 67.6%

Line Branch Exec Source
1 /*
2 * Copyright (C) 2011-2013 Michael Niedermayer (michaelni@gmx.at)
3 *
4 * This file is part of libswresample
5 *
6 * libswresample 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 * libswresample 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 libswresample; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "libavutil/mem.h"
22 #include "libavutil/opt.h"
23 #include "swresample_internal.h"
24 #include "audioconvert.h"
25 #include "libavutil/avassert.h"
26 #include "libavutil/channel_layout.h"
27 #include "libavutil/internal.h"
28
29 #include <float.h>
30
31 #define ALIGN 32
32
33 14962 int swri_check_chlayout(struct SwrContext *s, const AVChannelLayout *chl, const char *name) {
34 char l1[1024];
35 int ret;
36
37
2/4
✓ Branch 1 taken 14962 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 14962 times.
14962 if (!(ret = av_channel_layout_check(chl)) || chl->nb_channels > SWR_CH_MAX) {
38 ✗ if (ret)
39 ✗ av_channel_layout_describe(chl, l1, sizeof(l1));
40 ✗ av_log(s, AV_LOG_WARNING, "%s channel layout \"%s\" is invalid or unsupported.\n", name, ret ? l1 : "");
41 ✗ return AVERROR(EINVAL);
42 }
43
44 14962 return 0;
45 }
46
47 19 int swr_set_channel_mapping(struct SwrContext *s, const int *channel_map){
48
2/4
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 19 times.
19 if(!s || s->in_convert) // s needs to be allocated but not initialized
49 ✗ return AVERROR(EINVAL);
50 19 s->channel_map = channel_map;
51 19 return 0;
52 }
53
54 3716 int swr_alloc_set_opts2(struct SwrContext **ps,
55 const AVChannelLayout *out_ch_layout, enum AVSampleFormat out_sample_fmt, int out_sample_rate,
56 const AVChannelLayout *in_ch_layout, enum AVSampleFormat in_sample_fmt, int in_sample_rate,
57 int log_offset, void *log_ctx) {
58 3716 struct SwrContext *s = *ps;
59 int ret;
60
61
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 3684 times.
3716 if (!s) s = swr_alloc();
62
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3716 times.
3716 if (!s) return AVERROR(ENOMEM);
63
64 3716 *ps = s;
65
66 3716 s->log_level_offset = log_offset;
67 3716 s->log_ctx = log_ctx;
68
69
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3716 times.
3716 if ((ret = av_opt_set_chlayout(s, "ochl", out_ch_layout, 0)) < 0)
70 ✗ goto fail;
71
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3716 times.
3716 if ((ret = swri_check_chlayout(s, out_ch_layout, "ochl")) < 0)
72 ✗ goto fail;
73
74
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3716 times.
3716 if ((ret = av_opt_set_int(s, "osf", out_sample_fmt, 0)) < 0)
75 ✗ goto fail;
76
77
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3716 times.
3716 if ((ret = av_opt_set_int(s, "osr", out_sample_rate, 0)) < 0)
78 ✗ goto fail;
79
80
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3716 times.
3716 if ((ret = av_opt_set_chlayout(s, "ichl", in_ch_layout, 0)) < 0)
81 ✗ goto fail;
82
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3716 times.
3716 if ((ret = swri_check_chlayout(s, in_ch_layout, "ichl")) < 0)
83 ✗ goto fail;
84
85
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3716 times.
3716 if ((ret = av_opt_set_int(s, "isf", in_sample_fmt, 0)) < 0)
86 ✗ goto fail;
87
88
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3716 times.
3716 if ((ret = av_opt_set_int(s, "isr", in_sample_rate, 0)) < 0)
89 ✗ goto fail;
90
91 3716 return 0;
92 ✗ fail:
93 ✗ av_log(s, AV_LOG_ERROR, "Failed to set option\n");
94 ✗ swr_free(ps);
95 ✗ return ret;
96 }
97
98 17938 static void set_audiodata_fmt(AudioData *a, enum AVSampleFormat fmt){
99 17938 a->fmt = fmt;
100 17938 a->bps = av_get_bytes_per_sample(fmt);
101 17938 a->planar= av_sample_fmt_is_planar(fmt);
102
2/2
✓ Branch 0 taken 5412 times.
✓ Branch 1 taken 12526 times.
17938 if (a->ch_count == 1)
103 5412 a->planar = 1;
104 17938 }
105
106 52072 static void free_temp(AudioData *a){
107 52072 av_free(a->data);
108 52072 memset(a, 0, sizeof(*a));
109 52072 }
110
111 6509 static void clear_context(SwrContext *s){
112 6509 s->in_buffer_index= 0;
113 6509 s->in_buffer_count= 0;
114 6509 s->resample_in_constraint= 0;
115 6509 memset(s->in.ch, 0, sizeof(s->in.ch));
116 6509 memset(s->out.ch, 0, sizeof(s->out.ch));
117 6509 free_temp(&s->postin);
118 6509 free_temp(&s->midbuf);
119 6509 free_temp(&s->preout);
120 6509 free_temp(&s->in_buffer);
121 6509 free_temp(&s->silence);
122 6509 free_temp(&s->drop_temp);
123 6509 free_temp(&s->dither.noise);
124 6509 free_temp(&s->dither.temp);
125 6509 av_channel_layout_uninit(&s->in_ch_layout);
126 6509 av_channel_layout_uninit(&s->out_ch_layout);
127 6509 av_channel_layout_uninit(&s->used_ch_layout);
128 6509 swri_audio_convert_free(&s-> in_convert);
129 6509 swri_audio_convert_free(&s->out_convert);
130 6509 swri_audio_convert_free(&s->full_convert);
131 6509 swri_rematrix_free(s);
132
133 6509 s->delayed_samples_fixup = 0;
134 6509 s->flushed = 0;
135 6509 }
136
137 2774 av_cold void swr_free(SwrContext **ss){
138 2774 SwrContext *s= *ss;
139
2/2
✓ Branch 0 taken 2736 times.
✓ Branch 1 taken 38 times.
2774 if(s){
140 2736 clear_context(s);
141 2736 av_channel_layout_uninit(&s->user_in_chlayout);
142 2736 av_channel_layout_uninit(&s->user_out_chlayout);
143 2736 av_channel_layout_uninit(&s->user_used_chlayout);
144
145
2/2
✓ Branch 0 taken 1743 times.
✓ Branch 1 taken 993 times.
2736 if (s->resampler)
146 1743 s->resampler->free(&s->resample);
147 }
148
149 2774 av_freep(ss);
150 2774 }
151
152 18 av_cold void swr_close(SwrContext *s){
153 18 clear_context(s);
154 18 }
155
156 3755 av_cold int swr_init(struct SwrContext *s){
157 int ret, mixing;
158 char l1[1024], l2[1024];
159
160 3755 clear_context(s);
161
162
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3755 times.
3755 if((unsigned) s-> in_sample_fmt >= AV_SAMPLE_FMT_NB){
163 ✗ av_log(s, AV_LOG_ERROR, "Requested input sample format %d is invalid\n", s->in_sample_fmt);
164 ✗ return AVERROR(EINVAL);
165 }
166
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3755 times.
3755 if((unsigned) s->out_sample_fmt >= AV_SAMPLE_FMT_NB){
167 ✗ av_log(s, AV_LOG_ERROR, "Requested output sample format %d is invalid\n", s->out_sample_fmt);
168 ✗ return AVERROR(EINVAL);
169 }
170
171
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3755 times.
3755 if(s-> in_sample_rate <= 0){
172 ✗ av_log(s, AV_LOG_ERROR, "Requested input sample rate %d is invalid\n", s->in_sample_rate);
173 ✗ return AVERROR(EINVAL);
174 }
175
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3755 times.
3755 if(s->out_sample_rate <= 0){
176 ✗ av_log(s, AV_LOG_ERROR, "Requested output sample rate %d is invalid\n", s->out_sample_rate);
177 ✗ return AVERROR(EINVAL);
178 }
179
180
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3755 times.
3755 if (s->out_sample_fmt == AV_SAMPLE_FMT_DSD &&
181 ✗ !(s->in_sample_fmt == AV_SAMPLE_FMT_DSD &&
182 ✗ s->in_sample_rate == s->out_sample_rate &&
183 ✗ !(s->flags & SWR_FLAG_RESAMPLE))) {
184 ✗ av_log(s, AV_LOG_ERROR, "Conversion to DSD is not supported\n");
185 ✗ return AVERROR(EINVAL);
186 }
187
188 3755 s->out.ch_count = s-> user_out_chlayout.nb_channels;
189 3755 s-> in.ch_count = s-> user_in_chlayout.nb_channels;
190
191
2/4
✓ Branch 1 taken 3755 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 3755 times.
7510 if (swri_check_chlayout(s, &s->user_in_chlayout , "input") ||
192 3755 swri_check_chlayout(s, &s->user_out_chlayout, "output"))
193 ✗ return AVERROR(EINVAL);
194
195 3755 ret = av_channel_layout_copy(&s->in_ch_layout, &s->user_in_chlayout);
196 3755 ret |= av_channel_layout_copy(&s->out_ch_layout, &s->user_out_chlayout);
197 3755 ret |= av_channel_layout_copy(&s->used_ch_layout, &s->user_used_chlayout);
198
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3755 times.
3755 if (ret < 0)
199 ✗ return ret;
200
201 3755 s->int_sample_fmt= s->user_int_sample_fmt;
202
203 3755 s->dither.method = s->user_dither_method;
204
205
1/2
✓ Branch 0 taken 3755 times.
✗ Branch 1 not taken.
3755 switch(s->engine){
206 #if CONFIG_LIBSOXR
207 case SWR_ENGINE_SOXR: s->resampler = &swri_soxr_resampler; break;
208 #endif
209 3755 case SWR_ENGINE_SWR : s->resampler = &swri_resampler; break;
210 ✗ default:
211 ✗ av_log(s, AV_LOG_ERROR, "Requested resampling engine is unavailable\n");
212 ✗ return AVERROR(EINVAL);
213 }
214
215
2/2
✓ Branch 1 taken 3736 times.
✓ Branch 2 taken 19 times.
3755 if (!av_channel_layout_check(&s->used_ch_layout))
216 3736 av_channel_layout_default(&s->used_ch_layout, s->in.ch_count);
217
218
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3746 times.
3755 if (s->used_ch_layout.nb_channels != s->in_ch_layout.nb_channels)
219 9 av_channel_layout_uninit(&s->in_ch_layout);
220
221
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3754 times.
3755 if (s->used_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC)
222 1 av_channel_layout_default(&s->used_ch_layout, s->used_ch_layout.nb_channels);
223
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 3728 times.
3755 if (s->in_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC) {
224 27 ret = av_channel_layout_copy(&s->in_ch_layout, &s->used_ch_layout);
225
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
27 if (ret < 0)
226 ✗ return ret;
227 }
228
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 3736 times.
3755 if (s->out_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC)
229 19 av_channel_layout_default(&s->out_ch_layout, s->out.ch_count);
230
231 3755 s->rematrix = av_channel_layout_compare(&s->out_ch_layout, &s->in_ch_layout) ||
232
3/4
✓ Branch 0 taken 1867 times.
✓ Branch 1 taken 1888 times.
✓ Branch 2 taken 1867 times.
✗ Branch 3 not taken.
5622 s->rematrix_volume!=1.0 ||
233
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1865 times.
1867 s->rematrix_custom;
234
235 3755 av_channel_layout_describe(&s->out_ch_layout, l2, sizeof(l2));
236 3755 av_channel_layout_describe(&s->in_ch_layout, l1, sizeof(l1));
237
2/2
✓ Branch 0 taken 3754 times.
✓ Branch 1 taken 1 times.
3755 if (( s->out_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC
238
4/6
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3753 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
3755 || s-> in_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC) && s->used_ch_layout.nb_channels != s->out.ch_count && !s->rematrix_custom) {
239 ✗ av_log(s, AV_LOG_ERROR, "Rematrix is needed between %s and %s "
240 "but there is not enough information to do it\n", l1, l2);
241 ✗ return AVERROR(EINVAL);
242 }
243
244 /* a matrix that only copies channels leaves the samples as they are,
245 * so the format in between is selected like without a matrix */
246 3755 mixing = 0;
247
2/2
✓ Branch 0 taken 1890 times.
✓ Branch 1 taken 1865 times.
3755 if (s->rematrix) {
248 1890 mixing = swri_rematrix_build(s);
249
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1890 times.
1890 if (mixing < 0)
250 ✗ return mixing;
251 }
252
253
2/2
✓ Branch 0 taken 3114 times.
✓ Branch 1 taken 641 times.
3755 if(s->int_sample_fmt == AV_SAMPLE_FMT_NONE){
254 // DSD to PCM conversion is done in floating point
255
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 3109 times.
3114 if( s->in_sample_fmt == AV_SAMPLE_FMT_DSD
256
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 && s->out_sample_fmt != AV_SAMPLE_FMT_DSD) {
257 5 s->int_sample_fmt= AV_SAMPLE_FMT_FLTP;
258 // 16bit or less to 16bit or less with the same sample rate
259
2/2
✓ Branch 1 taken 1401 times.
✓ Branch 2 taken 1708 times.
3109 } else if( av_get_bytes_per_sample(s-> in_sample_fmt) <= 2
260
2/2
✓ Branch 1 taken 803 times.
✓ Branch 2 taken 598 times.
1401 && av_get_bytes_per_sample(s->out_sample_fmt) <= 2
261
2/2
✓ Branch 0 taken 556 times.
✓ Branch 1 taken 247 times.
803 && s->out_sample_rate==s->in_sample_rate) {
262 556 s->int_sample_fmt= AV_SAMPLE_FMT_S16P;
263 // 8 -> 8, 16->8, 8->16bit
264 2553 } else if( av_get_bytes_per_sample(s-> in_sample_fmt)
265
2/2
✓ Branch 1 taken 188 times.
✓ Branch 2 taken 2365 times.
2553 +av_get_bytes_per_sample(s->out_sample_fmt) <= 3 ) {
266 188 s->int_sample_fmt= AV_SAMPLE_FMT_S16P;
267
2/2
✓ Branch 1 taken 657 times.
✓ Branch 2 taken 1708 times.
2365 }else if( av_get_bytes_per_sample(s-> in_sample_fmt) <= 2
268
2/2
✓ Branch 0 taken 346 times.
✓ Branch 1 taken 311 times.
657 && !mixing
269
2/2
✓ Branch 0 taken 122 times.
✓ Branch 1 taken 224 times.
346 && s->out_sample_rate==s->in_sample_rate
270
1/2
✓ Branch 0 taken 122 times.
✗ Branch 1 not taken.
122 && !(s->flags & SWR_FLAG_RESAMPLE)){
271 122 s->int_sample_fmt= AV_SAMPLE_FMT_S16P;
272
2/2
✓ Branch 1 taken 463 times.
✓ Branch 2 taken 1780 times.
2243 }else if( av_get_planar_sample_fmt(s-> in_sample_fmt) == AV_SAMPLE_FMT_S32P
273
2/2
✓ Branch 1 taken 113 times.
✓ Branch 2 taken 350 times.
463 && av_get_planar_sample_fmt(s->out_sample_fmt) == AV_SAMPLE_FMT_S32P
274
2/2
✓ Branch 0 taken 75 times.
✓ Branch 1 taken 38 times.
113 && !mixing
275
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 29 times.
75 && s->out_sample_rate == s->in_sample_rate
276
1/2
✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
46 && !(s->flags & SWR_FLAG_RESAMPLE)
277
1/2
✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
46 && s->engine != SWR_ENGINE_SOXR){
278 46 s->int_sample_fmt= AV_SAMPLE_FMT_S32P;
279
2/2
✓ Branch 1 taken 1668 times.
✓ Branch 2 taken 529 times.
2197 }else if(av_get_bytes_per_sample(s->in_sample_fmt) <= 4){
280 1668 s->int_sample_fmt= AV_SAMPLE_FMT_FLTP;
281 }else{
282 529 s->int_sample_fmt= AV_SAMPLE_FMT_DBLP;
283 }
284 }
285 3755 av_log(s, AV_LOG_DEBUG, "Using %s internally between filters\n", av_get_sample_fmt_name(s->int_sample_fmt));
286
287
2/2
✓ Branch 0 taken 2713 times.
✓ Branch 1 taken 1042 times.
3755 if( s->int_sample_fmt != AV_SAMPLE_FMT_S16P
288
2/2
✓ Branch 0 taken 2522 times.
✓ Branch 1 taken 191 times.
2713 &&s->int_sample_fmt != AV_SAMPLE_FMT_S32P
289
1/2
✓ Branch 0 taken 2522 times.
✗ Branch 1 not taken.
2522 &&s->int_sample_fmt != AV_SAMPLE_FMT_S64P
290
2/2
✓ Branch 0 taken 685 times.
✓ Branch 1 taken 1837 times.
2522 &&s->int_sample_fmt != AV_SAMPLE_FMT_FLTP
291
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 685 times.
685 &&s->int_sample_fmt != AV_SAMPLE_FMT_DBLP){
292 ✗ av_log(s, AV_LOG_ERROR, "Requested sample format %s is not supported internally, s16p/s32p/s64p/fltp/dblp are supported\n", av_get_sample_fmt_name(s->int_sample_fmt));
293 ✗ return AVERROR(EINVAL);
294 }
295
296 3755 set_audiodata_fmt(&s-> in, s-> in_sample_fmt);
297 3755 set_audiodata_fmt(&s->out, s->out_sample_fmt);
298
299
2/2
✓ Branch 0 taken 55 times.
✓ Branch 1 taken 3700 times.
3755 if (s->firstpts_in_samples != AV_NOPTS_VALUE) {
300
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 54 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
55 if (!s->async && s->min_compensation >= FLT_MAX/2)
301 ✗ s->async = 1;
302
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 1 times.
55 if (s->firstpts == AV_NOPTS_VALUE)
303 54 s->firstpts =
304 54 s->outpts = s->firstpts_in_samples * s->out_sample_rate;
305 } else
306 3700 s->firstpts = AV_NOPTS_VALUE;
307
308
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 3701 times.
3755 if (s->async) {
309
2/2
✓ Branch 0 taken 53 times.
✓ Branch 1 taken 1 times.
54 if (s->min_compensation >= FLT_MAX/2)
310 53 s->min_compensation = 0.001;
311
1/2
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
54 if (s->async > 1.0001) {
312 54 s->max_soft_compensation = s->async / (double) s->in_sample_rate;
313 }
314 }
315
316
4/4
✓ Branch 0 taken 1422 times.
✓ Branch 1 taken 2333 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1421 times.
3755 if (s->out_sample_rate!=s->in_sample_rate || (s->flags & SWR_FLAG_RESAMPLE)){
317 2334 s->resample = s->resampler->init(s->resample, s->out_sample_rate, s->in_sample_rate, s->filter_size, s->phase_shift, s->linear_interp, s->cutoff, s->int_sample_fmt, s->filter_type, s->kaiser_beta, s->precision, s->cheby, s->exact_rational);
318
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2334 times.
2334 if (!s->resample) {
319 ✗ av_log(s, AV_LOG_ERROR, "Failed to initialize resampler\n");
320 ✗ return AVERROR(ENOMEM);
321 }
322 }else
323 1421 s->resampler->free(&s->resample);
324
2/2
✓ Branch 0 taken 2713 times.
✓ Branch 1 taken 1042 times.
3755 if( s->int_sample_fmt != AV_SAMPLE_FMT_S16P
325
2/2
✓ Branch 0 taken 2522 times.
✓ Branch 1 taken 191 times.
2713 && s->int_sample_fmt != AV_SAMPLE_FMT_S32P
326
2/2
✓ Branch 0 taken 685 times.
✓ Branch 1 taken 1837 times.
2522 && s->int_sample_fmt != AV_SAMPLE_FMT_FLTP
327
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 685 times.
685 && s->int_sample_fmt != AV_SAMPLE_FMT_DBLP
328 ✗ && s->resample){
329 ✗ av_log(s, AV_LOG_ERROR, "Resampling only supported with internal s16p/s32p/fltp/dblp\n");
330 ✗ ret = AVERROR(EINVAL);
331 ✗ goto fail;
332 }
333
334 #define RSC 1 //FIXME finetune
335
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3755 times.
3755 if(!s-> in.ch_count)
336 ✗ s-> in.ch_count = s->in_ch_layout.nb_channels;
337
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3755 times.
3755 if (!av_channel_layout_check(&s->used_ch_layout))
338 ✗ av_channel_layout_default(&s->used_ch_layout, s->in.ch_count);
339
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3755 times.
3755 if(!s->out.ch_count)
340 ✗ s->out.ch_count = s->out_ch_layout.nb_channels;
341
342
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3755 times.
3755 if(!s-> in.ch_count){
343 ✗ av_assert0(s->in_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC);
344 ✗ av_log(s, AV_LOG_ERROR, "Input channel count and layout are unset\n");
345 ✗ ret = AVERROR(EINVAL);
346 ✗ goto fail;
347 }
348
349
3/4
✓ Branch 0 taken 3754 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3754 times.
3755 if (s->in_ch_layout.order != AV_CHANNEL_ORDER_UNSPEC && s->used_ch_layout.nb_channels != s->in_ch_layout.nb_channels) {
350 ✗ av_log(s, AV_LOG_ERROR, "Input channel layout %s mismatches specified channel count %d\n", l1, s->used_ch_layout.nb_channels);
351 ✗ ret = AVERROR(EINVAL);
352 ✗ goto fail;
353 }
354
355
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3755 times.
3755 av_assert0(s->used_ch_layout.nb_channels);
356
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3755 times.
3755 av_assert0(s->out.ch_count);
357 3755 s->resample_first= RSC*s->out.ch_count/s->used_ch_layout.nb_channels - RSC < s->out_sample_rate/(float)s-> in_sample_rate - 1.0;
358
359 3755 s->in_buffer= s->in;
360 3755 s->silence = s->in;
361 3755 s->drop_temp= s->out;
362
363
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3755 times.
3755 if ((ret = swri_dither_init(s, s->out_sample_fmt, s->int_sample_fmt)) < 0)
364 ✗ goto fail;
365
366
7/8
✓ Branch 0 taken 1421 times.
✓ Branch 1 taken 2334 times.
✓ Branch 2 taken 1069 times.
✓ Branch 3 taken 352 times.
✓ Branch 4 taken 1058 times.
✓ Branch 5 taken 11 times.
✓ Branch 6 taken 1058 times.
✗ Branch 7 not taken.
3755 if(!s->resample && !s->rematrix && !s->channel_map && !s->dither.method){
367 1058 s->full_convert = swri_audio_convert_alloc(s->out_sample_fmt,
368 s-> in_sample_fmt, s-> in.ch_count, NULL, 0);
369 // fall through to the generic path for conversions that have no
370 // direct implementation (e.g. DSD input to non-float output)
371
2/2
✓ Branch 0 taken 1057 times.
✓ Branch 1 taken 1 times.
1058 if (s->full_convert)
372 1057 return 0;
373 }
374
375 2698 s->in_convert = swri_audio_convert_alloc(s->int_sample_fmt,
376 s-> in_sample_fmt, s->used_ch_layout.nb_channels, s->channel_map, 0);
377 2698 s->out_convert= swri_audio_convert_alloc(s->out_sample_fmt,
378 s->int_sample_fmt, s->out.ch_count, NULL, 0);
379
380
2/4
✓ Branch 0 taken 2698 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2698 times.
2698 if (!s->in_convert || !s->out_convert) {
381 ✗ av_log(s, AV_LOG_ERROR, "Cannot convert %s sample format to %s sample format\n",
382 ✗ av_get_sample_fmt_name(!s->in_convert ? s->in_sample_fmt : s->int_sample_fmt),
383 ✗ av_get_sample_fmt_name(!s->in_convert ? s->int_sample_fmt : s->out_sample_fmt));
384 ✗ ret = AVERROR(EINVAL);
385 ✗ goto fail;
386 }
387
388 2698 s->postin= s->in;
389 2698 s->preout= s->out;
390 2698 s->midbuf= s->in;
391
392
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 2679 times.
2698 if(s->channel_map){
393 19 s->postin.ch_count=
394 19 s->midbuf.ch_count= s->used_ch_layout.nb_channels;
395
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
19 if(s->resample)
396 ✗ s->in_buffer.ch_count= s->used_ch_layout.nb_channels;
397 }
398
2/2
✓ Branch 0 taken 1160 times.
✓ Branch 1 taken 1538 times.
2698 if(!s->resample_first){
399 1160 s->midbuf.ch_count= s->out.ch_count;
400
2/2
✓ Branch 0 taken 957 times.
✓ Branch 1 taken 203 times.
1160 if(s->resample)
401 957 s->in_buffer.ch_count = s->out.ch_count;
402 }
403
404 2698 set_audiodata_fmt(&s->postin, s->int_sample_fmt);
405 2698 set_audiodata_fmt(&s->midbuf, s->int_sample_fmt);
406 2698 set_audiodata_fmt(&s->preout, s->int_sample_fmt);
407
408
2/2
✓ Branch 0 taken 2334 times.
✓ Branch 1 taken 364 times.
2698 if(s->resample){
409 2334 set_audiodata_fmt(&s->in_buffer, s->int_sample_fmt);
410 }
411
412
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2698 times.
2698 av_assert0(!s->preout.count);
413 2698 s->dither.noise = s->preout;
414 2698 s->dither.temp = s->preout;
415
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2698 times.
2698 if (s->dither.method > SWR_DITHER_NS) {
416 ✗ s->dither.noise.bps = 4;
417 ✗ s->dither.noise.fmt = AV_SAMPLE_FMT_FLTP;
418 ✗ s->dither.noise_scale = 1;
419 }
420
421
3/4
✓ Branch 0 taken 808 times.
✓ Branch 1 taken 1890 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 808 times.
2698 if(s->rematrix || s->dither.method) {
422 1890 ret = swri_rematrix_init(s);
423
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1890 times.
1890 if (ret < 0)
424 ✗ goto fail;
425 }
426
427 2698 return 0;
428 ✗ fail:
429 ✗ swr_close(s);
430 ✗ return ret;
431
432 }
433
434 123094 int swri_realloc_audio(AudioData *a, int count){
435 int i, countb;
436 AudioData old;
437
438
2/4
✓ Branch 0 taken 123094 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 123094 times.
123094 if(count < 0 || count > INT_MAX/2/a->bps/a->ch_count)
439 ✗ return AVERROR(EINVAL);
440
441
2/2
✓ Branch 0 taken 110231 times.
✓ Branch 1 taken 12863 times.
123094 if(a->count >= count)
442 110231 return 0;
443
444 12863 count*=2;
445
446 12863 countb= FFALIGN(count*a->bps, ALIGN);
447 12863 old= *a;
448
449
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12863 times.
12863 av_assert0(a->bps);
450
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12863 times.
12863 av_assert0(a->ch_count);
451
452 12863 a->data = av_calloc(countb, a->ch_count);
453
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12863 times.
12863 if(!a->data)
454 ✗ return AVERROR(ENOMEM);
455
2/2
✓ Branch 0 taken 50537 times.
✓ Branch 1 taken 12863 times.
63400 for(i=0; i<a->ch_count; i++){
456
2/2
✓ Branch 0 taken 372 times.
✓ Branch 1 taken 50165 times.
50537 a->ch[i]= a->data + i*(a->planar ? countb : a->bps);
457
4/4
✓ Branch 0 taken 7112 times.
✓ Branch 1 taken 43425 times.
✓ Branch 2 taken 6993 times.
✓ Branch 3 taken 119 times.
50537 if(a->count && a->planar) memcpy(a->ch[i], old.ch[i], a->count*a->bps);
458 }
459
4/4
✓ Branch 0 taken 2257 times.
✓ Branch 1 taken 10606 times.
✓ Branch 2 taken 23 times.
✓ Branch 3 taken 2234 times.
12863 if(a->count && !a->planar) memcpy(a->ch[0], old.ch[0], a->count*a->ch_count*a->bps);
460 12863 av_freep(&old.data);
461 12863 a->count= count;
462
463 12863 return 1;
464 }
465
466 37783 static void copy(AudioData *out, AudioData *in,
467 int count){
468
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37783 times.
37783 av_assert0(out->planar == in->planar);
469
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37783 times.
37783 av_assert0(out->bps == in->bps);
470
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37783 times.
37783 av_assert0(out->ch_count == in->ch_count);
471
2/2
✓ Branch 0 taken 37709 times.
✓ Branch 1 taken 74 times.
37783 if(out->planar){
472 int ch;
473
2/2
✓ Branch 0 taken 66561 times.
✓ Branch 1 taken 37709 times.
104270 for(ch=0; ch<out->ch_count; ch++)
474 66561 memcpy(out->ch[ch], in->ch[ch], count*out->bps);
475 }else
476 74 memcpy(out->ch[0], in->ch[0], count*out->ch_count*out->bps);
477 37783 }
478
479 577254 static void fill_audiodata(AudioData *out, uint8_t *const in_arg [SWR_CH_MAX])
480 {
481 int i;
482
2/2
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 577184 times.
577254 if(!in_arg){
483 70 memset(out->ch, 0, sizeof(out->ch));
484
2/2
✓ Branch 0 taken 417591 times.
✓ Branch 1 taken 159593 times.
577184 }else if(out->planar){
485
2/2
✓ Branch 0 taken 648714 times.
✓ Branch 1 taken 417591 times.
1066305 for(i=0; i<out->ch_count; i++)
486 648714 out->ch[i]= in_arg[i];
487 }else{
488
2/2
✓ Branch 0 taken 386242 times.
✓ Branch 1 taken 159593 times.
545835 for(i=0; i<out->ch_count; i++)
489 386242 out->ch[i]= in_arg[0] + i*out->bps;
490 }
491 577254 }
492
493 137 static void reversefill_audiodata(AudioData *out, uint8_t *in_arg [SWR_CH_MAX]){
494 int i;
495
1/2
✓ Branch 0 taken 137 times.
✗ Branch 1 not taken.
137 if(out->planar){
496
2/2
✓ Branch 0 taken 137 times.
✓ Branch 1 taken 137 times.
274 for(i=0; i<out->ch_count; i++)
497 137 in_arg[i]= out->ch[i];
498 }else{
499 ✗ in_arg[0]= out->ch[0];
500 }
501 137 }
502
503 /**
504 *
505 * out may be equal in.
506 */
507 507013 static void buf_set(AudioData *out, AudioData *in, int count){
508 int ch;
509
2/2
✓ Branch 0 taken 494891 times.
✓ Branch 1 taken 12122 times.
507013 if(in->planar){
510
2/2
✓ Branch 0 taken 904085 times.
✓ Branch 1 taken 494891 times.
1398976 for(ch=0; ch<out->ch_count; ch++)
511 904085 out->ch[ch]= in->ch[ch] + count*out->bps;
512 }else{
513
2/2
✓ Branch 0 taken 32404 times.
✓ Branch 1 taken 12122 times.
44526 for(ch=out->ch_count-1; ch>=0; ch--)
514 32404 out->ch[ch]= in->ch[0] + (ch + count*out->ch_count) * out->bps;
515 }
516 507013 }
517
518 /**
519 *
520 * @return number of samples output per channel
521 */
522 24470 static int resample(SwrContext *s, AudioData *out_param, int out_count,
523 const AudioData * in_param, int in_count){
524 AudioData in, out, tmp;
525 24470 int ret_sum=0;
526 24470 int border=0;
527
1/2
✓ Branch 0 taken 24470 times.
✗ Branch 1 not taken.
24470 int padless = ARCH_X86 && s->engine == SWR_ENGINE_SWR ? 7 : 0;
528
529 av_assert1(s->in_buffer.ch_count == in_param->ch_count);
530 av_assert1(s->in_buffer.planar == in_param->planar);
531 av_assert1(s->in_buffer.fmt == in_param->fmt);
532
533 24470 tmp=out=*out_param;
534 24470 in = *in_param;
535
536 24470 border = s->resampler->invert_initial_buffer(s->resample, &s->in_buffer,
537 &in, in_count, &s->in_buffer_index, &s->in_buffer_count);
538
2/2
✓ Branch 0 taken 863 times.
✓ Branch 1 taken 23607 times.
24470 if (border == INT_MAX) {
539 863 return 0;
540
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23607 times.
23607 } else if (border < 0) {
541 ✗ return border;
542
2/2
✓ Branch 0 taken 2332 times.
✓ Branch 1 taken 21275 times.
23607 } else if (border) {
543 2332 buf_set(&in, &in, border);
544 2332 in_count -= border;
545 2332 s->resample_in_constraint = 0;
546 }
547
548 37566 do{
549 int ret, size, consumed;
550
4/4
✓ Branch 0 taken 52949 times.
✓ Branch 1 taken 8224 times.
✓ Branch 2 taken 52943 times.
✓ Branch 3 taken 6 times.
61173 if(!s->resample_in_constraint && s->in_buffer_count){
551 52943 buf_set(&tmp, &s->in_buffer, s->in_buffer_index);
552 52943 ret= s->resampler->multiple_resample(s->resample, &out, out_count, &tmp, s->in_buffer_count, &consumed);
553 52943 out_count -= ret;
554 52943 ret_sum += ret;
555 52943 buf_set(&out, &out, ret);
556 52943 s->in_buffer_count -= consumed;
557 52943 s->in_buffer_index += consumed;
558
559
2/2
✓ Branch 0 taken 23602 times.
✓ Branch 1 taken 29341 times.
52943 if(!in_count)
560 23602 break;
561
2/2
✓ Branch 0 taken 19192 times.
✓ Branch 1 taken 10149 times.
29341 if(s->in_buffer_count <= border){
562 19192 buf_set(&in, &in, -s->in_buffer_count);
563 19192 in_count += s->in_buffer_count;
564 19192 s->in_buffer_count=0;
565 19192 s->in_buffer_index=0;
566 19192 border = 0;
567 }
568 }
569
570
6/6
✓ Branch 0 taken 37567 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 37566 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 19236 times.
✓ Branch 5 taken 18334 times.
37571 if((s->flushed || in_count > padless) && !s->in_buffer_count){
571 19236 s->in_buffer_index=0;
572 19236 ret= s->resampler->multiple_resample(s->resample, &out, out_count, &in, FFMAX(in_count-padless, 0), &consumed);
573 19236 out_count -= ret;
574 19236 ret_sum += ret;
575 19236 buf_set(&out, &out, ret);
576 19236 in_count -= consumed;
577 19236 buf_set(&in, &in, consumed);
578 }
579
580 //TODO is this check sane considering the advanced copy avoidance below
581 37571 size= s->in_buffer_index + s->in_buffer_count + in_count;
582
2/2
✓ Branch 0 taken 1221 times.
✓ Branch 1 taken 36350 times.
37571 if( size > s->in_buffer.count
583
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1221 times.
1221 && s->in_buffer_count + in_count <= s->in_buffer_index){
584 ✗ buf_set(&tmp, &s->in_buffer, s->in_buffer_index);
585 ✗ copy(&s->in_buffer, &tmp, s->in_buffer_count);
586 ✗ s->in_buffer_index=0;
587 }else
588
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 37571 times.
37571 if((ret=swri_realloc_audio(&s->in_buffer, size)) < 0)
589 ✗ return ret;
590
591
2/2
✓ Branch 0 taken 37566 times.
✓ Branch 1 taken 5 times.
37571 if(in_count){
592 37566 int count= in_count;
593
6/6
✓ Branch 0 taken 18334 times.
✓ Branch 1 taken 19232 times.
✓ Branch 2 taken 18023 times.
✓ Branch 3 taken 311 times.
✓ Branch 4 taken 17481 times.
✓ Branch 5 taken 542 times.
37566 if(s->in_buffer_count && s->in_buffer_count+2 < count && out_count) count= s->in_buffer_count+2;
594
595 37566 buf_set(&tmp, &s->in_buffer, s->in_buffer_index + s->in_buffer_count);
596 37566 copy(&tmp, &in, /*in_*/count);
597 37566 s->in_buffer_count += count;
598 37566 in_count -= count;
599 37566 border += count;
600 37566 buf_set(&in, &in, count);
601 37566 s->resample_in_constraint= 0;
602
3/4
✓ Branch 0 taken 19232 times.
✓ Branch 1 taken 18334 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 19232 times.
37566 if(s->in_buffer_count != count || in_count)
603 37566 continue;
604
1/2
✓ Branch 0 taken 19232 times.
✗ Branch 1 not taken.
19232 if (padless) {
605 19232 padless = 0;
606 19232 continue;
607 }
608 }
609 5 break;
610 }while(1);
611
612 23607 s->resample_in_constraint= !!out_count;
613
614 23607 return ret_sum;
615 }
616
617 289945 static int swr_convert_internal(struct SwrContext *s, AudioData *out, int out_count,
618 AudioData *in , int in_count){
619 AudioData *postin, *midbuf, *preout;
620 int ret/*, in_max*/;
621 AudioData preout_tmp, midbuf_tmp;
622
623
2/2
✓ Branch 0 taken 263115 times.
✓ Branch 1 taken 26830 times.
289945 if(s->full_convert){
624
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 263115 times.
263115 av_assert0(!s->resample);
625 263115 swri_audio_convert(s->full_convert, out, in, in_count);
626 263115 return out_count;
627 }
628
629 // in_max= out_count*(int64_t)s->in_sample_rate / s->out_sample_rate + resample_filter_taps;
630 // in_count= FFMIN(in_count, in_in + 2 - s->hist_buffer_count);
631
632
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 26830 times.
26830 if((ret=swri_realloc_audio(&s->postin, in_count))<0)
633 ✗ return ret;
634
2/2
✓ Branch 0 taken 17912 times.
✓ Branch 1 taken 8918 times.
26830 if(s->resample_first){
635
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17912 times.
17912 av_assert0(s->midbuf.ch_count == s->used_ch_layout.nb_channels);
636
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 17912 times.
17912 if((ret=swri_realloc_audio(&s->midbuf, out_count))<0)
637 ✗ return ret;
638 }else{
639
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8918 times.
8918 av_assert0(s->midbuf.ch_count == s->out.ch_count);
640
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8918 times.
8918 if((ret=swri_realloc_audio(&s->midbuf, in_count))<0)
641 ✗ return ret;
642 }
643
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 26830 times.
26830 if((ret=swri_realloc_audio(&s->preout, out_count))<0)
644 ✗ return ret;
645
646 26830 postin= &s->postin;
647
648 26830 midbuf_tmp= s->midbuf;
649 26830 midbuf= &midbuf_tmp;
650 26830 preout_tmp= s->preout;
651 26830 preout= &preout_tmp;
652
653
5/6
✓ Branch 0 taken 16594 times.
✓ Branch 1 taken 10236 times.
✓ Branch 2 taken 16594 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 16378 times.
✓ Branch 5 taken 216 times.
26830 if(s->int_sample_fmt == s-> in_sample_fmt && s->in.planar && !s->channel_map)
654 16378 postin= in;
655
656
4/4
✓ Branch 0 taken 17912 times.
✓ Branch 1 taken 8918 times.
✓ Branch 2 taken 6765 times.
✓ Branch 3 taken 20065 times.
26830 if(s->resample_first ? !s->resample : !s->rematrix)
657 6765 midbuf= postin;
658
659
4/4
✓ Branch 0 taken 17912 times.
✓ Branch 1 taken 8918 times.
✓ Branch 2 taken 16455 times.
✓ Branch 3 taken 10375 times.
26830 if(s->resample_first ? !s->rematrix : !s->resample)
660 16455 preout= midbuf;
661
662
3/4
✓ Branch 0 taken 14924 times.
✓ Branch 1 taken 11906 times.
✓ Branch 2 taken 14924 times.
✗ Branch 3 not taken.
26830 if(s->int_sample_fmt == s->out_sample_fmt && s->out.planar
663
3/4
✓ Branch 0 taken 1045 times.
✓ Branch 1 taken 13879 times.
✓ Branch 2 taken 1045 times.
✗ Branch 3 not taken.
14924 && !(s->out_sample_fmt==AV_SAMPLE_FMT_S32P && (s->dither.output_sample_bits&31))){
664
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14924 times.
14924 if(preout==in){
665 ✗ out_count= FFMIN(out_count, in_count); //TODO check at the end if this is needed or redundant
666 ✗ av_assert0(s->in.planar); //we only support planar internally so it has to be, we support copying non planar though
667 ✗ copy(out, in, out_count);
668 ✗ return out_count;
669 }
670
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 14708 times.
14924 else if(preout==postin) preout= midbuf= postin= out;
671
2/2
✓ Branch 0 taken 13098 times.
✓ Branch 1 taken 1610 times.
14708 else if(preout==midbuf) preout= midbuf= out;
672 1610 else preout= out;
673 }
674
675
2/2
✓ Branch 0 taken 10452 times.
✓ Branch 1 taken 16378 times.
26830 if(in != postin){
676 10452 swri_audio_convert(s->in_convert, postin, in, in_count);
677 }
678
679
2/2
✓ Branch 0 taken 17912 times.
✓ Branch 1 taken 8918 times.
26830 if(s->resample_first){
680
2/2
✓ Branch 0 taken 17374 times.
✓ Branch 1 taken 538 times.
17912 if(postin != midbuf)
681
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 17374 times.
17374 if ((out_count = resample(s, midbuf, out_count, postin, in_count)) < 0)
682 ✗ return out_count;
683
4/4
✓ Branch 0 taken 3279 times.
✓ Branch 1 taken 14633 times.
✓ Branch 2 taken 2562 times.
✓ Branch 3 taken 717 times.
17912 if(midbuf != preout && out_count)
684 2562 swri_rematrix(s, preout, midbuf, out_count, preout==out);
685 }else{
686
4/4
✓ Branch 0 taken 2691 times.
✓ Branch 1 taken 6227 times.
✓ Branch 2 taken 1803 times.
✓ Branch 3 taken 888 times.
8918 if(postin != midbuf && in_count)
687 1803 swri_rematrix(s, midbuf, postin, in_count, midbuf==out);
688
2/2
✓ Branch 0 taken 7096 times.
✓ Branch 1 taken 1822 times.
8918 if(midbuf != preout)
689
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7096 times.
7096 if ((out_count = resample(s, preout, out_count, midbuf, in_count)) < 0)
690 ✗ return out_count;
691 }
692
693
4/4
✓ Branch 0 taken 11906 times.
✓ Branch 1 taken 14924 times.
✓ Branch 2 taken 10544 times.
✓ Branch 3 taken 1362 times.
26830 if(preout != out && out_count){
694 10544 AudioData *conv_src = preout;
695
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10544 times.
10544 if(s->dither.method){
696 int ch;
697 ✗ int dither_count= FFMAX(out_count, 1<<16);
698
699 ✗ if (preout == in) {
700 ✗ conv_src = &s->dither.temp;
701 ✗ if((ret=swri_realloc_audio(&s->dither.temp, dither_count))<0)
702 ✗ return ret;
703 }
704
705 ✗ if((ret=swri_realloc_audio(&s->dither.noise, dither_count))<0)
706 ✗ return ret;
707 ✗ if(ret)
708 ✗ for(ch=0; ch<s->dither.noise.ch_count; ch++)
709 ✗ if((ret=swri_get_dither(s, s->dither.noise.ch[ch], s->dither.noise.count, (12345678913579ULL*ch + 3141592) % 2718281828U, s->dither.noise.fmt))<0)
710 ✗ return ret;
711 ✗ av_assert0(s->dither.noise.ch_count == preout->ch_count);
712
713 ✗ if(s->dither.noise_pos + out_count > s->dither.noise.count)
714 ✗ s->dither.noise_pos = 0;
715
716 ✗ if (s->dither.method < SWR_DITHER_NS){
717 ✗ if (s->mix_2_1_simd) {
718 ✗ int len1= out_count&~15;
719 ✗ int off = len1 * preout->bps;
720
721 ✗ if(len1)
722 ✗ for(ch=0; ch<preout->ch_count; ch++)
723 ✗ s->mix_2_1_simd(conv_src->ch[ch], preout->ch[ch], s->dither.noise.ch[ch] + s->dither.noise.bps * s->dither.noise_pos, &s->native_simd_one, 0, 0, len1);
724 ✗ if(out_count != len1)
725 ✗ for(ch=0; ch<preout->ch_count; ch++)
726 ✗ s->mix_2_1_f(conv_src->ch[ch] + off, preout->ch[ch] + off, s->dither.noise.ch[ch] + s->dither.noise.bps * s->dither.noise_pos + off, &s->native_one, 0, 0, out_count - len1);
727 } else {
728 ✗ for(ch=0; ch<preout->ch_count; ch++)
729 ✗ s->mix_2_1_f(conv_src->ch[ch], preout->ch[ch], s->dither.noise.ch[ch] + s->dither.noise.bps * s->dither.noise_pos, &s->native_one, 0, 0, out_count);
730 }
731 } else {
732 ✗ switch(s->int_sample_fmt) {
733 ✗ case AV_SAMPLE_FMT_S16P :swri_noise_shaping_int16(s, conv_src, preout, &s->dither.noise, out_count); break;
734 ✗ case AV_SAMPLE_FMT_S32P :swri_noise_shaping_int32(s, conv_src, preout, &s->dither.noise, out_count); break;
735 ✗ case AV_SAMPLE_FMT_FLTP :swri_noise_shaping_float(s, conv_src, preout, &s->dither.noise, out_count); break;
736 ✗ case AV_SAMPLE_FMT_DBLP :swri_noise_shaping_double(s,conv_src, preout, &s->dither.noise, out_count); break;
737 }
738 }
739 ✗ s->dither.noise_pos += out_count;
740 }
741 //FIXME packed doesn't need more than 1 chan here!
742 10544 swri_audio_convert(s->out_convert, out, conv_src, out_count);
743 }
744 26830 return out_count;
745 }
746
747 327455 int swr_is_initialized(struct SwrContext *s) {
748 327455 return !!s->in_buffer.ch_count;
749 }
750
751 291314 int attribute_align_arg swr_convert(struct SwrContext *s,
752 uint8_t * const *out_arg, int out_count,
753 const uint8_t * const *in_arg, int in_count)
754 {
755 291314 AudioData * in= &s->in;
756 291314 AudioData *out= &s->out;
757
758
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 291314 times.
291314 if (!swr_is_initialized(s)) {
759 ✗ av_log(s, AV_LOG_ERROR, "Context has not been initialized\n");
760 ✗ return AVERROR(EINVAL);
761 }
762 #if defined(ASSERT_LEVEL) && ASSERT_LEVEL >1
763 int max_output = swr_get_out_samples(s, in_count);
764 #endif
765
766
2/2
✓ Branch 0 taken 104 times.
✓ Branch 1 taken 291262 times.
291366 while(s->drop_output > 0){
767 int ret;
768 uint8_t *tmp_arg[SWR_CH_MAX];
769 #define MAX_DROP_STEP 16384
770
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 104 times.
104 if((ret=swri_realloc_audio(&s->drop_temp, FFMIN(s->drop_output, MAX_DROP_STEP)))<0)
771 52 return ret;
772
773 104 reversefill_audiodata(&s->drop_temp, tmp_arg);
774 104 s->drop_output *= -1; //FIXME find a less hackish solution
775
1/2
✓ Branch 0 taken 104 times.
✗ Branch 1 not taken.
104 ret = swr_convert(s, tmp_arg, FFMIN(-s->drop_output, MAX_DROP_STEP), in_arg, in_count); //FIXME optimize but this is as good as never called so maybe it doesn't matter
776 104 s->drop_output *= -1;
777 104 in_count = 0;
778
2/2
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 52 times.
104 if(ret>0) {
779 52 s->drop_output -= ret;
780
2/4
✓ Branch 0 taken 52 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 52 times.
52 if (!s->drop_output && !out_arg)
781 ✗ return 0;
782 52 continue;
783 }
784
785
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52 times.
52 av_assert0(s->drop_output);
786 52 return 0;
787 }
788
789
2/2
✓ Branch 0 taken 4108 times.
✓ Branch 1 taken 287154 times.
291262 if(!in_arg){
790
2/2
✓ Branch 0 taken 2946 times.
✓ Branch 1 taken 1162 times.
4108 if(s->resample){
791
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 1462 times.
2946 if (!s->flushed)
792 1484 s->resampler->flush(s);
793 2946 s->resample_in_constraint = 0;
794 2946 s->flushed = 1;
795
1/2
✓ Branch 0 taken 1162 times.
✗ Branch 1 not taken.
1162 }else if(!s->in_buffer_count){
796 1162 return 0;
797 }
798 }else
799 287154 fill_audiodata(in , (void*)in_arg);
800
801 290100 fill_audiodata(out, out_arg);
802
803
2/2
✓ Branch 0 taken 24470 times.
✓ Branch 1 taken 265630 times.
290100 if(s->resample){
804 24470 int ret = swr_convert_internal(s, out, out_count, in, in_count);
805
4/4
✓ Branch 0 taken 22541 times.
✓ Branch 1 taken 1929 times.
✓ Branch 2 taken 22489 times.
✓ Branch 3 taken 52 times.
24470 if(ret>0 && !s->drop_output)
806 22489 s->outpts += ret * (int64_t)s->in_sample_rate;
807
808 av_assert2(max_output < 0 || ret <= max_output);
809
810 24470 return ret;
811 }else{
812 265630 AudioData tmp= *in;
813 265630 int ret2=0;
814 int ret, size;
815 265630 size = FFMIN(out_count, s->in_buffer_count);
816
2/2
✓ Branch 0 taken 307 times.
✓ Branch 1 taken 265323 times.
265630 if(size){
817 307 buf_set(&tmp, &s->in_buffer, s->in_buffer_index);
818 307 ret= swr_convert_internal(s, out, size, &tmp, size);
819
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 307 times.
307 if(ret<0)
820 ✗ return ret;
821 307 ret2= ret;
822 307 s->in_buffer_count -= ret;
823 307 s->in_buffer_index += ret;
824 307 buf_set(out, out, ret);
825 307 out_count -= ret;
826
2/2
✓ Branch 0 taken 186 times.
✓ Branch 1 taken 121 times.
307 if(!s->in_buffer_count)
827 186 s->in_buffer_index = 0;
828 }
829
830
2/2
✓ Branch 0 taken 265323 times.
✓ Branch 1 taken 307 times.
265630 if(in_count){
831 265323 size= s->in_buffer_index + s->in_buffer_count + in_count - out_count;
832
833
2/2
✓ Branch 0 taken 217 times.
✓ Branch 1 taken 265106 times.
265323 if(in_count > out_count) { //FIXME move after swr_convert_internal
834
2/2
✓ Branch 0 taken 187 times.
✓ Branch 1 taken 30 times.
217 if( size > s->in_buffer.count
835
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 187 times.
187 && s->in_buffer_count + in_count - out_count <= s->in_buffer_index){
836 ✗ buf_set(&tmp, &s->in_buffer, s->in_buffer_index);
837 ✗ copy(&s->in_buffer, &tmp, s->in_buffer_count);
838 ✗ s->in_buffer_index=0;
839 }else
840
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 217 times.
217 if((ret=swri_realloc_audio(&s->in_buffer, size)) < 0)
841 ✗ return ret;
842 }
843
844
2/2
✓ Branch 0 taken 265168 times.
✓ Branch 1 taken 155 times.
265323 if(out_count){
845 265168 size = FFMIN(in_count, out_count);
846 265168 ret= swr_convert_internal(s, out, size, in, size);
847
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 265168 times.
265168 if(ret<0)
848 ✗ return ret;
849 265168 buf_set(in, in, ret);
850 265168 in_count -= ret;
851 265168 ret2 += ret;
852 }
853
2/2
✓ Branch 0 taken 217 times.
✓ Branch 1 taken 265106 times.
265323 if(in_count){
854 217 buf_set(&tmp, &s->in_buffer, s->in_buffer_index + s->in_buffer_count);
855 217 copy(&tmp, in, in_count);
856 217 s->in_buffer_count += in_count;
857 }
858 }
859
3/4
✓ Branch 0 taken 265474 times.
✓ Branch 1 taken 156 times.
✓ Branch 2 taken 265474 times.
✗ Branch 3 not taken.
265630 if(ret2>0 && !s->drop_output)
860 265474 s->outpts += ret2 * (int64_t)s->in_sample_rate;
861 av_assert2(max_output < 0 || ret2 < 0 || ret2 <= max_output);
862 265630 return ret2;
863 }
864 }
865
866 52 int swr_drop_output(struct SwrContext *s, int count){
867 const uint8_t *tmp_arg[SWR_CH_MAX];
868 52 s->drop_output += count;
869
870
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52 times.
52 if(s->drop_output <= 0)
871 ✗ return 0;
872
873 52 av_log(s, AV_LOG_VERBOSE, "discarding %d audio samples\n", count);
874 52 return swr_convert(s, NULL, s->drop_output, tmp_arg, 0);
875 }
876
877 33 int swr_inject_silence(struct SwrContext *s, int count){
878 int ret, i;
879 uint8_t *tmp_arg[SWR_CH_MAX];
880
881
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 33 times.
33 if(count <= 0)
882 ✗ return 0;
883
884 #define MAX_SILENCE_STEP 16384
885
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 33 times.
62 while (count > MAX_SILENCE_STEP) {
886
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 29 times.
29 if ((ret = swr_inject_silence(s, MAX_SILENCE_STEP)) < 0)
887 ✗ return ret;
888 29 count -= MAX_SILENCE_STEP;
889 }
890
891
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 33 times.
33 if((ret=swri_realloc_audio(&s->silence, count))<0)
892 ✗ return ret;
893
894 {
895
1/2
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
66 int fill = s->silence.fmt == AV_SAMPLE_FMT_DSD ? 0x69 :
896
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 33 times.
33 s->silence.bps == 1 ? 0x80 : 0;
897
3/4
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 33 times.
✓ Branch 3 taken 33 times.
66 if(s->silence.planar) for(i=0; i<s->silence.ch_count; i++) {
898 33 memset(s->silence.ch[i], fill, count*s->silence.bps);
899 } else
900 ✗ memset(s->silence.ch[0], fill, count*s->silence.bps*s->silence.ch_count);
901 }
902
903 33 reversefill_audiodata(&s->silence, tmp_arg);
904 33 av_log(s, AV_LOG_VERBOSE, "adding %d audio samples of silence\n", count);
905 33 ret = swr_convert(s, NULL, 0, (const uint8_t**)tmp_arg, count);
906 33 return ret;
907 }
908
909 544420 int64_t swr_get_delay(struct SwrContext *s, int64_t base){
910
3/4
✓ Branch 0 taken 544420 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17730 times.
✓ Branch 3 taken 526690 times.
544420 if (s->resampler && s->resample){
911 17730 return s->resampler->get_delay(s, base);
912 }else{
913 526690 return (s->in_buffer_count*base + (s->in_sample_rate>>1))/ s->in_sample_rate;
914 }
915 }
916
917 ✗ int swr_get_out_samples(struct SwrContext *s, int in_samples)
918 {
919 int64_t out_samples;
920
921 ✗ if (in_samples < 0)
922 ✗ return AVERROR(EINVAL);
923
924 ✗ if (s->resampler && s->resample) {
925 ✗ if (!s->resampler->get_out_samples)
926 ✗ return AVERROR(ENOSYS);
927 ✗ out_samples = s->resampler->get_out_samples(s, in_samples);
928 } else {
929 ✗ out_samples = s->in_buffer_count + in_samples;
930 ✗ av_assert0(s->out_sample_rate == s->in_sample_rate);
931 }
932
933 ✗ if (out_samples > INT_MAX)
934 ✗ return AVERROR(EINVAL);
935
936 ✗ return out_samples;
937 }
938
939 127 int swr_set_compensation(struct SwrContext *s, int sample_delta, int compensation_distance){
940 int ret;
941
942
2/4
✓ Branch 0 taken 127 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 127 times.
127 if (!s || compensation_distance < 0)
943 ✗ return AVERROR(EINVAL);
944
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 127 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
127 if (!compensation_distance && sample_delta)
945 ✗ return AVERROR(EINVAL);
946
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 126 times.
127 if (!s->resample) {
947 1 s->flags |= SWR_FLAG_RESAMPLE;
948 1 ret = swr_init(s);
949
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (ret < 0)
950 ✗ return ret;
951 }
952
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 127 times.
127 if (!s->resampler->set_compensation){
953 ✗ return AVERROR(EINVAL);
954 }else{
955 127 return s->resampler->set_compensation(s->resample, sample_delta, compensation_distance);
956 }
957 }
958
959 274427 int64_t swr_next_pts(struct SwrContext *s, int64_t pts){
960
2/2
✓ Branch 0 taken 2217 times.
✓ Branch 1 taken 272210 times.
274427 if(pts == INT64_MIN)
961 2217 return s->outpts;
962
963
2/2
✓ Branch 0 taken 1631 times.
✓ Branch 1 taken 270579 times.
272210 if (s->firstpts == AV_NOPTS_VALUE)
964 1631 s->outpts = s->firstpts = pts;
965
966
2/2
✓ Branch 0 taken 270979 times.
✓ Branch 1 taken 1231 times.
272210 if(s->min_compensation >= FLT_MAX) {
967 270979 return (s->outpts = pts - swr_get_delay(s, s->in_sample_rate * (int64_t)s->out_sample_rate));
968 } else {
969 1231 int64_t delta = pts - swr_get_delay(s, s->in_sample_rate * (int64_t)s->out_sample_rate) - s->outpts + s->drop_output*(int64_t)s->in_sample_rate;
970 1231 double fdelta = delta /(double)(s->in_sample_rate * (int64_t)s->out_sample_rate);
971
972
2/2
✓ Branch 0 taken 183 times.
✓ Branch 1 taken 1048 times.
1231 if(fabs(fdelta) > s->min_compensation) {
973
4/4
✓ Branch 0 taken 129 times.
✓ Branch 1 taken 54 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 127 times.
239 if(s->outpts == s->firstpts || fabs(fdelta) > s->min_hard_compensation){
974 int ret;
975
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 52 times.
56 if(delta > 0) ret = swr_inject_silence(s, delta / s->out_sample_rate);
976 52 else ret = swr_drop_output (s, -delta / s-> in_sample_rate);
977
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
56 if(ret<0){
978 ✗ av_log(s, AV_LOG_ERROR, "Failed to compensate for timestamp delta of %f\n", fdelta);
979 }
980
2/4
✓ Branch 0 taken 127 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 127 times.
✗ Branch 3 not taken.
127 } else if(s->soft_compensation_duration && s->max_soft_compensation) {
981 127 int duration = s->out_sample_rate * s->soft_compensation_duration;
982
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 127 times.
127 double max_soft_compensation = s->max_soft_compensation / (s->max_soft_compensation < 0 ? -s->in_sample_rate : 1);
983 127 int comp = av_clipf(fdelta, -max_soft_compensation, max_soft_compensation) * duration ;
984 127 av_log(s, AV_LOG_VERBOSE, "compensating audio timestamp drift:%f compensation:%d in:%d\n", fdelta, comp, duration);
985 127 swr_set_compensation(s, comp, duration);
986 }
987 }
988
989 1231 return s->outpts;
990 }
991 }
992