GCC Code Coverage Report


Directory: avs_core/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 55.1% 59 / 0 / 107
Functions: 100.0% 5 / 0 / 5
Branches: 39.4% 41 / 0 / 104

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
50 // There are two type parameters. Acceptable sample types and a prefered sample type.
51 // If the current clip is already one of the defined types in sampletype, this will be returned.
52 // If not, the current clip will be converted to the prefered type.
53 20 PClip ConvertAudio::Create(PClip clip, int sample_type, int prefered_type) {
54
5/6
✓ Branch 5 → 6 taken 20 times.
✗ Branch 5 → 10 not taken.
✓ Branch 9 → 10 taken 19 times.
✓ Branch 9 → 11 taken 1 time.
✓ Branch 12 → 13 taken 19 times.
✓ Branch 12 → 14 taken 1 time.
20 if ((!clip->GetVideoInfo().HasAudio()) || clip->GetVideoInfo().SampleType() & (sample_type | prefered_type)) {
55 // Sample type is already ok!
56 19 return clip;
57 } else
58
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);
59 }
60
61 1 int __stdcall ConvertAudio::SetCacheHints(int cachehints, int frame_range) {
62 // We do pass cache requests upwards, to the next filter.
63 1 return child->SetCacheHints(cachehints, frame_range);
64 }
65
66 3 ConvertAudio::ConvertAudio(PClip _clip, int _sample_type)
67
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) {
68 3 dst_format = _sample_type;
69
1/2
✓ Branch 5 → 6 taken 3 times.
✗ Branch 5 → 51 not taken.
3 src_format = vi.SampleType();
70 // Set up convertion matrix
71
1/2
✓ Branch 6 → 7 taken 3 times.
✗ Branch 6 → 51 not taken.
3 src_bps = vi.BytesPerChannelSample(); // Store old size
72 3 vi.sample_type = dst_format;
73 3 tempbuffer_size = 0;
74
75 #define PAIR(src, dst) ((src << 16) | dst)
76
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)) {
77 case PAIR(SAMPLE_INT32, SAMPLE_INT16): convert_c = convert32To16; break;
78 case PAIR(SAMPLE_INT16, SAMPLE_INT32): convert_c = convert16To32; break;
79 case PAIR(SAMPLE_INT32, SAMPLE_INT8 ): convert_c = convert32To8; break;
80 case PAIR(SAMPLE_INT8 , SAMPLE_INT32): convert_c = convert8To32; break;
81 case PAIR(SAMPLE_INT16, SAMPLE_INT8 ): convert_c = convert16To8; break;
82 case PAIR(SAMPLE_INT8 , SAMPLE_INT16): convert_c = convert8To16; break;
83 case PAIR(SAMPLE_FLOAT, SAMPLE_INT24): two_stage = true; // no-break;
84 case PAIR(SAMPLE_INT32, SAMPLE_INT24): convert_c = convert32To24; break;
85 case PAIR(SAMPLE_INT24, SAMPLE_FLOAT): two_stage = true; // no-break;
86 case PAIR(SAMPLE_INT24, SAMPLE_INT32): convert_c = convert24To32; break;
87 case PAIR(SAMPLE_INT24, SAMPLE_INT16): convert_c = convert24To16; break;
88 case PAIR(SAMPLE_INT16, SAMPLE_INT24): convert_c = convert16To24; break;
89 case PAIR(SAMPLE_INT24, SAMPLE_INT8 ): convert_c = convert24To8; break;
90 case PAIR(SAMPLE_INT8 , SAMPLE_INT24): convert_c = convert8To24; break;
91 case PAIR(SAMPLE_INT8 , SAMPLE_FLOAT): convert_c = convert8ToFLT; break;
92 case PAIR(SAMPLE_FLOAT, SAMPLE_INT8): convert_c = convertFLTTo8; break;
93 1 case PAIR(SAMPLE_INT16, SAMPLE_FLOAT): convert_c = convert16ToFLT; break;
94 2 case PAIR(SAMPLE_FLOAT, SAMPLE_INT16): convert_c = convertFLTTo16; break;
95 case PAIR(SAMPLE_INT32, SAMPLE_FLOAT): convert_c = convert32ToFLT; break;
96 case PAIR(SAMPLE_FLOAT, SAMPLE_INT32): convert_c = convertFLTTo32; break;
97 }
98 #ifdef INTEL_INTRINSICS
99
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)) {
100 case PAIR(SAMPLE_INT32, SAMPLE_INT16): convert_sse2 = convert32To16_SSE2; convert_avx2 = convert32To16_AVX2; break;
101 case PAIR(SAMPLE_INT16, SAMPLE_INT32): convert_sse2 = convert16To32_SSE2; convert_avx2 = convert16To32_AVX2; break;
102 case PAIR(SAMPLE_INT32, SAMPLE_INT8 ): convert_sse2 = convert32To8_SSE2; break;
103 case PAIR(SAMPLE_INT8 , SAMPLE_INT32): convert_sse2 = convert8To32_SSE2; break;
104 case PAIR(SAMPLE_INT16, SAMPLE_INT8 ): convert_sse2 = convert16To8_SSE2; break;
105 case PAIR(SAMPLE_INT8 , SAMPLE_INT16): convert_sse2 = convert8To16_SSE2; break;
106 case PAIR(SAMPLE_FLOAT, SAMPLE_INT24):
107 case PAIR(SAMPLE_INT32, SAMPLE_INT24): convert_ssse3 = convert32To24_SSSE3; break;
108 case PAIR(SAMPLE_INT24, SAMPLE_FLOAT):
109 case PAIR(SAMPLE_INT24, SAMPLE_INT32): convert_ssse3 = convert24To32_SSSE3; break;
110 case PAIR(SAMPLE_INT24, SAMPLE_INT16): convert_ssse3 = convert24To16_SSSE3; break;
111 case PAIR(SAMPLE_INT16, SAMPLE_INT24): convert_ssse3 = convert16To24_SSSE3; break;
112 case PAIR(SAMPLE_INT24, SAMPLE_INT8 ): convert_ssse3 = convert24To8_SSSE3; break;
113 case PAIR(SAMPLE_INT8 , SAMPLE_INT24): convert_ssse3 = convert8To24_SSSE3; break;
114 case PAIR(SAMPLE_INT8 , SAMPLE_FLOAT): convert_sse41 = convert8ToFLT_SSE41; convert_avx2 = convert8ToFLT_AVX2; break;
115 case PAIR(SAMPLE_FLOAT, SAMPLE_INT8) : convert_sse2 = convertFLTTo8_SSE2; convert_avx2 = convertFLTTo8_AVX2; break;
116 1 case PAIR(SAMPLE_INT16, SAMPLE_FLOAT): convert_sse41 = convert16ToFLT_SSE41; convert_avx2 = convert16ToFLT_AVX2; break;
117 2 case PAIR(SAMPLE_FLOAT, SAMPLE_INT16): convert_sse2 = convertFLTTo16_SSE2; convert_avx2 = convertFLTTo16_AVX2; break;
118 case PAIR(SAMPLE_INT32, SAMPLE_FLOAT): convert_sse2 = convert32ToFLT_SSE2; convert_avx2 = convert32ToFLT_AVX2; break;
119 case PAIR(SAMPLE_FLOAT, SAMPLE_INT32): convert_sse41 = convertFLTTo32_SSE41; convert_avx2 = convertFLTTo32_AVX2; break;
120 }
121 #endif
122 #undef PAIR
123 3 }
124
125 4 ConvertAudio::~ConvertAudio() {
126
1/2
✓ Branch 2 → 3 taken 3 times.
✗ Branch 2 → 5 not taken.
3 if (tempbuffer_size) {
127 3 avs_free(tempbuffer);
128 3 tempbuffer_size = 0;
129 }
130 4 }
131
132 3 void __stdcall ConvertAudio::GetAudio(void *buf, int64_t start, int64_t count, IScriptEnvironment *env) {
133
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 6 taken 3 times.
3 if (src_format == dst_format) {
134 // Shouldn't happen, but just in case
135 child->GetAudio(buf, start, count, env);
136 return;
137 }
138
139 3 int channels = vi.AudioChannels();
140
141
1/2
✓ Branch 7 → 8 taken 3 times.
✗ Branch 7 → 12 not taken.
3 if (tempbuffer_size < count) {
142
1/2
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 10 taken 3 times.
3 if (tempbuffer_size)
143 avs_free(tempbuffer);
144 3 tempbuffer = (char *)avs_malloc((int)count * src_bps * channels, 16);
145 3 tempbuffer_size = (int)count;
146 }
147
148 3 child->GetAudio(tempbuffer, start, count, env);
149
150
1/2
✓ Branch 14 → 15 taken 3 times.
✗ Branch 14 → 39 not taken.
3 if (convert == nullptr) {
151 3 convert = convert_c;
152
2/2
✓ Branch 15 → 16 taken 2 times.
✓ Branch 15 → 17 taken 1 time.
3 convert_float = src_format == SAMPLE_FLOAT ? convertFLTTo32 : convert32ToFLT; // for two-stage
153 #ifdef INTEL_INTRINSICS
154 3 int cpu_flags = env->GetCPUFlags();
155
1/2
✓ Branch 19 → 20 taken 3 times.
✗ Branch 19 → 24 not taken.
3 if ((cpu_flags & CPUF_SSE2)) {
156
2/2
✓ Branch 20 → 21 taken 2 times.
✓ Branch 20 → 22 taken 1 time.
3 if (convert_sse2)
157 2 convert = convert_sse2;
158
2/2
✓ Branch 22 → 23 taken 1 time.
✓ Branch 22 → 24 taken 2 times.
3 if (src_format != SAMPLE_FLOAT)
159 1 convert_float = convert32ToFLT_SSE2;
160 }
161
1/2
✓ Branch 24 → 25 taken 3 times.
✗ Branch 24 → 27 not taken.
3 if ((cpu_flags & CPUF_SSSE3)) {
162
1/2
✗ Branch 25 → 26 not taken.
✓ Branch 25 → 27 taken 3 times.
3 if (convert_ssse3)
163 convert = convert_ssse3;
164 }
165
1/2
✓ Branch 27 → 28 taken 3 times.
✗ Branch 27 → 32 not taken.
3 if ((cpu_flags & CPUF_SSE4_1)) {
166
2/2
✓ Branch 28 → 29 taken 1 time.
✓ Branch 28 → 30 taken 2 times.
3 if (convert_sse41)
167 1 convert = convert_sse41;
168
2/2
✓ Branch 30 → 31 taken 2 times.
✓ Branch 30 → 32 taken 1 time.
3 if (src_format == SAMPLE_FLOAT)
169 2 convert_float = convertFLTTo32_SSE41;
170 }
171
1/2
✓ Branch 32 → 33 taken 3 times.
✗ Branch 32 → 39 not taken.
3 if ((cpu_flags & CPUF_AVX2)) {
172
1/2
✓ Branch 33 → 34 taken 3 times.
✗ Branch 33 → 35 not taken.
3 if (convert_avx2)
173 3 convert = convert_avx2;
174
2/2
✓ Branch 35 → 36 taken 2 times.
✓ Branch 35 → 37 taken 1 time.
3 convert_float = src_format == SAMPLE_FLOAT ? convertFLTTo32_AVX2 : convert32ToFLT_AVX2;
175 }
176 #endif
177 }
178
179 3 int sample_count = static_cast<int>(count * channels);
180
181 // Direct conversion cases
182
1/2
✓ Branch 39 → 40 taken 3 times.
✗ Branch 39 → 42 not taken.
3 if (!two_stage) {
183 3 convert(tempbuffer, buf, sample_count);
184 3 return;
185 }
186
187 // Floating point cases
188 if (src_format == SAMPLE_FLOAT) {
189 convert_float(tempbuffer, tempbuffer, sample_count);
190 convert(tempbuffer, buf, sample_count);
191 return;
192 }
193
194 if (dst_format == SAMPLE_FLOAT) {
195 convert(tempbuffer, buf, sample_count);
196 convert_float(buf, buf, sample_count);
197 return;
198 }
199 }
200