GCC Code Coverage Report


Directory: avs_core/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 56.9% 66 / 0 / 116
Functions: 100.0% 5 / 0 / 5
Branches: 40.5% 47 / 0 / 116

convert/convert_audio.cpp
Line Branch Exec Source
1 // Avisynth v2.5. Copyright 2002 Ben Rudiak-Gould et al.
2 // http://avisynth.nl
3
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit
17 // http://www.gnu.org/copyleft/gpl.html .
18 //
19 // Linking Avisynth statically or dynamically with other modules is making a
20 // combined work based on Avisynth. Thus, the terms and conditions of the GNU
21 // General Public License cover the whole combination.
22 //
23 // As a special exception, the copyright holders of Avisynth give you
24 // permission to link Avisynth with independent modules that communicate with
25 // Avisynth solely through the interfaces defined in avisynth.h, regardless of the license
26 // terms of these independent modules, and to copy and distribute the
27 // resulting combined work under terms of your choice, provided that
28 // every copy of the combined work is accompanied by a complete copy of
29 // the source code of Avisynth (the version of Avisynth used to produce the
30 // combined work), being distributed under the terms of the GNU General
31 // Public License plus this exception. An independent module is a module
32 // which is not derived from or based on Avisynth, such as 3rd-party filters,
33 // import and export plugins, or graphical user interfaces.
34
35 // ConvertAudio classes
36 // Copyright (c) Klaus Post 2001 - 2004
37 // Copyright (c) Ian Brabham 2005
38 // Copyright (c) 2020 Xinyue Lu
39 // Copyright (c) 2021 pinterf
40
41 #include <avisynth.h>
42 #include <avs/alignment.h>
43 #include "convert_audio.h"
44 #if defined(AVS_BSD) || defined(AVS_MACOS)
45 #include <stdlib.h>
46 #else
47 #include <malloc.h>
48 #endif
49 #include <limits>
50
51 // There are two type parameters. Acceptable sample types and a prefered sample type.
52 // If the current clip is already one of the defined types in sampletype, this will be returned.
53 // If not, the current clip will be converted to the prefered type.
54 24 PClip ConvertAudio::Create(PClip clip, int sample_type, int prefered_type) {
55
5/6
✓ Branch 5 → 6 taken 24 times.
✗ Branch 5 → 10 not taken.
✓ Branch 9 → 10 taken 23 times.
✓ Branch 9 → 11 taken 1 time.
✓ Branch 12 → 13 taken 23 times.
✓ Branch 12 → 14 taken 1 time.
24 if ((!clip->GetVideoInfo().HasAudio()) || clip->GetVideoInfo().SampleType() & (sample_type | prefered_type)) {
56 // Sample type is already ok!
57 23 return clip;
58 } else
59
4/10
✓ Branch 15 → 16 taken 1 time.
✗ Branch 15 → 25 not taken.
✓ Branch 16 → 17 taken 1 time.
✗ Branch 16 → 23 not taken.
✓ Branch 17 → 18 taken 1 time.
✗ Branch 17 → 23 not taken.
✗ Branch 19 → 20 not taken.
✓ Branch 19 → 21 taken 1 time.
✗ Branch 26 → 27 not taken.
✗ Branch 26 → 28 not taken.
1 return new ConvertAudio(clip, prefered_type);
60 }
61
62 1 int __stdcall ConvertAudio::SetCacheHints(int cachehints, int frame_range) {
63 // We do pass cache requests upwards, to the next filter.
64 1 return child->SetCacheHints(cachehints, frame_range);
65 }
66
67 3 ConvertAudio::ConvertAudio(PClip _clip, int _sample_type)
68
2/4
✓ Branch 2 → 3 taken 3 times.
✗ Branch 2 → 50 not taken.
✓ Branch 3 → 4 taken 3 times.
✗ Branch 3 → 48 not taken.
3 : GenericVideoFilter(_clip) {
69 3 dst_format = _sample_type;
70
1/2
✓ Branch 5 → 6 taken 3 times.
✗ Branch 5 → 51 not taken.
3 src_format = vi.SampleType();
71 // Set up convertion matrix
72
1/2
✓ Branch 6 → 7 taken 3 times.
✗ Branch 6 → 51 not taken.
3 src_bps = vi.BytesPerChannelSample(); // Store old size
73 3 vi.sample_type = dst_format;
74 3 tempbuffer_size = 0;
75
76 #define PAIR(src, dst) ((src << 16) | dst)
77
2/21
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 9 not taken.
✗ Branch 7 → 10 not taken.
✗ Branch 7 → 11 not taken.
✗ Branch 7 → 12 not taken.
✗ Branch 7 → 13 not taken.
✗ Branch 7 → 14 not taken.
✗ Branch 7 → 15 not taken.
✗ Branch 7 → 16 not taken.
✗ Branch 7 → 17 not taken.
✗ Branch 7 → 18 not taken.
✗ Branch 7 → 19 not taken.
✗ Branch 7 → 20 not taken.
✗ Branch 7 → 21 not taken.
✗ Branch 7 → 22 not taken.
✗ Branch 7 → 23 not taken.
✓ Branch 7 → 24 taken 1 time.
✓ Branch 7 → 25 taken 2 times.
✗ Branch 7 → 26 not taken.
✗ Branch 7 → 27 not taken.
✗ Branch 7 → 28 not taken.
3 switch(PAIR(src_format, dst_format)) {
78 case PAIR(SAMPLE_INT32, SAMPLE_INT16): convert_c = convert32To16; break;
79 case PAIR(SAMPLE_INT16, SAMPLE_INT32): convert_c = convert16To32; break;
80 case PAIR(SAMPLE_INT32, SAMPLE_INT8 ): convert_c = convert32To8; break;
81 case PAIR(SAMPLE_INT8 , SAMPLE_INT32): convert_c = convert8To32; break;
82 case PAIR(SAMPLE_INT16, SAMPLE_INT8 ): convert_c = convert16To8; break;
83 case PAIR(SAMPLE_INT8 , SAMPLE_INT16): convert_c = convert8To16; break;
84 case PAIR(SAMPLE_FLOAT, SAMPLE_INT24): two_stage = true; // no-break;
85 case PAIR(SAMPLE_INT32, SAMPLE_INT24): convert_c = convert32To24; break;
86 case PAIR(SAMPLE_INT24, SAMPLE_FLOAT): two_stage = true; // no-break;
87 case PAIR(SAMPLE_INT24, SAMPLE_INT32): convert_c = convert24To32; break;
88 case PAIR(SAMPLE_INT24, SAMPLE_INT16): convert_c = convert24To16; break;
89 case PAIR(SAMPLE_INT16, SAMPLE_INT24): convert_c = convert16To24; break;
90 case PAIR(SAMPLE_INT24, SAMPLE_INT8 ): convert_c = convert24To8; break;
91 case PAIR(SAMPLE_INT8 , SAMPLE_INT24): convert_c = convert8To24; break;
92 case PAIR(SAMPLE_INT8 , SAMPLE_FLOAT): convert_c = convert8ToFLT; break;
93 case PAIR(SAMPLE_FLOAT, SAMPLE_INT8): convert_c = convertFLTTo8; break;
94 1 case PAIR(SAMPLE_INT16, SAMPLE_FLOAT): convert_c = convert16ToFLT; break;
95 2 case PAIR(SAMPLE_FLOAT, SAMPLE_INT16): convert_c = convertFLTTo16; break;
96 case PAIR(SAMPLE_INT32, SAMPLE_FLOAT): convert_c = convert32ToFLT; break;
97 case PAIR(SAMPLE_FLOAT, SAMPLE_INT32): convert_c = convertFLTTo32; break;
98 }
99 #ifdef INTEL_INTRINSICS
100
2/19
✗ Branch 28 → 29 not taken.
✗ Branch 28 → 30 not taken.
✗ Branch 28 → 31 not taken.
✗ Branch 28 → 32 not taken.
✗ Branch 28 → 33 not taken.
✗ Branch 28 → 34 not taken.
✗ Branch 28 → 35 not taken.
✗ Branch 28 → 36 not taken.
✗ Branch 28 → 37 not taken.
✗ Branch 28 → 38 not taken.
✗ Branch 28 → 39 not taken.
✗ Branch 28 → 40 not taken.
✗ Branch 28 → 41 not taken.
✗ Branch 28 → 42 not taken.
✓ Branch 28 → 43 taken 1 time.
✓ Branch 28 → 44 taken 2 times.
✗ Branch 28 → 45 not taken.
✗ Branch 28 → 46 not taken.
✗ Branch 28 → 47 not taken.
3 switch(PAIR(src_format, dst_format)) {
101 case PAIR(SAMPLE_INT32, SAMPLE_INT16): convert_sse2 = convert32To16_SSE2; convert_avx2 = convert32To16_AVX2; break;
102 case PAIR(SAMPLE_INT16, SAMPLE_INT32): convert_sse2 = convert16To32_SSE2; convert_avx2 = convert16To32_AVX2; break;
103 case PAIR(SAMPLE_INT32, SAMPLE_INT8 ): convert_sse2 = convert32To8_SSE2; break;
104 case PAIR(SAMPLE_INT8 , SAMPLE_INT32): convert_sse2 = convert8To32_SSE2; break;
105 case PAIR(SAMPLE_INT16, SAMPLE_INT8 ): convert_sse2 = convert16To8_SSE2; break;
106 case PAIR(SAMPLE_INT8 , SAMPLE_INT16): convert_sse2 = convert8To16_SSE2; break;
107 case PAIR(SAMPLE_FLOAT, SAMPLE_INT24):
108 case PAIR(SAMPLE_INT32, SAMPLE_INT24): convert_ssse3 = convert32To24_SSSE3; break;
109 case PAIR(SAMPLE_INT24, SAMPLE_FLOAT):
110 case PAIR(SAMPLE_INT24, SAMPLE_INT32): convert_ssse3 = convert24To32_SSSE3; break;
111 case PAIR(SAMPLE_INT24, SAMPLE_INT16): convert_ssse3 = convert24To16_SSSE3; break;
112 case PAIR(SAMPLE_INT16, SAMPLE_INT24): convert_ssse3 = convert16To24_SSSE3; break;
113 case PAIR(SAMPLE_INT24, SAMPLE_INT8 ): convert_ssse3 = convert24To8_SSSE3; break;
114 case PAIR(SAMPLE_INT8 , SAMPLE_INT24): convert_ssse3 = convert8To24_SSSE3; break;
115 case PAIR(SAMPLE_INT8 , SAMPLE_FLOAT): convert_sse41 = convert8ToFLT_SSE41; convert_avx2 = convert8ToFLT_AVX2; break;
116 case PAIR(SAMPLE_FLOAT, SAMPLE_INT8) : convert_sse2 = convertFLTTo8_SSE2; convert_avx2 = convertFLTTo8_AVX2; break;
117 1 case PAIR(SAMPLE_INT16, SAMPLE_FLOAT): convert_sse41 = convert16ToFLT_SSE41; convert_avx2 = convert16ToFLT_AVX2; break;
118 2 case PAIR(SAMPLE_FLOAT, SAMPLE_INT16): convert_sse2 = convertFLTTo16_SSE2; convert_avx2 = convertFLTTo16_AVX2; break;
119 case PAIR(SAMPLE_INT32, SAMPLE_FLOAT): convert_sse2 = convert32ToFLT_SSE2; convert_avx2 = convert32ToFLT_AVX2; break;
120 case PAIR(SAMPLE_FLOAT, SAMPLE_INT32): convert_sse41 = convertFLTTo32_SSE41; convert_avx2 = convertFLTTo32_AVX2; break;
121 }
122 #endif
123 #undef PAIR
124 3 }
125
126 4 ConvertAudio::~ConvertAudio() {
127
1/2
✓ Branch 2 → 3 taken 3 times.
✗ Branch 2 → 5 not taken.
3 if (tempbuffer_size) {
128 3 avs_free(tempbuffer);
129 3 tempbuffer_size = 0;
130 }
131 4 }
132
133 3 void __stdcall ConvertAudio::GetAudio(void *buf, int64_t start, int64_t count, IScriptEnvironment *env) {
134
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 6 taken 3 times.
3 if (src_format == dst_format) {
135 // Shouldn't happen, but just in case
136 child->GetAudio(buf, start, count, env);
137 return;
138 }
139
140 3 int channels = vi.AudioChannels();
141
142
1/2
✓ Branch 7 → 8 taken 3 times.
✗ Branch 7 → 27 not taken.
3 if (tempbuffer_size < count) {
143
3/6
✓ Branch 8 → 9 taken 3 times.
✗ Branch 8 → 11 not taken.
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 3 times.
✗ Branch 13 → 14 not taken.
✓ Branch 13 → 15 taken 3 times.
3 if (count < 0 || count > std::numeric_limits<int>::max())
144 env->ThrowError("ConvertAudio: audio count is too large.");
145
146 3 const size_t sample_count = static_cast<size_t>(count);
147 3 const size_t bytes_per_sample = static_cast<size_t>(src_bps) * static_cast<size_t>(channels);
148
149
3/6
✓ Branch 15 → 16 taken 3 times.
✗ Branch 15 → 18 not taken.
✗ Branch 17 → 18 not taken.
✓ Branch 17 → 19 taken 3 times.
✗ Branch 20 → 21 not taken.
✓ Branch 20 → 22 taken 3 times.
3 if (bytes_per_sample == 0 || sample_count > std::numeric_limits<size_t>::max() / bytes_per_sample)
150 env->ThrowError("ConvertAudio: audio buffer size overflow.");
151
152 3 const size_t buffer_size = sample_count * bytes_per_sample;
153 3 char* new_tempbuffer = static_cast<char*>(avs_malloc(buffer_size, 16));
154
155
1/2
✗ Branch 23 → 24 not taken.
✓ Branch 23 → 25 taken 3 times.
3 if (!new_tempbuffer)
156 env->ThrowError("ConvertAudio: insufficient memory.");
157
158 3 avs_free(tempbuffer);
159 3 tempbuffer = new_tempbuffer;
160 3 tempbuffer_size = static_cast<int>(count);
161 }
162
163 3 child->GetAudio(tempbuffer, start, count, env);
164
165
1/2
✓ Branch 29 → 30 taken 3 times.
✗ Branch 29 → 54 not taken.
3 if (convert == nullptr) {
166 3 convert = convert_c;
167
2/2
✓ Branch 30 → 31 taken 2 times.
✓ Branch 30 → 32 taken 1 time.
3 convert_float = src_format == SAMPLE_FLOAT ? convertFLTTo32 : convert32ToFLT; // for two-stage
168 #ifdef INTEL_INTRINSICS
169 3 int cpu_flags = env->GetCPUFlags();
170
1/2
✓ Branch 34 → 35 taken 3 times.
✗ Branch 34 → 39 not taken.
3 if ((cpu_flags & CPUF_SSE2)) {
171
2/2
✓ Branch 35 → 36 taken 2 times.
✓ Branch 35 → 37 taken 1 time.
3 if (convert_sse2)
172 2 convert = convert_sse2;
173
2/2
✓ Branch 37 → 38 taken 1 time.
✓ Branch 37 → 39 taken 2 times.
3 if (src_format != SAMPLE_FLOAT)
174 1 convert_float = convert32ToFLT_SSE2;
175 }
176
1/2
✓ Branch 39 → 40 taken 3 times.
✗ Branch 39 → 42 not taken.
3 if ((cpu_flags & CPUF_SSSE3)) {
177
1/2
✗ Branch 40 → 41 not taken.
✓ Branch 40 → 42 taken 3 times.
3 if (convert_ssse3)
178 convert = convert_ssse3;
179 }
180
1/2
✓ Branch 42 → 43 taken 3 times.
✗ Branch 42 → 47 not taken.
3 if ((cpu_flags & CPUF_SSE4_1)) {
181
2/2
✓ Branch 43 → 44 taken 1 time.
✓ Branch 43 → 45 taken 2 times.
3 if (convert_sse41)
182 1 convert = convert_sse41;
183
2/2
✓ Branch 45 → 46 taken 2 times.
✓ Branch 45 → 47 taken 1 time.
3 if (src_format == SAMPLE_FLOAT)
184 2 convert_float = convertFLTTo32_SSE41;
185 }
186
1/2
✓ Branch 47 → 48 taken 3 times.
✗ Branch 47 → 54 not taken.
3 if ((cpu_flags & CPUF_AVX2)) {
187
1/2
✓ Branch 48 → 49 taken 3 times.
✗ Branch 48 → 50 not taken.
3 if (convert_avx2)
188 3 convert = convert_avx2;
189
2/2
✓ Branch 50 → 51 taken 2 times.
✓ Branch 50 → 52 taken 1 time.
3 convert_float = src_format == SAMPLE_FLOAT ? convertFLTTo32_AVX2 : convert32ToFLT_AVX2;
190 }
191 #endif
192 }
193
194 3 int sample_count = static_cast<int>(count * channels);
195
196 // Direct conversion cases
197
1/2
✓ Branch 54 → 55 taken 3 times.
✗ Branch 54 → 57 not taken.
3 if (!two_stage) {
198 3 convert(tempbuffer, buf, sample_count);
199 3 return;
200 }
201
202 // Floating point cases
203 if (src_format == SAMPLE_FLOAT) {
204 convert_float(tempbuffer, tempbuffer, sample_count);
205 convert(tempbuffer, buf, sample_count);
206 return;
207 }
208
209 if (dst_format == SAMPLE_FLOAT) {
210 convert(tempbuffer, buf, sample_count);
211 convert_float(buf, buf, sample_count);
212 return;
213 }
214 }
215