FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libswresample/swresample.c
Date: 2025-10-10 03:51:19
Exec Total Coverage
Lines: 467 615 75.9%
Functions: 22 23 95.7%
Branches: 350 529 66.2%

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 16 int swr_set_channel_mapping(struct SwrContext *s, const int *channel_map){
34
2/4
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 16 times.
16 if(!s || s->in_convert) // s needs to be allocated but not initialized
35 return AVERROR(EINVAL);
36 16 s->channel_map = channel_map;
37 16 return 0;
38 }
39
40 1514 int swr_alloc_set_opts2(struct SwrContext **ps,
41 const AVChannelLayout *out_ch_layout, enum AVSampleFormat out_sample_fmt, int out_sample_rate,
42 const AVChannelLayout *in_ch_layout, enum AVSampleFormat in_sample_fmt, int in_sample_rate,
43 int log_offset, void *log_ctx) {
44 1514 struct SwrContext *s = *ps;
45 int ret;
46
47
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 1490 times.
1514 if (!s) s = swr_alloc();
48
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1514 times.
1514 if (!s) return AVERROR(ENOMEM);
49
50 1514 *ps = s;
51
52 1514 s->log_level_offset = log_offset;
53 1514 s->log_ctx = log_ctx;
54
55
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1514 times.
1514 if ((ret = av_opt_set_chlayout(s, "ochl", out_ch_layout, 0)) < 0)
56 goto fail;
57
58
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1514 times.
1514 if ((ret = av_opt_set_int(s, "osf", out_sample_fmt, 0)) < 0)
59 goto fail;
60
61
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1514 times.
1514 if ((ret = av_opt_set_int(s, "osr", out_sample_rate, 0)) < 0)
62 goto fail;
63
64
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1514 times.
1514 if ((ret = av_opt_set_chlayout(s, "ichl", in_ch_layout, 0)) < 0)
65 goto fail;
66
67
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1514 times.
1514 if ((ret = av_opt_set_int(s, "isf", in_sample_fmt, 0)) < 0)
68 goto fail;
69
70
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1514 times.
1514 if ((ret = av_opt_set_int(s, "isr", in_sample_rate, 0)) < 0)
71 goto fail;
72
73 1514 return 0;
74 fail:
75 av_log(s, AV_LOG_ERROR, "Failed to set option\n");
76 swr_free(ps);
77 return ret;
78 }
79
80 5924 static void set_audiodata_fmt(AudioData *a, enum AVSampleFormat fmt){
81 5924 a->fmt = fmt;
82 5924 a->bps = av_get_bytes_per_sample(fmt);
83 5924 a->planar= av_sample_fmt_is_planar(fmt);
84
2/2
✓ Branch 0 taken 4598 times.
✓ Branch 1 taken 1326 times.
5924 if (a->ch_count == 1)
85 4598 a->planar = 1;
86 5924 }
87
88 32352 static void free_temp(AudioData *a){
89 32352 av_free(a->data);
90 32352 memset(a, 0, sizeof(*a));
91 32352 }
92
93 4044 static void clear_context(SwrContext *s){
94 4044 s->in_buffer_index= 0;
95 4044 s->in_buffer_count= 0;
96 4044 s->resample_in_constraint= 0;
97 4044 memset(s->in.ch, 0, sizeof(s->in.ch));
98 4044 memset(s->out.ch, 0, sizeof(s->out.ch));
99 4044 free_temp(&s->postin);
100 4044 free_temp(&s->midbuf);
101 4044 free_temp(&s->preout);
102 4044 free_temp(&s->in_buffer);
103 4044 free_temp(&s->silence);
104 4044 free_temp(&s->drop_temp);
105 4044 free_temp(&s->dither.noise);
106 4044 free_temp(&s->dither.temp);
107 4044 av_channel_layout_uninit(&s->in_ch_layout);
108 4044 av_channel_layout_uninit(&s->out_ch_layout);
109 4044 av_channel_layout_uninit(&s->used_ch_layout);
110 4044 swri_audio_convert_free(&s-> in_convert);
111 4044 swri_audio_convert_free(&s->out_convert);
112 4044 swri_audio_convert_free(&s->full_convert);
113 4044 swri_rematrix_free(s);
114
115 4044 s->delayed_samples_fixup = 0;
116 4044 s->flushed = 0;
117 4044 }
118
119 2502 av_cold void swr_free(SwrContext **ss){
120 2502 SwrContext *s= *ss;
121
2/2
✓ Branch 0 taken 2477 times.
✓ Branch 1 taken 25 times.
2502 if(s){
122 2477 clear_context(s);
123 2477 av_channel_layout_uninit(&s->user_in_chlayout);
124 2477 av_channel_layout_uninit(&s->user_out_chlayout);
125 2477 av_channel_layout_uninit(&s->user_used_chlayout);
126
127
2/2
✓ Branch 0 taken 1536 times.
✓ Branch 1 taken 941 times.
2477 if (s->resampler)
128 1536 s->resampler->free(&s->resample);
129 }
130
131 2502 av_freep(ss);
132 2502 }
133
134 17 av_cold void swr_close(SwrContext *s){
135 17 clear_context(s);
136 17 }
137
138 1550 av_cold int swr_init(struct SwrContext *s){
139 int ret;
140 char l1[1024], l2[1024];
141
142 1550 clear_context(s);
143
144
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1550 times.
1550 if((unsigned) s-> in_sample_fmt >= AV_SAMPLE_FMT_NB){
145 av_log(s, AV_LOG_ERROR, "Requested input sample format %d is invalid\n", s->in_sample_fmt);
146 return AVERROR(EINVAL);
147 }
148
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1550 times.
1550 if((unsigned) s->out_sample_fmt >= AV_SAMPLE_FMT_NB){
149 av_log(s, AV_LOG_ERROR, "Requested output sample format %d is invalid\n", s->out_sample_fmt);
150 return AVERROR(EINVAL);
151 }
152
153
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1550 times.
1550 if(s-> in_sample_rate <= 0){
154 av_log(s, AV_LOG_ERROR, "Requested input sample rate %d is invalid\n", s->in_sample_rate);
155 return AVERROR(EINVAL);
156 }
157
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1550 times.
1550 if(s->out_sample_rate <= 0){
158 av_log(s, AV_LOG_ERROR, "Requested output sample rate %d is invalid\n", s->out_sample_rate);
159 return AVERROR(EINVAL);
160 }
161
162 1550 s->out.ch_count = s-> user_out_chlayout.nb_channels;
163 1550 s-> in.ch_count = s-> user_in_chlayout.nb_channels;
164
165
2/4
✓ Branch 1 taken 1550 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1550 times.
1550 if (!(ret = av_channel_layout_check(&s->user_in_chlayout)) || s->user_in_chlayout.nb_channels > SWR_CH_MAX) {
166 if (ret)
167 av_channel_layout_describe(&s->user_in_chlayout, l1, sizeof(l1));
168 av_log(s, AV_LOG_WARNING, "Input channel layout \"%s\" is invalid or unsupported.\n", ret ? l1 : "");
169 return AVERROR(EINVAL);
170 }
171
172
2/4
✓ Branch 1 taken 1550 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1550 times.
1550 if (!(ret = av_channel_layout_check(&s->user_out_chlayout)) || s->user_out_chlayout.nb_channels > SWR_CH_MAX) {
173 if (ret)
174 av_channel_layout_describe(&s->user_out_chlayout, l2, sizeof(l2));
175 av_log(s, AV_LOG_WARNING, "Output channel layout \"%s\" is invalid or unsupported.\n", ret ? l2 : "");
176 return AVERROR(EINVAL);
177 }
178
179 1550 ret = av_channel_layout_copy(&s->in_ch_layout, &s->user_in_chlayout);
180 1550 ret |= av_channel_layout_copy(&s->out_ch_layout, &s->user_out_chlayout);
181 1550 ret |= av_channel_layout_copy(&s->used_ch_layout, &s->user_used_chlayout);
182
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1550 times.
1550 if (ret < 0)
183 return ret;
184
185 1550 s->int_sample_fmt= s->user_int_sample_fmt;
186
187 1550 s->dither.method = s->user_dither_method;
188
189
1/2
✓ Branch 0 taken 1550 times.
✗ Branch 1 not taken.
1550 switch(s->engine){
190 #if CONFIG_LIBSOXR
191 case SWR_ENGINE_SOXR: s->resampler = &swri_soxr_resampler; break;
192 #endif
193 1550 case SWR_ENGINE_SWR : s->resampler = &swri_resampler; break;
194 default:
195 av_log(s, AV_LOG_ERROR, "Requested resampling engine is unavailable\n");
196 return AVERROR(EINVAL);
197 }
198
199
2/2
✓ Branch 1 taken 1534 times.
✓ Branch 2 taken 16 times.
1550 if (!av_channel_layout_check(&s->used_ch_layout))
200 1534 av_channel_layout_default(&s->used_ch_layout, s->in.ch_count);
201
202
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1543 times.
1550 if (s->used_ch_layout.nb_channels != s->in_ch_layout.nb_channels)
203 7 av_channel_layout_uninit(&s->in_ch_layout);
204
205
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1549 times.
1550 if (s->used_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC)
206 1 av_channel_layout_default(&s->used_ch_layout, s->used_ch_layout.nb_channels);
207
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 1532 times.
1550 if (s->in_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC) {
208 18 ret = av_channel_layout_copy(&s->in_ch_layout, &s->used_ch_layout);
209
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if (ret < 0)
210 return ret;
211 }
212
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 1538 times.
1550 if (s->out_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC)
213 12 av_channel_layout_default(&s->out_ch_layout, s->out.ch_count);
214
215 1550 s->rematrix = av_channel_layout_compare(&s->out_ch_layout, &s->in_ch_layout) ||
216
3/4
✓ Branch 0 taken 1525 times.
✓ Branch 1 taken 25 times.
✓ Branch 2 taken 1525 times.
✗ Branch 3 not taken.
3075 s->rematrix_volume!=1.0 ||
217
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1523 times.
1525 s->rematrix_custom;
218
219
2/2
✓ Branch 0 taken 911 times.
✓ Branch 1 taken 639 times.
1550 if(s->int_sample_fmt == AV_SAMPLE_FMT_NONE){
220 // 16bit or less to 16bit or less with the same sample rate
221
2/2
✓ Branch 1 taken 533 times.
✓ Branch 2 taken 378 times.
911 if( av_get_bytes_per_sample(s-> in_sample_fmt) <= 2
222
2/2
✓ Branch 1 taken 463 times.
✓ Branch 2 taken 70 times.
533 && av_get_bytes_per_sample(s->out_sample_fmt) <= 2
223
2/2
✓ Branch 0 taken 462 times.
✓ Branch 1 taken 1 times.
463 && s->out_sample_rate==s->in_sample_rate) {
224 462 s->int_sample_fmt= AV_SAMPLE_FMT_S16P;
225 // 8 -> 8, 16->8, 8->16bit
226 449 } else if( av_get_bytes_per_sample(s-> in_sample_fmt)
227
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 449 times.
449 +av_get_bytes_per_sample(s->out_sample_fmt) <= 3 ) {
228 s->int_sample_fmt= AV_SAMPLE_FMT_S16P;
229
2/2
✓ Branch 1 taken 71 times.
✓ Branch 2 taken 378 times.
449 }else if( av_get_bytes_per_sample(s-> in_sample_fmt) <= 2
230
2/2
✓ Branch 0 taken 69 times.
✓ Branch 1 taken 2 times.
71 && !s->rematrix
231
2/2
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 1 times.
69 && s->out_sample_rate==s->in_sample_rate
232
1/2
✓ Branch 0 taken 68 times.
✗ Branch 1 not taken.
68 && !(s->flags & SWR_FLAG_RESAMPLE)){
233 68 s->int_sample_fmt= AV_SAMPLE_FMT_S16P;
234
2/2
✓ Branch 1 taken 75 times.
✓ Branch 2 taken 306 times.
381 }else if( av_get_planar_sample_fmt(s-> in_sample_fmt) == AV_SAMPLE_FMT_S32P
235
2/2
✓ Branch 1 taken 41 times.
✓ Branch 2 taken 34 times.
75 && av_get_planar_sample_fmt(s->out_sample_fmt) == AV_SAMPLE_FMT_S32P
236
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 && !s->rematrix
237
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 && s->out_sample_rate == s->in_sample_rate
238
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 && !(s->flags & SWR_FLAG_RESAMPLE)
239
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 && s->engine != SWR_ENGINE_SOXR){
240 41 s->int_sample_fmt= AV_SAMPLE_FMT_S32P;
241
2/2
✓ Branch 1 taken 302 times.
✓ Branch 2 taken 38 times.
340 }else if(av_get_bytes_per_sample(s->in_sample_fmt) <= 4){
242 302 s->int_sample_fmt= AV_SAMPLE_FMT_FLTP;
243 }else{
244 38 s->int_sample_fmt= AV_SAMPLE_FMT_DBLP;
245 }
246 }
247 1550 av_log(s, AV_LOG_DEBUG, "Using %s internally between filters\n", av_get_sample_fmt_name(s->int_sample_fmt));
248
249
2/2
✓ Branch 0 taken 845 times.
✓ Branch 1 taken 705 times.
1550 if( s->int_sample_fmt != AV_SAMPLE_FMT_S16P
250
2/2
✓ Branch 0 taken 660 times.
✓ Branch 1 taken 185 times.
845 &&s->int_sample_fmt != AV_SAMPLE_FMT_S32P
251
1/2
✓ Branch 0 taken 660 times.
✗ Branch 1 not taken.
660 &&s->int_sample_fmt != AV_SAMPLE_FMT_S64P
252
2/2
✓ Branch 0 taken 194 times.
✓ Branch 1 taken 466 times.
660 &&s->int_sample_fmt != AV_SAMPLE_FMT_FLTP
253
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 194 times.
194 &&s->int_sample_fmt != AV_SAMPLE_FMT_DBLP){
254 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));
255 return AVERROR(EINVAL);
256 }
257
258 1550 set_audiodata_fmt(&s-> in, s-> in_sample_fmt);
259 1550 set_audiodata_fmt(&s->out, s->out_sample_fmt);
260
261
2/2
✓ Branch 0 taken 55 times.
✓ Branch 1 taken 1495 times.
1550 if (s->firstpts_in_samples != AV_NOPTS_VALUE) {
262
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)
263 s->async = 1;
264
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 1 times.
55 if (s->firstpts == AV_NOPTS_VALUE)
265 54 s->firstpts =
266 54 s->outpts = s->firstpts_in_samples * s->out_sample_rate;
267 } else
268 1495 s->firstpts = AV_NOPTS_VALUE;
269
270
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 1496 times.
1550 if (s->async) {
271
2/2
✓ Branch 0 taken 53 times.
✓ Branch 1 taken 1 times.
54 if (s->min_compensation >= FLT_MAX/2)
272 53 s->min_compensation = 0.001;
273
1/2
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
54 if (s->async > 1.0001) {
274 54 s->max_soft_compensation = s->async / (double) s->in_sample_rate;
275 }
276 }
277
278
4/4
✓ Branch 0 taken 869 times.
✓ Branch 1 taken 681 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 868 times.
1550 if (s->out_sample_rate!=s->in_sample_rate || (s->flags & SWR_FLAG_RESAMPLE)){
279 682 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);
280
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 682 times.
682 if (!s->resample) {
281 av_log(s, AV_LOG_ERROR, "Failed to initialize resampler\n");
282 return AVERROR(ENOMEM);
283 }
284 }else
285 868 s->resampler->free(&s->resample);
286
2/2
✓ Branch 0 taken 845 times.
✓ Branch 1 taken 705 times.
1550 if( s->int_sample_fmt != AV_SAMPLE_FMT_S16P
287
2/2
✓ Branch 0 taken 660 times.
✓ Branch 1 taken 185 times.
845 && s->int_sample_fmt != AV_SAMPLE_FMT_S32P
288
2/2
✓ Branch 0 taken 194 times.
✓ Branch 1 taken 466 times.
660 && s->int_sample_fmt != AV_SAMPLE_FMT_FLTP
289
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 194 times.
194 && s->int_sample_fmt != AV_SAMPLE_FMT_DBLP
290 && s->resample){
291 av_log(s, AV_LOG_ERROR, "Resampling only supported with internal s16p/s32p/fltp/dblp\n");
292 ret = AVERROR(EINVAL);
293 goto fail;
294 }
295
296 #define RSC 1 //FIXME finetune
297
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1550 times.
1550 if(!s-> in.ch_count)
298 s-> in.ch_count = s->in_ch_layout.nb_channels;
299
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1550 times.
1550 if (!av_channel_layout_check(&s->used_ch_layout))
300 av_channel_layout_default(&s->used_ch_layout, s->in.ch_count);
301
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1550 times.
1550 if(!s->out.ch_count)
302 s->out.ch_count = s->out_ch_layout.nb_channels;
303
304
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1550 times.
1550 if(!s-> in.ch_count){
305 av_assert0(s->in_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC);
306 av_log(s, AV_LOG_ERROR, "Input channel count and layout are unset\n");
307 ret = AVERROR(EINVAL);
308 goto fail;
309 }
310
311 1550 av_channel_layout_describe(&s->out_ch_layout, l2, sizeof(l2));
312 1550 av_channel_layout_describe(&s->in_ch_layout, l1, sizeof(l1));
313
3/4
✓ Branch 0 taken 1549 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1549 times.
1550 if (s->in_ch_layout.order != AV_CHANNEL_ORDER_UNSPEC && s->used_ch_layout.nb_channels != s->in_ch_layout.nb_channels) {
314 av_log(s, AV_LOG_ERROR, "Input channel layout %s mismatches specified channel count %d\n", l1, s->used_ch_layout.nb_channels);
315 ret = AVERROR(EINVAL);
316 goto fail;
317 }
318
319
2/2
✓ Branch 0 taken 1549 times.
✓ Branch 1 taken 1 times.
1550 if (( s->out_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC
320
4/6
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1548 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
1550 || s-> in_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC) && s->used_ch_layout.nb_channels != s->out.ch_count && !s->rematrix_custom) {
321 av_log(s, AV_LOG_ERROR, "Rematrix is needed between %s and %s "
322 "but there is not enough information to do it\n", l1, l2);
323 ret = AVERROR(EINVAL);
324 goto fail;
325 }
326
327
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1550 times.
1550 av_assert0(s->used_ch_layout.nb_channels);
328
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1550 times.
1550 av_assert0(s->out.ch_count);
329 1550 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;
330
331 1550 s->in_buffer= s->in;
332 1550 s->silence = s->in;
333 1550 s->drop_temp= s->out;
334
335
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1550 times.
1550 if ((ret = swri_dither_init(s, s->out_sample_fmt, s->int_sample_fmt)) < 0)
336 goto fail;
337
338
7/8
✓ Branch 0 taken 868 times.
✓ Branch 1 taken 682 times.
✓ Branch 2 taken 845 times.
✓ Branch 3 taken 23 times.
✓ Branch 4 taken 836 times.
✓ Branch 5 taken 9 times.
✓ Branch 6 taken 836 times.
✗ Branch 7 not taken.
1550 if(!s->resample && !s->rematrix && !s->channel_map && !s->dither.method){
339 836 s->full_convert = swri_audio_convert_alloc(s->out_sample_fmt,
340 s-> in_sample_fmt, s-> in.ch_count, NULL, 0);
341 836 return 0;
342 }
343
344 714 s->in_convert = swri_audio_convert_alloc(s->int_sample_fmt,
345 s-> in_sample_fmt, s->used_ch_layout.nb_channels, s->channel_map, 0);
346 714 s->out_convert= swri_audio_convert_alloc(s->out_sample_fmt,
347 s->int_sample_fmt, s->out.ch_count, NULL, 0);
348
349
2/4
✓ Branch 0 taken 714 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 714 times.
714 if (!s->in_convert || !s->out_convert) {
350 ret = AVERROR(ENOMEM);
351 goto fail;
352 }
353
354 714 s->postin= s->in;
355 714 s->preout= s->out;
356 714 s->midbuf= s->in;
357
358
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 698 times.
714 if(s->channel_map){
359 16 s->postin.ch_count=
360 16 s->midbuf.ch_count= s->used_ch_layout.nb_channels;
361
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if(s->resample)
362 s->in_buffer.ch_count= s->used_ch_layout.nb_channels;
363 }
364
2/2
✓ Branch 0 taken 346 times.
✓ Branch 1 taken 368 times.
714 if(!s->resample_first){
365 346 s->midbuf.ch_count= s->out.ch_count;
366
2/2
✓ Branch 0 taken 324 times.
✓ Branch 1 taken 22 times.
346 if(s->resample)
367 324 s->in_buffer.ch_count = s->out.ch_count;
368 }
369
370 714 set_audiodata_fmt(&s->postin, s->int_sample_fmt);
371 714 set_audiodata_fmt(&s->midbuf, s->int_sample_fmt);
372 714 set_audiodata_fmt(&s->preout, s->int_sample_fmt);
373
374
2/2
✓ Branch 0 taken 682 times.
✓ Branch 1 taken 32 times.
714 if(s->resample){
375 682 set_audiodata_fmt(&s->in_buffer, s->int_sample_fmt);
376 }
377
378
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 714 times.
714 av_assert0(!s->preout.count);
379 714 s->dither.noise = s->preout;
380 714 s->dither.temp = s->preout;
381
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 714 times.
714 if (s->dither.method > SWR_DITHER_NS) {
382 s->dither.noise.bps = 4;
383 s->dither.noise.fmt = AV_SAMPLE_FMT_FLTP;
384 s->dither.noise_scale = 1;
385 }
386
387
3/4
✓ Branch 0 taken 687 times.
✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 687 times.
714 if(s->rematrix || s->dither.method) {
388 27 ret = swri_rematrix_init(s);
389
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
27 if (ret < 0)
390 goto fail;
391 }
392
393 714 return 0;
394 fail:
395 swr_close(s);
396 return ret;
397
398 }
399
400 99336 int swri_realloc_audio(AudioData *a, int count){
401 int i, countb;
402 AudioData old;
403
404
2/4
✓ Branch 0 taken 99336 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 99336 times.
99336 if(count < 0 || count > INT_MAX/2/a->bps/a->ch_count)
405 return AVERROR(EINVAL);
406
407
2/2
✓ Branch 0 taken 95302 times.
✓ Branch 1 taken 4034 times.
99336 if(a->count >= count)
408 95302 return 0;
409
410 4034 count*=2;
411
412 4034 countb= FFALIGN(count*a->bps, ALIGN);
413 4034 old= *a;
414
415
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4034 times.
4034 av_assert0(a->bps);
416
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4034 times.
4034 av_assert0(a->ch_count);
417
418 4034 a->data = av_calloc(countb, a->ch_count);
419
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4034 times.
4034 if(!a->data)
420 return AVERROR(ENOMEM);
421
2/2
✓ Branch 0 taken 4486 times.
✓ Branch 1 taken 4034 times.
8520 for(i=0; i<a->ch_count; i++){
422
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4486 times.
4486 a->ch[i]= a->data + i*(a->planar ? countb : a->bps);
423
3/4
✓ Branch 0 taken 1237 times.
✓ Branch 1 taken 3249 times.
✓ Branch 2 taken 1237 times.
✗ Branch 3 not taken.
4486 if(a->count && a->planar) memcpy(a->ch[i], old.ch[i], a->count*a->bps);
424 }
425
3/4
✓ Branch 0 taken 1153 times.
✓ Branch 1 taken 2881 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1153 times.
4034 if(a->count && !a->planar) memcpy(a->ch[0], old.ch[0], a->count*a->ch_count*a->bps);
426 4034 av_freep(&old.data);
427 4034 a->count= count;
428
429 4034 return 1;
430 }
431
432 35037 static void copy(AudioData *out, AudioData *in,
433 int count){
434
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35037 times.
35037 av_assert0(out->planar == in->planar);
435
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35037 times.
35037 av_assert0(out->bps == in->bps);
436
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35037 times.
35037 av_assert0(out->ch_count == in->ch_count);
437
1/2
✓ Branch 0 taken 35037 times.
✗ Branch 1 not taken.
35037 if(out->planar){
438 int ch;
439
2/2
✓ Branch 0 taken 55254 times.
✓ Branch 1 taken 35037 times.
90291 for(ch=0; ch<out->ch_count; ch++)
440 55254 memcpy(out->ch[ch], in->ch[ch], count*out->bps);
441 }else
442 memcpy(out->ch[0], in->ch[0], count*out->ch_count*out->bps);
443 35037 }
444
445 465761 static void fill_audiodata(AudioData *out, uint8_t *const in_arg [SWR_CH_MAX])
446 {
447 int i;
448
2/2
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 465693 times.
465761 if(!in_arg){
449 68 memset(out->ch, 0, sizeof(out->ch));
450
2/2
✓ Branch 0 taken 332524 times.
✓ Branch 1 taken 133169 times.
465693 }else if(out->planar){
451
2/2
✓ Branch 0 taken 516740 times.
✓ Branch 1 taken 332524 times.
849264 for(i=0; i<out->ch_count; i++)
452 516740 out->ch[i]= in_arg[i];
453 }else{
454
2/2
✓ Branch 0 taken 311243 times.
✓ Branch 1 taken 133169 times.
444412 for(i=0; i<out->ch_count; i++)
455 311243 out->ch[i]= in_arg[0] + i*out->bps;
456 }
457 465761 }
458
459 137 static void reversefill_audiodata(AudioData *out, uint8_t *in_arg [SWR_CH_MAX]){
460 int i;
461
1/2
✓ Branch 0 taken 137 times.
✗ Branch 1 not taken.
137 if(out->planar){
462
2/2
✓ Branch 0 taken 137 times.
✓ Branch 1 taken 137 times.
274 for(i=0; i<out->ch_count; i++)
463 137 in_arg[i]= out->ch[i];
464 }else{
465 in_arg[0]= out->ch[0];
466 }
467 137 }
468
469 /**
470 *
471 * out may be equal in.
472 */
473 430850 static void buf_set(AudioData *out, AudioData *in, int count){
474 int ch;
475
2/2
✓ Branch 0 taken 420645 times.
✓ Branch 1 taken 10205 times.
430850 if(in->planar){
476
2/2
✓ Branch 0 taken 705139 times.
✓ Branch 1 taken 420645 times.
1125784 for(ch=0; ch<out->ch_count; ch++)
477 705139 out->ch[ch]= in->ch[ch] + count*out->bps;
478 }else{
479
2/2
✓ Branch 0 taken 26648 times.
✓ Branch 1 taken 10205 times.
36853 for(ch=out->ch_count-1; ch>=0; ch--)
480 26648 out->ch[ch]= in->ch[0] + (ch + count*out->ch_count) * out->bps;
481 }
482 430850 }
483
484 /**
485 *
486 * @return number of samples output per channel
487 */
488 19412 static int resample(SwrContext *s, AudioData *out_param, int out_count,
489 const AudioData * in_param, int in_count){
490 AudioData in, out, tmp;
491 19412 int ret_sum=0;
492 19412 int border=0;
493
1/2
✓ Branch 0 taken 19412 times.
✗ Branch 1 not taken.
19412 int padless = ARCH_X86 && s->engine == SWR_ENGINE_SWR ? 7 : 0;
494
495 av_assert1(s->in_buffer.ch_count == in_param->ch_count);
496 av_assert1(s->in_buffer.planar == in_param->planar);
497 av_assert1(s->in_buffer.fmt == in_param->fmt);
498
499 19412 tmp=out=*out_param;
500 19412 in = *in_param;
501
502 19412 border = s->resampler->invert_initial_buffer(s->resample, &s->in_buffer,
503 &in, in_count, &s->in_buffer_index, &s->in_buffer_count);
504
2/2
✓ Branch 0 taken 87 times.
✓ Branch 1 taken 19325 times.
19412 if (border == INT_MAX) {
505 87 return 0;
506
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19325 times.
19325 } else if (border < 0) {
507 return border;
508
2/2
✓ Branch 0 taken 680 times.
✓ Branch 1 taken 18645 times.
19325 } else if (border) {
509 680 buf_set(&in, &in, border);
510 680 in_count -= border;
511 680 s->resample_in_constraint = 0;
512 }
513
514 35002 do{
515 int ret, size, consumed;
516
4/4
✓ Branch 0 taken 46514 times.
✓ Branch 1 taken 7813 times.
✓ Branch 2 taken 46508 times.
✓ Branch 3 taken 6 times.
54327 if(!s->resample_in_constraint && s->in_buffer_count){
517 46508 buf_set(&tmp, &s->in_buffer, s->in_buffer_index);
518 46508 ret= s->resampler->multiple_resample(s->resample, &out, out_count, &tmp, s->in_buffer_count, &consumed);
519 46508 out_count -= ret;
520 46508 ret_sum += ret;
521 46508 buf_set(&out, &out, ret);
522 46508 s->in_buffer_count -= consumed;
523 46508 s->in_buffer_index += consumed;
524
525
2/2
✓ Branch 0 taken 19320 times.
✓ Branch 1 taken 27188 times.
46508 if(!in_count)
526 19320 break;
527
2/2
✓ Branch 0 taken 17607 times.
✓ Branch 1 taken 9581 times.
27188 if(s->in_buffer_count <= border){
528 17607 buf_set(&in, &in, -s->in_buffer_count);
529 17607 in_count += s->in_buffer_count;
530 17607 s->in_buffer_count=0;
531 17607 s->in_buffer_index=0;
532 17607 border = 0;
533 }
534 }
535
536
6/6
✓ Branch 0 taken 35003 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 35002 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 17651 times.
✓ Branch 5 taken 17355 times.
35007 if((s->flushed || in_count > padless) && !s->in_buffer_count){
537 17651 s->in_buffer_index=0;
538 17651 ret= s->resampler->multiple_resample(s->resample, &out, out_count, &in, FFMAX(in_count-padless, 0), &consumed);
539 17651 out_count -= ret;
540 17651 ret_sum += ret;
541 17651 buf_set(&out, &out, ret);
542 17651 in_count -= consumed;
543 17651 buf_set(&in, &in, consumed);
544 }
545
546 //TODO is this check sane considering the advanced copy avoidance below
547 35007 size= s->in_buffer_index + s->in_buffer_count + in_count;
548
2/2
✓ Branch 0 taken 693 times.
✓ Branch 1 taken 34314 times.
35007 if( size > s->in_buffer.count
549
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 693 times.
693 && s->in_buffer_count + in_count <= s->in_buffer_index){
550 buf_set(&tmp, &s->in_buffer, s->in_buffer_index);
551 copy(&s->in_buffer, &tmp, s->in_buffer_count);
552 s->in_buffer_index=0;
553 }else
554
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 35007 times.
35007 if((ret=swri_realloc_audio(&s->in_buffer, size)) < 0)
555 return ret;
556
557
2/2
✓ Branch 0 taken 35002 times.
✓ Branch 1 taken 5 times.
35007 if(in_count){
558 35002 int count= in_count;
559
6/6
✓ Branch 0 taken 17355 times.
✓ Branch 1 taken 17647 times.
✓ Branch 2 taken 17044 times.
✓ Branch 3 taken 311 times.
✓ Branch 4 taken 17024 times.
✓ Branch 5 taken 20 times.
35002 if(s->in_buffer_count && s->in_buffer_count+2 < count && out_count) count= s->in_buffer_count+2;
560
561 35002 buf_set(&tmp, &s->in_buffer, s->in_buffer_index + s->in_buffer_count);
562 35002 copy(&tmp, &in, /*in_*/count);
563 35002 s->in_buffer_count += count;
564 35002 in_count -= count;
565 35002 border += count;
566 35002 buf_set(&in, &in, count);
567 35002 s->resample_in_constraint= 0;
568
3/4
✓ Branch 0 taken 17647 times.
✓ Branch 1 taken 17355 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17647 times.
35002 if(s->in_buffer_count != count || in_count)
569 35002 continue;
570
1/2
✓ Branch 0 taken 17647 times.
✗ Branch 1 not taken.
17647 if (padless) {
571 17647 padless = 0;
572 17647 continue;
573 }
574 }
575 5 break;
576 }while(1);
577
578 19325 s->resample_in_constraint= !!out_count;
579
580 19325 return ret_sum;
581 }
582
583 233493 static int swr_convert_internal(struct SwrContext *s, AudioData *out, int out_count,
584 AudioData *in , int in_count){
585 AudioData *postin, *midbuf, *preout;
586 int ret/*, in_max*/;
587 AudioData preout_tmp, midbuf_tmp;
588
589
2/2
✓ Branch 0 taken 212582 times.
✓ Branch 1 taken 20911 times.
233493 if(s->full_convert){
590
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 212582 times.
212582 av_assert0(!s->resample);
591 212582 swri_audio_convert(s->full_convert, out, in, in_count);
592 212582 return out_count;
593 }
594
595 // in_max= out_count*(int64_t)s->in_sample_rate / s->out_sample_rate + resample_filter_taps;
596 // in_count= FFMIN(in_count, in_in + 2 - s->hist_buffer_count);
597
598
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 20911 times.
20911 if((ret=swri_realloc_audio(&s->postin, in_count))<0)
599 return ret;
600
2/2
✓ Branch 0 taken 14800 times.
✓ Branch 1 taken 6111 times.
20911 if(s->resample_first){
601
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14800 times.
14800 av_assert0(s->midbuf.ch_count == s->used_ch_layout.nb_channels);
602
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 14800 times.
14800 if((ret=swri_realloc_audio(&s->midbuf, out_count))<0)
603 return ret;
604 }else{
605
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6111 times.
6111 av_assert0(s->midbuf.ch_count == s->out.ch_count);
606
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6111 times.
6111 if((ret=swri_realloc_audio(&s->midbuf, in_count))<0)
607 return ret;
608 }
609
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 20911 times.
20911 if((ret=swri_realloc_audio(&s->preout, out_count))<0)
610 return ret;
611
612 20911 postin= &s->postin;
613
614 20911 midbuf_tmp= s->midbuf;
615 20911 midbuf= &midbuf_tmp;
616 20911 preout_tmp= s->preout;
617 20911 preout= &preout_tmp;
618
619
4/6
✓ Branch 0 taken 14776 times.
✓ Branch 1 taken 6135 times.
✓ Branch 2 taken 14776 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 14776 times.
✗ Branch 5 not taken.
20911 if(s->int_sample_fmt == s-> in_sample_fmt && s->in.planar && !s->channel_map)
620 14776 postin= in;
621
622
4/4
✓ Branch 0 taken 14800 times.
✓ Branch 1 taken 6111 times.
✓ Branch 2 taken 5671 times.
✓ Branch 3 taken 15240 times.
20911 if(s->resample_first ? !s->resample : !s->rematrix)
623 5671 midbuf= postin;
624
625
4/4
✓ Branch 0 taken 14800 times.
✓ Branch 1 taken 6111 times.
✓ Branch 2 taken 15642 times.
✓ Branch 3 taken 5269 times.
20911 if(s->resample_first ? !s->rematrix : !s->resample)
626 15642 preout= midbuf;
627
628
3/4
✓ Branch 0 taken 14029 times.
✓ Branch 1 taken 6882 times.
✓ Branch 2 taken 14029 times.
✗ Branch 3 not taken.
20911 if(s->int_sample_fmt == s->out_sample_fmt && s->out.planar
629
3/4
✓ Branch 0 taken 1044 times.
✓ Branch 1 taken 12985 times.
✓ Branch 2 taken 1044 times.
✗ Branch 3 not taken.
14029 && !(s->out_sample_fmt==AV_SAMPLE_FMT_S32P && (s->dither.output_sample_bits&31))){
630
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14029 times.
14029 if(preout==in){
631 out_count= FFMIN(out_count, in_count); //TODO check at the end if this is needed or redundant
632 av_assert0(s->in.planar); //we only support planar internally so it has to be, we support copying non planar though
633 copy(out, in, out_count);
634 return out_count;
635 }
636
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14029 times.
14029 else if(preout==postin) preout= midbuf= postin= out;
637
2/2
✓ Branch 0 taken 12986 times.
✓ Branch 1 taken 1043 times.
14029 else if(preout==midbuf) preout= midbuf= out;
638 1043 else preout= out;
639 }
640
641
2/2
✓ Branch 0 taken 6135 times.
✓ Branch 1 taken 14776 times.
20911 if(in != postin){
642 6135 swri_audio_convert(s->in_convert, postin, in, in_count);
643 }
644
645
2/2
✓ Branch 0 taken 14800 times.
✓ Branch 1 taken 6111 times.
20911 if(s->resample_first){
646
2/2
✓ Branch 0 taken 14507 times.
✓ Branch 1 taken 293 times.
14800 if(postin != midbuf)
647
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 14507 times.
14507 if ((out_count = resample(s, midbuf, out_count, postin, in_count)) < 0)
648 return out_count;
649
2/2
✓ Branch 0 taken 364 times.
✓ Branch 1 taken 14436 times.
14800 if(midbuf != preout)
650 364 swri_rematrix(s, preout, midbuf, out_count, preout==out);
651 }else{
652
2/2
✓ Branch 0 taken 733 times.
✓ Branch 1 taken 5378 times.
6111 if(postin != midbuf)
653 733 swri_rematrix(s, midbuf, postin, in_count, midbuf==out);
654
2/2
✓ Branch 0 taken 4905 times.
✓ Branch 1 taken 1206 times.
6111 if(midbuf != preout)
655
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4905 times.
4905 if ((out_count = resample(s, preout, out_count, midbuf, in_count)) < 0)
656 return out_count;
657 }
658
659
4/4
✓ Branch 0 taken 6882 times.
✓ Branch 1 taken 14029 times.
✓ Branch 2 taken 6554 times.
✓ Branch 3 taken 328 times.
20911 if(preout != out && out_count){
660 6554 AudioData *conv_src = preout;
661
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6554 times.
6554 if(s->dither.method){
662 int ch;
663 int dither_count= FFMAX(out_count, 1<<16);
664
665 if (preout == in) {
666 conv_src = &s->dither.temp;
667 if((ret=swri_realloc_audio(&s->dither.temp, dither_count))<0)
668 return ret;
669 }
670
671 if((ret=swri_realloc_audio(&s->dither.noise, dither_count))<0)
672 return ret;
673 if(ret)
674 for(ch=0; ch<s->dither.noise.ch_count; ch++)
675 if((ret=swri_get_dither(s, s->dither.noise.ch[ch], s->dither.noise.count, (12345678913579ULL*ch + 3141592) % 2718281828U, s->dither.noise.fmt))<0)
676 return ret;
677 av_assert0(s->dither.noise.ch_count == preout->ch_count);
678
679 if(s->dither.noise_pos + out_count > s->dither.noise.count)
680 s->dither.noise_pos = 0;
681
682 if (s->dither.method < SWR_DITHER_NS){
683 if (s->mix_2_1_simd) {
684 int len1= out_count&~15;
685 int off = len1 * preout->bps;
686
687 if(len1)
688 for(ch=0; ch<preout->ch_count; ch++)
689 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);
690 if(out_count != len1)
691 for(ch=0; ch<preout->ch_count; ch++)
692 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);
693 } else {
694 for(ch=0; ch<preout->ch_count; ch++)
695 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);
696 }
697 } else {
698 switch(s->int_sample_fmt) {
699 case AV_SAMPLE_FMT_S16P :swri_noise_shaping_int16(s, conv_src, preout, &s->dither.noise, out_count); break;
700 case AV_SAMPLE_FMT_S32P :swri_noise_shaping_int32(s, conv_src, preout, &s->dither.noise, out_count); break;
701 case AV_SAMPLE_FMT_FLTP :swri_noise_shaping_float(s, conv_src, preout, &s->dither.noise, out_count); break;
702 case AV_SAMPLE_FMT_DBLP :swri_noise_shaping_double(s,conv_src, preout, &s->dither.noise, out_count); break;
703 }
704 }
705 s->dither.noise_pos += out_count;
706 }
707 //FIXME packed doesn't need more than 1 chan here!
708 6554 swri_audio_convert(s->out_convert, out, conv_src, out_count);
709 }
710 20911 return out_count;
711 }
712
713 270043 int swr_is_initialized(struct SwrContext *s) {
714 270043 return !!s->in_buffer.ch_count;
715 }
716
717 234217 int attribute_align_arg swr_convert(struct SwrContext *s,
718 uint8_t * const *out_arg, int out_count,
719 const uint8_t * const *in_arg, int in_count)
720 {
721 234217 AudioData * in= &s->in;
722 234217 AudioData *out= &s->out;
723 av_unused int max_output;
724
725
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 234217 times.
234217 if (!swr_is_initialized(s)) {
726 av_log(s, AV_LOG_ERROR, "Context has not been initialized\n");
727 return AVERROR(EINVAL);
728 }
729 #if defined(ASSERT_LEVEL) && ASSERT_LEVEL >1
730 max_output = swr_get_out_samples(s, in_count);
731 #endif
732
733
2/2
✓ Branch 0 taken 104 times.
✓ Branch 1 taken 234165 times.
234269 while(s->drop_output > 0){
734 int ret;
735 uint8_t *tmp_arg[SWR_CH_MAX];
736 #define MAX_DROP_STEP 16384
737
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)
738 52 return ret;
739
740 104 reversefill_audiodata(&s->drop_temp, tmp_arg);
741 104 s->drop_output *= -1; //FIXME find a less hackish solution
742
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
743 104 s->drop_output *= -1;
744 104 in_count = 0;
745
2/2
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 52 times.
104 if(ret>0) {
746 52 s->drop_output -= ret;
747
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)
748 return 0;
749 52 continue;
750 }
751
752
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52 times.
52 av_assert0(s->drop_output);
753 52 return 0;
754 }
755
756
2/2
✓ Branch 0 taken 1931 times.
✓ Branch 1 taken 232234 times.
234165 if(!in_arg){
757
2/2
✓ Branch 0 taken 1293 times.
✓ Branch 1 taken 638 times.
1931 if(s->resample){
758
2/2
✓ Branch 0 taken 657 times.
✓ Branch 1 taken 636 times.
1293 if (!s->flushed)
759 657 s->resampler->flush(s);
760 1293 s->resample_in_constraint = 0;
761 1293 s->flushed = 1;
762
1/2
✓ Branch 0 taken 638 times.
✗ Branch 1 not taken.
638 }else if(!s->in_buffer_count){
763 638 return 0;
764 }
765 }else
766 232234 fill_audiodata(in , (void*)in_arg);
767
768 233527 fill_audiodata(out, out_arg);
769
770
2/2
✓ Branch 0 taken 19412 times.
✓ Branch 1 taken 214115 times.
233527 if(s->resample){
771 19412 int ret = swr_convert_internal(s, out, out_count, in, in_count);
772
4/4
✓ Branch 0 taken 18671 times.
✓ Branch 1 taken 741 times.
✓ Branch 2 taken 18619 times.
✓ Branch 3 taken 52 times.
19412 if(ret>0 && !s->drop_output)
773 18619 s->outpts += ret * (int64_t)s->in_sample_rate;
774
775 av_assert2(max_output < 0 || ret <= max_output);
776
777 19412 return ret;
778 }else{
779 214115 AudioData tmp= *in;
780 214115 int ret2=0;
781 int ret, size;
782 214115 size = FFMIN(out_count, s->in_buffer_count);
783
2/2
✓ Branch 0 taken 125 times.
✓ Branch 1 taken 213990 times.
214115 if(size){
784 125 buf_set(&tmp, &s->in_buffer, s->in_buffer_index);
785 125 ret= swr_convert_internal(s, out, size, &tmp, size);
786
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 125 times.
125 if(ret<0)
787 return ret;
788 125 ret2= ret;
789 125 s->in_buffer_count -= ret;
790 125 s->in_buffer_index += ret;
791 125 buf_set(out, out, ret);
792 125 out_count -= ret;
793
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 121 times.
125 if(!s->in_buffer_count)
794 4 s->in_buffer_index = 0;
795 }
796
797
2/2
✓ Branch 0 taken 213990 times.
✓ Branch 1 taken 125 times.
214115 if(in_count){
798 213990 size= s->in_buffer_index + s->in_buffer_count + in_count - out_count;
799
800
2/2
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 213955 times.
213990 if(in_count > out_count) { //FIXME move after swr_convert_internal
801
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 30 times.
35 if( size > s->in_buffer.count
802
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 && s->in_buffer_count + in_count - out_count <= s->in_buffer_index){
803 buf_set(&tmp, &s->in_buffer, s->in_buffer_index);
804 copy(&s->in_buffer, &tmp, s->in_buffer_count);
805 s->in_buffer_index=0;
806 }else
807
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 35 times.
35 if((ret=swri_realloc_audio(&s->in_buffer, size)) < 0)
808 return ret;
809 }
810
811
2/2
✓ Branch 0 taken 213956 times.
✓ Branch 1 taken 34 times.
213990 if(out_count){
812 213956 size = FFMIN(in_count, out_count);
813 213956 ret= swr_convert_internal(s, out, size, in, size);
814
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 213956 times.
213956 if(ret<0)
815 return ret;
816 213956 buf_set(in, in, ret);
817 213956 in_count -= ret;
818 213956 ret2 += ret;
819 }
820
2/2
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 213955 times.
213990 if(in_count){
821 35 buf_set(&tmp, &s->in_buffer, s->in_buffer_index + s->in_buffer_count);
822 35 copy(&tmp, in, in_count);
823 35 s->in_buffer_count += in_count;
824 }
825 }
826
3/4
✓ Branch 0 taken 214080 times.
✓ Branch 1 taken 35 times.
✓ Branch 2 taken 214080 times.
✗ Branch 3 not taken.
214115 if(ret2>0 && !s->drop_output)
827 214080 s->outpts += ret2 * (int64_t)s->in_sample_rate;
828 av_assert2(max_output < 0 || ret2 < 0 || ret2 <= max_output);
829 214115 return ret2;
830 }
831 }
832
833 52 int swr_drop_output(struct SwrContext *s, int count){
834 const uint8_t *tmp_arg[SWR_CH_MAX];
835 52 s->drop_output += count;
836
837
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52 times.
52 if(s->drop_output <= 0)
838 return 0;
839
840 52 av_log(s, AV_LOG_VERBOSE, "discarding %d audio samples\n", count);
841 52 return swr_convert(s, NULL, s->drop_output, tmp_arg, 0);
842 }
843
844 33 int swr_inject_silence(struct SwrContext *s, int count){
845 int ret, i;
846 uint8_t *tmp_arg[SWR_CH_MAX];
847
848
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 33 times.
33 if(count <= 0)
849 return 0;
850
851 #define MAX_SILENCE_STEP 16384
852
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 33 times.
62 while (count > MAX_SILENCE_STEP) {
853
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 29 times.
29 if ((ret = swr_inject_silence(s, MAX_SILENCE_STEP)) < 0)
854 return ret;
855 29 count -= MAX_SILENCE_STEP;
856 }
857
858
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 33 times.
33 if((ret=swri_realloc_audio(&s->silence, count))<0)
859 return ret;
860
861
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++) {
862
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 33 times.
33 memset(s->silence.ch[i], s->silence.bps==1 ? 0x80 : 0, count*s->silence.bps);
863 } else
864 memset(s->silence.ch[0], s->silence.bps==1 ? 0x80 : 0, count*s->silence.bps*s->silence.ch_count);
865
866 33 reversefill_audiodata(&s->silence, tmp_arg);
867 33 av_log(s, AV_LOG_VERBOSE, "adding %d audio samples of silence\n", count);
868 33 ret = swr_convert(s, NULL, 0, (const uint8_t**)tmp_arg, count);
869 33 return ret;
870 }
871
872 442584 int64_t swr_get_delay(struct SwrContext *s, int64_t base){
873
3/4
✓ Branch 0 taken 442584 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16906 times.
✓ Branch 3 taken 425678 times.
442584 if (s->resampler && s->resample){
874 16906 return s->resampler->get_delay(s, base);
875 }else{
876 425678 return (s->in_buffer_count*base + (s->in_sample_rate>>1))/ s->in_sample_rate;
877 }
878 }
879
880 int swr_get_out_samples(struct SwrContext *s, int in_samples)
881 {
882 int64_t out_samples;
883
884 if (in_samples < 0)
885 return AVERROR(EINVAL);
886
887 if (s->resampler && s->resample) {
888 if (!s->resampler->get_out_samples)
889 return AVERROR(ENOSYS);
890 out_samples = s->resampler->get_out_samples(s, in_samples);
891 } else {
892 out_samples = s->in_buffer_count + in_samples;
893 av_assert0(s->out_sample_rate == s->in_sample_rate);
894 }
895
896 if (out_samples > INT_MAX)
897 return AVERROR(EINVAL);
898
899 return out_samples;
900 }
901
902 127 int swr_set_compensation(struct SwrContext *s, int sample_delta, int compensation_distance){
903 int ret;
904
905
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)
906 return AVERROR(EINVAL);
907
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)
908 return AVERROR(EINVAL);
909
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 126 times.
127 if (!s->resample) {
910 1 s->flags |= SWR_FLAG_RESAMPLE;
911 1 ret = swr_init(s);
912
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (ret < 0)
913 return ret;
914 }
915
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 127 times.
127 if (!s->resampler->set_compensation){
916 return AVERROR(EINVAL);
917 }else{
918 127 return s->resampler->set_compensation(s->resample, sample_delta, compensation_distance);
919 }
920 }
921
922 223333 int64_t swr_next_pts(struct SwrContext *s, int64_t pts){
923
2/2
✓ Branch 0 taken 2041 times.
✓ Branch 1 taken 221292 times.
223333 if(pts == INT64_MIN)
924 2041 return s->outpts;
925
926
2/2
✓ Branch 0 taken 1435 times.
✓ Branch 1 taken 219857 times.
221292 if (s->firstpts == AV_NOPTS_VALUE)
927 1435 s->outpts = s->firstpts = pts;
928
929
2/2
✓ Branch 0 taken 220061 times.
✓ Branch 1 taken 1231 times.
221292 if(s->min_compensation >= FLT_MAX) {
930 220061 return (s->outpts = pts - swr_get_delay(s, s->in_sample_rate * (int64_t)s->out_sample_rate));
931 } else {
932 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;
933 1231 double fdelta = delta /(double)(s->in_sample_rate * (int64_t)s->out_sample_rate);
934
935
2/2
✓ Branch 0 taken 183 times.
✓ Branch 1 taken 1048 times.
1231 if(fabs(fdelta) > s->min_compensation) {
936
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){
937 int ret;
938
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);
939 52 else ret = swr_drop_output (s, -delta / s-> in_sample_rate);
940
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
56 if(ret<0){
941 av_log(s, AV_LOG_ERROR, "Failed to compensate for timestamp delta of %f\n", fdelta);
942 }
943
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) {
944 127 int duration = s->out_sample_rate * s->soft_compensation_duration;
945
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);
946 127 int comp = av_clipf(fdelta, -max_soft_compensation, max_soft_compensation) * duration ;
947 127 av_log(s, AV_LOG_VERBOSE, "compensating audio timestamp drift:%f compensation:%d in:%d\n", fdelta, comp, duration);
948 127 swr_set_compensation(s, comp, duration);
949 }
950 }
951
952 1231 return s->outpts;
953 }
954 }
955