├── .editorconfig
├── .gitignore
├── Average.sln
├── Average
├── Average.vcxproj
├── Average.vcxproj.filters
├── CMakeLists.txt
├── Files.cmake
├── average.cpp
├── average.rc
├── average_avx.cpp
├── average_avx.h
├── average_avx2.cpp
├── average_avx2.h
├── avisynth.h
└── avs
│ ├── alignment.h
│ ├── capi.h
│ ├── config.h
│ ├── cpuid.h
│ ├── filesystem.h
│ ├── minmax.h
│ ├── posix.h
│ ├── types.h
│ └── win.h
├── CMakeLists.txt
├── LICENSE
├── README.md
└── cmake_uninstall.cmake.in
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | # NOTE: editorconfig-core-c has a hardcoded limitation of 50 chars per .ini section name
4 |
5 | [*.{cpp,h,hpp,c,asm}]
6 | indent_style = space
7 | indent_size = 2
8 | trim_trailing_whitespace = true
9 | end_of_line = crlf
10 | insert_final_newline = true
11 |
12 | [*.md]
13 | indent_style = space
14 | trim_trailing_whitespace = false
15 |
16 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | CMakeCache.txt
2 | CMakeFiles/*
3 |
4 | #cmake generated files
5 | cmake_install.cmake
6 | cmake_uninstall.cmake
7 | generate.stamp
8 | generate.stamp.depend
9 | makefile
10 |
11 | #make
12 | install_manifest.txt
13 |
14 | ## Ignore Visual Studio temporary files, build results, and
15 | ## files generated by popular Visual Studio add-ons.
16 | ##
17 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
18 |
19 | # User-specific files
20 | *.rsuser
21 | *.suo
22 | *.user
23 | *.userosscache
24 | *.sln.docstates
25 |
26 | # User-specific files (MonoDevelop/Xamarin Studio)
27 | *.userprefs
28 |
29 | # Mono auto generated files
30 | mono_crash.*
31 |
32 | # Build results
33 | build/
34 | [Dd]ebug/
35 | [Dd]ebugPublic/
36 | [Rr]elease/
37 | [Rr]eleases/
38 | [Rr]elease Clang/
39 | [Rr]eleases/
40 | x64/
41 | x86/
42 | [Aa][Rr][Mm]/
43 | [Aa][Rr][Mm]64/
44 | bld/
45 | [Bb]in/
46 | [Oo]bj/
47 | [Ll]og/
48 | [Ll]ogs/
49 |
50 | # Visual Studio 2015/2017 cache/options directory
51 | .vs/
52 | # Uncomment if you have tasks that create the project's static files in wwwroot
53 | #wwwroot/
54 |
55 | # Visual Studio 2017 auto generated files
56 | Generated\ Files/
57 |
58 | # MSTest test Results
59 | [Tt]est[Rr]esult*/
60 | [Bb]uild[Ll]og.*
61 |
62 | # NUnit
63 | *.VisualState.xml
64 | TestResult.xml
65 | nunit-*.xml
66 |
67 | # Build Results of an ATL Project
68 | [Dd]ebugPS/
69 | [Rr]eleasePS/
70 | dlldata.c
71 |
72 | # Benchmark Results
73 | BenchmarkDotNet.Artifacts/
74 |
75 | # .NET Core
76 | project.lock.json
77 | project.fragment.lock.json
78 | artifacts/
79 |
80 | # StyleCop
81 | StyleCopReport.xml
82 |
83 | # Files built by Visual Studio
84 | *_i.c
85 | *_p.c
86 | *_h.h
87 | *.ilk
88 | *.meta
89 | *.obj
90 | *.iobj
91 | *.pch
92 | *.pdb
93 | *.ipdb
94 | *.pgc
95 | *.pgd
96 | *.rsp
97 | *.sbr
98 | *.tlb
99 | *.tli
100 | *.tlh
101 | *.tmp
102 | *.tmp_proj
103 | *_wpftmp.csproj
104 | *.log
105 | *.vspscc
106 | *.vssscc
107 | .builds
108 | *.pidb
109 | *.svclog
110 | *.scc
111 |
112 | # Chutzpah Test files
113 | _Chutzpah*
114 |
115 | # Visual C++ cache files
116 | ipch/
117 | *.aps
118 | *.ncb
119 | *.opendb
120 | *.opensdf
121 | *.sdf
122 | *.cachefile
123 | *.VC.db
124 | *.VC.VC.opendb
125 |
126 | # Visual Studio profiler
127 | *.psess
128 | *.vsp
129 | *.vspx
130 | *.sap
131 |
132 | # Visual Studio Trace Files
133 | *.e2e
134 |
135 | # TFS 2012 Local Workspace
136 | $tf/
137 |
138 | # Guidance Automation Toolkit
139 | *.gpState
140 |
141 | # ReSharper is a .NET coding add-in
142 | _ReSharper*/
143 | *.[Rr]e[Ss]harper
144 | *.DotSettings.user
145 |
146 | # TeamCity is a build add-in
147 | _TeamCity*
148 |
149 | # DotCover is a Code Coverage Tool
150 | *.dotCover
151 |
152 | # AxoCover is a Code Coverage Tool
153 | .axoCover/*
154 | !.axoCover/settings.json
155 |
156 | # Visual Studio code coverage results
157 | *.coverage
158 | *.coveragexml
159 |
160 | # NCrunch
161 | _NCrunch_*
162 | .*crunch*.local.xml
163 | nCrunchTemp_*
164 |
165 | # MightyMoose
166 | *.mm.*
167 | AutoTest.Net/
168 |
169 | # Web workbench (sass)
170 | .sass-cache/
171 |
172 | # Installshield output folder
173 | [Ee]xpress/
174 |
175 | # DocProject is a documentation generator add-in
176 | DocProject/buildhelp/
177 | DocProject/Help/*.HxT
178 | DocProject/Help/*.HxC
179 | DocProject/Help/*.hhc
180 | DocProject/Help/*.hhk
181 | DocProject/Help/*.hhp
182 | DocProject/Help/Html2
183 | DocProject/Help/html
184 |
185 | # Click-Once directory
186 | publish/
187 |
188 | # Publish Web Output
189 | *.[Pp]ublish.xml
190 | *.azurePubxml
191 | # Note: Comment the next line if you want to checkin your web deploy settings,
192 | # but database connection strings (with potential passwords) will be unencrypted
193 | *.pubxml
194 | *.publishproj
195 |
196 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
197 | # checkin your Azure Web App publish settings, but sensitive information contained
198 | # in these scripts will be unencrypted
199 | PublishScripts/
200 |
201 | # NuGet Packages
202 | *.nupkg
203 | # NuGet Symbol Packages
204 | *.snupkg
205 | # The packages folder can be ignored because of Package Restore
206 | **/[Pp]ackages/*
207 | # except build/, which is used as an MSBuild target.
208 | !**/[Pp]ackages/build/
209 | # Uncomment if necessary however generally it will be regenerated when needed
210 | #!**/[Pp]ackages/repositories.config
211 | # NuGet v3's project.json files produces more ignorable files
212 | *.nuget.props
213 | *.nuget.targets
214 |
215 | # Microsoft Azure Build Output
216 | csx/
217 | *.build.csdef
218 |
219 | # Microsoft Azure Emulator
220 | ecf/
221 | rcf/
222 |
223 | # Windows Store app package directories and files
224 | AppPackages/
225 | BundleArtifacts/
226 | Package.StoreAssociation.xml
227 | _pkginfo.txt
228 | *.appx
229 | *.appxbundle
230 | *.appxupload
231 |
232 | # Visual Studio cache files
233 | # files ending in .cache can be ignored
234 | *.[Cc]ache
235 | # but keep track of directories ending in .cache
236 | !?*.[Cc]ache/
237 |
238 | # Others
239 | ClientBin/
240 | ~$*
241 | *~
242 | *.dbmdl
243 | *.dbproj.schemaview
244 | *.jfm
245 | *.pfx
246 | *.publishsettings
247 | orleans.codegen.cs
248 |
249 | # Including strong name files can present a security risk
250 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
251 | #*.snk
252 |
253 | # Since there are multiple workflows, uncomment next line to ignore bower_components
254 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
255 | #bower_components/
256 |
257 | # RIA/Silverlight projects
258 | Generated_Code/
259 |
260 | # Backup & report files from converting an old project file
261 | # to a newer Visual Studio version. Backup files are not needed,
262 | # because we have git ;-)
263 | _UpgradeReport_Files/
264 | Backup*/
265 | UpgradeLog*.XML
266 | UpgradeLog*.htm
267 | ServiceFabricBackup/
268 | *.rptproj.bak
269 |
270 | # SQL Server files
271 | *.mdf
272 | *.ldf
273 | *.ndf
274 |
275 | # Business Intelligence projects
276 | *.rdl.data
277 | *.bim.layout
278 | *.bim_*.settings
279 | *.rptproj.rsuser
280 | *- [Bb]ackup.rdl
281 | *- [Bb]ackup ([0-9]).rdl
282 | *- [Bb]ackup ([0-9][0-9]).rdl
283 |
284 | # Microsoft Fakes
285 | FakesAssemblies/
286 |
287 | # GhostDoc plugin setting file
288 | *.GhostDoc.xml
289 |
290 | # Node.js Tools for Visual Studio
291 | .ntvs_analysis.dat
292 | node_modules/
293 |
294 | # Visual Studio 6 build log
295 | *.plg
296 |
297 | # Visual Studio 6 workspace options file
298 | *.opt
299 |
300 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
301 | *.vbw
302 |
303 | # Visual Studio LightSwitch build output
304 | **/*.HTMLClient/GeneratedArtifacts
305 | **/*.DesktopClient/GeneratedArtifacts
306 | **/*.DesktopClient/ModelManifest.xml
307 | **/*.Server/GeneratedArtifacts
308 | **/*.Server/ModelManifest.xml
309 | _Pvt_Extensions
310 |
311 | # Paket dependency manager
312 | .paket/paket.exe
313 | paket-files/
314 |
315 | # FAKE - F# Make
316 | .fake/
317 |
318 | # CodeRush personal settings
319 | .cr/personal
320 |
321 | # Python Tools for Visual Studio (PTVS)
322 | __pycache__/
323 | *.pyc
324 |
325 | # Cake - Uncomment if you are using it
326 | # tools/**
327 | # !tools/packages.config
328 |
329 | # Tabs Studio
330 | *.tss
331 |
332 | # Telerik's JustMock configuration file
333 | *.jmconfig
334 |
335 | # BizTalk build output
336 | *.btp.cs
337 | *.btm.cs
338 | *.odx.cs
339 | *.xsd.cs
340 |
341 | # OpenCover UI analysis results
342 | OpenCover/
343 |
344 | # Azure Stream Analytics local run output
345 | ASALocalRun/
346 |
347 | # MSBuild Binary and Structured Log
348 | *.binlog
349 |
350 | # NVidia Nsight GPU debugger configuration file
351 | *.nvuser
352 |
353 | # MFractors (Xamarin productivity tool) working folder
354 | .mfractor/
355 |
356 | # Local History for Visual Studio
357 | .localhistory/
358 |
359 | # BeatPulse healthcheck temp database
360 | healthchecksdb
361 |
362 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
363 | MigrationBackup/
364 |
365 | # Ionide (cross platform F# VS Code tools) working folder
366 | .ionide/
367 |
--------------------------------------------------------------------------------
/Average.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.31727.386
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Average", "Average\Average.vcxproj", "{057699EE-4AAD-481A-97EA-881068AF6DB5}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Win32 = Debug|Win32
11 | Debug|x64 = Debug|x64
12 | Rel LLVM|Win32 = Rel LLVM|Win32
13 | Rel LLVM|x64 = Rel LLVM|x64
14 | Release|Win32 = Release|Win32
15 | Release|x64 = Release|x64
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {057699EE-4AAD-481A-97EA-881068AF6DB5}.Debug|Win32.ActiveCfg = Debug|Win32
19 | {057699EE-4AAD-481A-97EA-881068AF6DB5}.Debug|Win32.Build.0 = Debug|Win32
20 | {057699EE-4AAD-481A-97EA-881068AF6DB5}.Debug|x64.ActiveCfg = Debug|x64
21 | {057699EE-4AAD-481A-97EA-881068AF6DB5}.Debug|x64.Build.0 = Debug|x64
22 | {057699EE-4AAD-481A-97EA-881068AF6DB5}.Rel LLVM|Win32.ActiveCfg = Rel LLVM|Win32
23 | {057699EE-4AAD-481A-97EA-881068AF6DB5}.Rel LLVM|Win32.Build.0 = Rel LLVM|Win32
24 | {057699EE-4AAD-481A-97EA-881068AF6DB5}.Rel LLVM|x64.ActiveCfg = Rel LLVM|x64
25 | {057699EE-4AAD-481A-97EA-881068AF6DB5}.Rel LLVM|x64.Build.0 = Rel LLVM|x64
26 | {057699EE-4AAD-481A-97EA-881068AF6DB5}.Release|Win32.ActiveCfg = Release|Win32
27 | {057699EE-4AAD-481A-97EA-881068AF6DB5}.Release|Win32.Build.0 = Release|Win32
28 | {057699EE-4AAD-481A-97EA-881068AF6DB5}.Release|x64.ActiveCfg = Release|x64
29 | {057699EE-4AAD-481A-97EA-881068AF6DB5}.Release|x64.Build.0 = Release|x64
30 | EndGlobalSection
31 | GlobalSection(SolutionProperties) = preSolution
32 | HideSolutionNode = FALSE
33 | EndGlobalSection
34 | GlobalSection(ExtensibilityGlobals) = postSolution
35 | SolutionGuid = {175F9FC8-28B3-4088-BFC9-3BC55371EDAD}
36 | EndGlobalSection
37 | EndGlobal
38 |
--------------------------------------------------------------------------------
/Average/Average.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Debug
10 | x64
11 |
12 |
13 | Rel LLVM
14 | Win32
15 |
16 |
17 | Rel LLVM
18 | x64
19 |
20 |
21 | Release
22 | Win32
23 |
24 |
25 | Release
26 | x64
27 |
28 |
29 |
30 | {057699EE-4AAD-481A-97EA-881068AF6DB5}
31 | Average
32 | 10.0
33 |
34 |
35 |
36 | DynamicLibrary
37 | true
38 | v141_xp
39 | MultiByte
40 |
41 |
42 | DynamicLibrary
43 | true
44 | v141_xp
45 | MultiByte
46 |
47 |
48 | DynamicLibrary
49 | false
50 | v141_xp
51 | true
52 | MultiByte
53 |
54 |
55 | DynamicLibrary
56 | false
57 | ClangCL
58 | true
59 | MultiByte
60 |
61 |
62 | DynamicLibrary
63 | false
64 | v141_xp
65 | true
66 | MultiByte
67 |
68 |
69 | DynamicLibrary
70 | false
71 | ClangCL
72 | true
73 | MultiByte
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 | $(SolutionDir)Build\$(Platform)\$(Configuration)\
99 | $(SolutionDir)Build\$(Platform)\Temp\$(Configuration)\
100 |
101 |
102 | $(SolutionDir)Build\$(Platform)\$(Configuration)\
103 | $(SolutionDir)Build\$(Platform)\Temp\$(Configuration)\
104 |
105 |
106 | $(SolutionDir)Build\$(Platform)\$(Configuration)\
107 | $(SolutionDir)Build\$(Platform)\Temp\$(Configuration)\
108 |
109 |
110 | $(SolutionDir)Build\$(Platform)\$(Configuration)\
111 | $(SolutionDir)Build\$(Platform)\Temp\$(Configuration)\
112 |
113 |
114 | $(SolutionDir)Build\$(Platform)\$(Configuration)\
115 | $(SolutionDir)Build\$(Platform)\Temp\$(Configuration)\
116 |
117 |
118 | $(SolutionDir)Build\$(Platform)\$(Configuration)\
119 | $(SolutionDir)Build\$(Platform)\Temp\$(Configuration)\
120 |
121 |
122 |
123 | Level3
124 | Disabled
125 | true
126 | .\
127 | /Zc:threadSafeInit- %(AdditionalOptions)
128 | StreamingSIMDExtensions2
129 | stdcpp17
130 | _USING_V110_SDK71_;%(PreprocessorDefinitions);INTEL_INTRINSICS
131 |
132 |
133 | true
134 |
135 |
136 |
137 |
138 | Level3
139 | Disabled
140 | true
141 | .\
142 | /Zc:threadSafeInit- %(AdditionalOptions)
143 | stdcpp17
144 | _USING_V110_SDK71_;%(PreprocessorDefinitions);INTEL_INTRINSICS
145 |
146 |
147 | true
148 |
149 |
150 |
151 |
152 | Level3
153 | MaxSpeed
154 | true
155 | true
156 | true
157 | AssemblyAndSourceCode
158 | .\
159 | /Zc:threadSafeInit- %(AdditionalOptions)
160 | AnySuitable
161 | Speed
162 | false
163 | true
164 | StreamingSIMDExtensions2
165 | stdcpp17
166 | _USING_V110_SDK71_;%(PreprocessorDefinitions);INTEL_INTRINSICS
167 |
168 |
169 | true
170 | true
171 | true
172 |
173 |
174 |
175 |
176 | Level3
177 | MaxSpeed
178 | true
179 | true
180 | true
181 | NoListing
182 | .\
183 | /Zc:threadSafeInit- %(AdditionalOptions)
184 | AnySuitable
185 | Speed
186 | false
187 | true
188 | StreamingSIMDExtensions2
189 | stdcpp17
190 | _WINDLL;%(PreprocessorDefinitions);INTEL_INTRINSICS
191 |
192 |
193 | true
194 | true
195 | true
196 |
197 |
198 |
199 |
200 | Level3
201 | MaxSpeed
202 | true
203 | true
204 | true
205 | AssemblyAndSourceCode
206 | .\
207 | /Zc:threadSafeInit- %(AdditionalOptions)
208 | AnySuitable
209 | Speed
210 | false
211 | stdcpp17
212 | _USING_V110_SDK71_;%(PreprocessorDefinitions);INTEL_INTRINSICS
213 |
214 |
215 | true
216 | true
217 | true
218 |
219 |
220 |
221 |
222 | Level3
223 | MaxSpeed
224 | true
225 | true
226 | true
227 | AssemblyAndSourceCode
228 | .\
229 | /Zc:threadSafeInit- %(AdditionalOptions)
230 | AnySuitable
231 | Speed
232 | false
233 | stdcpp17
234 | _WINDLL;%(PreprocessorDefinitions);INTEL_INTRINSICS
235 |
236 |
237 | true
238 | true
239 | true
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 | AdvancedVectorExtensions
258 | AdvancedVectorExtensions
259 | AdvancedVectorExtensions
260 | AdvancedVectorExtensions
261 | AdvancedVectorExtensions
262 | AdvancedVectorExtensions
263 |
264 |
265 | AdvancedVectorExtensions2
266 | AdvancedVectorExtensions2
267 | AdvancedVectorExtensions2
268 | AdvancedVectorExtensions2
269 | AdvancedVectorExtensions2
270 | AdvancedVectorExtensions2
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
--------------------------------------------------------------------------------
/Average/Average.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Header Files
20 |
21 |
22 | Header Files
23 |
24 |
25 | Header Files
26 |
27 |
28 | Header Files
29 |
30 |
31 | Header Files
32 |
33 |
34 | Header Files
35 |
36 |
37 | Header Files
38 |
39 |
40 | Header Files
41 |
42 |
43 | Header Files
44 |
45 |
46 | Header Files
47 |
48 |
49 |
50 |
51 | Source Files
52 |
53 |
54 | Source Files
55 |
56 |
57 | Source Files
58 |
59 |
60 |
61 |
62 | Resource Files
63 |
64 |
65 |
--------------------------------------------------------------------------------
/Average/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # Visual Studio 2019 is supported from CMake 3.14.1
2 | # Tested generators:
3 | # "MinGW Makefiles": MSYS2/Mingw32 GCC 8.3 build
4 | # "Visual Studio 16 2019" optional platform generator Win32 and x64
5 | # "Visual Studio 16 2019" + LLVM 8.0 (clang) optional platform generator Win32 and x64
6 | CMAKE_MINIMUM_REQUIRED( VERSION 3.8.2 )
7 |
8 | set(PluginName "Average")
9 |
10 | if (NOT WIN32)
11 | string(TOLOWER "${PluginName}" PluginName)
12 | endif()
13 |
14 | set(ProjectName "${PluginName}")
15 | project(${ProjectName} LANGUAGES CXX)
16 |
17 | Include("Files.cmake")
18 |
19 | add_library(${PluginName} SHARED ${Average_Sources})
20 |
21 | set_target_properties(${PluginName} PROPERTIES "OUTPUT_NAME" "${PluginName}")
22 | if (MINGW)
23 | set_target_properties(${PluginName} PROPERTIES PREFIX "")
24 | set_target_properties(${PluginName} PROPERTIES IMPORT_PREFIX "")
25 | endif()
26 |
27 | IF(ENABLE_INTEL_SIMD)
28 | #require sse2, some other plugins may need to set sse4.1 for quick msvc->gcc porting
29 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DINTEL_INTRINSICS -msse2")
30 | ENDIF()
31 |
32 | # Automatically group source files according to directory structure
33 | foreach(FILE ${Average_Sources})
34 | get_filename_component(PARENT_DIR "${FILE}" PATH)
35 |
36 | string(REGEX REPLACE "(\\./)" "" GROUP "${PARENT_DIR}")
37 | string(REPLACE "/" "\\" GROUP "${GROUP}")
38 |
39 | # group into "Source Files" and "Header Files"
40 | if ("${FILE}" MATCHES ".*\\.cpp")
41 | set(GROUP "Source Files\\${GROUP}")
42 | elseif("${FILE}" MATCHES ".*\\.h")
43 | set(GROUP "Header Files\\${GROUP}")
44 | elseif("${FILE}" MATCHES ".*\\.asm")
45 | set(GROUP "Assembler Files\\${GROUP}")
46 | endif()
47 |
48 | source_group("${GROUP}" FILES "${FILE}")
49 | endforeach()
50 |
51 | if (MSVC_IDE)
52 | IF(CLANG_IN_VS STREQUAL "1")
53 | # special SSSE3 option for source files with *_ssse3.cpp pattern
54 | file(GLOB_RECURSE SRCS_SSSE3 "*_ssse3.cpp")
55 | set_source_files_properties(${SRCS_SSSE3} PROPERTIES COMPILE_FLAGS " -mssse3 ")
56 |
57 | # special SSE4.1 option for source files with *_sse41.cpp pattern
58 | file(GLOB_RECURSE SRCS_SSE41 "*_sse41.cpp")
59 | set_source_files_properties(${SRCS_SSE41} PROPERTIES COMPILE_FLAGS " -msse4.1 ")
60 |
61 | # special AVX option for source files with *_avx.cpp pattern
62 | file(GLOB_RECURSE SRCS_AVX "*_avx.cpp")
63 | set_source_files_properties(${SRCS_AVX} PROPERTIES COMPILE_FLAGS " -mavx ")
64 |
65 | # special AVX2 option for source files with *_avx2.cpp pattern
66 | file(GLOB_RECURSE SRCS_AVX2 "*_avx2.cpp")
67 | set_source_files_properties(${SRCS_AVX2} PROPERTIES COMPILE_FLAGS " -mavx2 -mfma ")
68 |
69 | # special AVX512 option for source files with *_avx512.cpp pattern
70 | file(GLOB_RECURSE SRCS_AVX512 "*_avx512.cpp")
71 | set_source_files_properties(${SRCS_AVX512} PROPERTIES COMPILE_FLAGS " -mavx512f -mavx512bw ")
72 | ELSE()
73 | # special AVX option for source files with *_avx.cpp pattern
74 | file(GLOB_RECURSE SRCS_AVX "*_avx.cpp")
75 | set_source_files_properties(${SRCS_AVX} PROPERTIES COMPILE_FLAGS " /arch:AVX ")
76 |
77 | # special AVX2 option for source files with *_avx2.cpp pattern
78 | file(GLOB_RECURSE SRCS_AVX2 "*_avx2.cpp")
79 | set_source_files_properties(${SRCS_AVX2} PROPERTIES COMPILE_FLAGS " /arch:AVX2 ")
80 |
81 | # special AVX512 option for source files with *_avx512.cpp pattern
82 | file(GLOB_RECURSE SRCS_AVX512 "*_avx512.cpp")
83 | set_source_files_properties(${SRCS_AVX512} PROPERTIES COMPILE_FLAGS " /arch:AVX512 ")
84 | ENDIF()
85 | else()
86 | # special SSSE3 option for source files with *_ssse3.cpp pattern
87 | file(GLOB_RECURSE SRCS_SSSE3 "*_ssse3.cpp")
88 | set_source_files_properties(${SRCS_SSSE3} PROPERTIES COMPILE_FLAGS " -mssse3 ")
89 |
90 | # special SSE4.1 option for source files with *_sse41.cpp pattern
91 | file(GLOB_RECURSE SRCS_SSE41 "*_sse41.cpp")
92 | set_source_files_properties(${SRCS_SSE41} PROPERTIES COMPILE_FLAGS " -msse4.1 ")
93 |
94 | # special AVX option for source files with *_avx.cpp pattern
95 | file(GLOB_RECURSE SRCS_AVX "*_avx.cpp")
96 | set_source_files_properties(${SRCS_AVX} PROPERTIES COMPILE_FLAGS " -mavx ")
97 |
98 | # special AVX2 option for source files with *_avx2.cpp pattern
99 | file(GLOB_RECURSE SRCS_AVX2 "*_avx2.cpp")
100 | set_source_files_properties(${SRCS_AVX2} PROPERTIES COMPILE_FLAGS " -mavx2 -mfma ")
101 |
102 | # special AVX512 option for source files with *_avx512.cpp pattern
103 | file(GLOB_RECURSE SRCS_AVX512 "*_avx512.cpp")
104 | set_source_files_properties(${SRCS_AVX512} PROPERTIES COMPILE_FLAGS " -mavx512f -mavx512bw ")
105 | endif()
106 |
107 |
108 | # Specify include directories
109 | target_include_directories(${ProjectName} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
110 | #dedicated include dir for avisynth.h
111 | #target_include_directories(${ProjectName} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
112 |
113 | # Windows DLL dependencies
114 | if (MSVC OR MINGW)
115 | target_link_libraries(${ProjectName} "uuid" "winmm" "vfw32" "msacm32" "gdi32" "user32" "advapi32" "ole32" "imagehlp")
116 | else()
117 | #non Windows
118 | target_link_libraries(${ProjectName})
119 | # "pthread" "dl"
120 | endif()
121 |
122 | include(GNUInstallDirs)
123 |
124 | INSTALL(TARGETS ${ProjectName}
125 | LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}/avisynth")
126 |
--------------------------------------------------------------------------------
/Average/Files.cmake:
--------------------------------------------------------------------------------
1 | FILE(GLOB Average_Sources RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
2 | "*.c"
3 | "*.cpp"
4 | "*.hpp"
5 | "*.h"
6 |
7 | "avs/*.h"
8 | )
9 |
10 | IF( MSVC OR MINGW )
11 | # Export definitions in general are not needed on x64 and only cause warnings,
12 | # unfortunately we still must need a .def file for some COM functions.
13 | # NO C interface for this plugin
14 | # if(CMAKE_SIZEOF_VOID_P EQUAL 8)
15 | # LIST(APPEND Convolution3D_Sources "Average64.def")
16 | # else()
17 | # LIST(APPEND Convolution3D_Sources "Average.def")
18 | # endif()
19 | ENDIF()
20 |
21 | IF( MSVC_IDE )
22 | # Ninja, unfortunately, seems to have some issues with using rc.exe
23 | LIST(APPEND Average_Sources "Average.rc")
24 | ENDIF()
25 |
--------------------------------------------------------------------------------
/Average/average.cpp:
--------------------------------------------------------------------------------
1 | #include "avisynth.h"
2 | #include "avs/alignment.h"
3 | #include
4 | #include
5 | #include
6 |
7 | #ifdef INTEL_INTRINSICS
8 | #include "average_avx.h"
9 | #include "average_avx2.h"
10 | #endif
11 |
12 | #ifdef INTEL_INTRINSICS
13 | #include "emmintrin.h"
14 | #endif
15 |
16 | #include
17 |
18 | #if defined(_WIN32) && !defined(INTEL_INTRINSICS)
19 | #error Forgot to set INTEL_INTRINSICS? Comment out this line if not
20 | #endif
21 |
22 | template
23 | static AVS_FORCEINLINE int static_clip(float val) {
24 | if (val > maximum) {
25 | return maximum;
26 | }
27 | if (val < minimum) {
28 | return minimum;
29 | }
30 | return (int)val;
31 | }
32 |
33 | template
34 | static AVS_FORCEINLINE void weighted_average_c(uint8_t *dstp, int dst_pitch, const uint8_t **src_pointers, int *src_pitches, float *weights, int frames_count, int width, int height) {
35 | // width is rowsize
36 | const int max_pixel_value = (sizeof(pixel_t) == 1) ? 255 : ((1 << bits_per_pixel) - 1);
37 |
38 | width /= sizeof(pixel_t);
39 |
40 | for (int y = 0; y < height; ++y) {
41 | for (int x = 0; x < width; ++x) {
42 | float acc = 0;
43 | for (int i = 0; i < frames_count; ++i) {
44 | acc += reinterpret_cast(src_pointers[i])[x] * weights[i];
45 | }
46 | if (sizeof(pixel_t) == 4)
47 | reinterpret_cast(dstp)[x] = acc;
48 | else
49 | reinterpret_cast(dstp)[x] = (pixel_t)(static_clip<0, max_pixel_value>(acc));
50 | }
51 |
52 | for (int i = 0; i < frames_count; ++i) {
53 | src_pointers[i] += src_pitches[i];
54 | }
55 | dstp += dst_pitch;
56 | }
57 | }
58 |
59 | #ifdef INTEL_INTRINSICS
60 | // fake _mm_packus_epi32 (orig is SSE4.1 only)
61 | static AVS_FORCEINLINE __m128i _MM_PACKUS_EPI32(__m128i a, __m128i b)
62 | {
63 | a = _mm_slli_epi32(a, 16);
64 | a = _mm_srai_epi32(a, 16);
65 | b = _mm_slli_epi32(b, 16);
66 | b = _mm_srai_epi32(b, 16);
67 | a = _mm_packs_epi32(a, b);
68 | return a;
69 | }
70 |
71 | template
72 | static inline void weighted_average_sse2(uint8_t *dstp, int dst_pitch, const uint8_t **src_pointers, int *src_pitches, float *weights, int frames_count, int width, int height) {
73 | // width is row_size
74 | int mod_width;
75 | if(sizeof(pixel_t) == 1)
76 | mod_width = width / 8 * 8;
77 | else
78 | mod_width = width / 16 * 16;
79 |
80 | const int sse_size = (sizeof(pixel_t) == 1) ? 8 : 16;
81 |
82 | const int max_pixel_value = (sizeof(pixel_t) == 1) ? 255 : ((1 << bits_per_pixel) - 1);
83 | __m128i pixel_limit;
84 | if (sizeof(pixel_t) == 2 && bits_per_pixel < 16)
85 | pixel_limit = _mm_set1_epi16((int16_t)max_pixel_value);
86 |
87 | __m128i zero = _mm_setzero_si128();
88 |
89 | for (int y = 0; y < height; ++y) {
90 | for (int x = 0; x < mod_width; x += sse_size) {
91 | __m128 acc_lo = _mm_setzero_ps();
92 | __m128 acc_hi = _mm_setzero_ps();
93 |
94 | for (int i = 0; i < frames_count; ++i) {
95 | __m128i src;
96 | if (sizeof(pixel_t) == 1)
97 | src = _mm_loadl_epi64(reinterpret_cast(src_pointers[i] + x));
98 | else
99 | src = _mm_load_si128(reinterpret_cast(src_pointers[i] + x));
100 | auto weight = _mm_set1_ps(weights[i]);
101 |
102 | if(sizeof(pixel_t) == 1)
103 | src = _mm_unpacklo_epi8(src, zero);
104 | auto src_lo_ps = _mm_cvtepi32_ps(_mm_unpacklo_epi16(src, zero));
105 | auto src_hi_ps = _mm_cvtepi32_ps(_mm_unpackhi_epi16(src, zero));
106 |
107 | auto weighted_lo = _mm_mul_ps(src_lo_ps, weight);
108 | auto weighted_hi = _mm_mul_ps(src_hi_ps, weight);
109 |
110 | acc_lo = _mm_add_ps(acc_lo, weighted_lo);
111 | acc_hi = _mm_add_ps(acc_hi, weighted_hi);
112 | }
113 | auto dst_lo = _mm_cvtps_epi32(acc_lo);
114 | auto dst_hi = _mm_cvtps_epi32(acc_hi);
115 |
116 | __m128i dst;
117 | if (sizeof(pixel_t) == 1) {
118 | dst = _mm_packs_epi32(dst_lo, dst_hi);
119 | dst = _mm_packus_epi16(dst, zero);
120 | }
121 | else if (sizeof(pixel_t) == 2) {
122 | if (bits_per_pixel < 16) {
123 | dst = _mm_packs_epi32(dst_lo, dst_hi); // no need for packus
124 | }
125 | else {
126 | dst = _MM_PACKUS_EPI32(dst_lo, dst_hi); // SSE2 friendly but slower
127 | }
128 | }
129 |
130 | if (sizeof(pixel_t) == 2 && bits_per_pixel < 16)
131 | dst = _mm_min_epi16(dst, pixel_limit); // no need for SSE4 epu16
132 |
133 | if(sizeof(pixel_t) == 1)
134 | _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp+x), dst);
135 | else
136 | _mm_store_si128(reinterpret_cast<__m128i*>(dstp + x), dst);
137 | }
138 |
139 | int start = mod_width / sizeof(pixel_t);
140 | int end = width / sizeof(pixel_t);
141 | for (int x = start; x < end; ++x) {
142 | float acc = 0;
143 | for (int i = 0; i < frames_count; ++i) {
144 | acc += reinterpret_cast(src_pointers[i])[x] * weights[i];
145 | }
146 | reinterpret_cast(dstp)[x] = static_clip<0, max_pixel_value>(acc);
147 | }
148 |
149 | for (int i = 0; i < frames_count; ++i) {
150 | src_pointers[i] += src_pitches[i];
151 | }
152 | dstp += dst_pitch;
153 | }
154 | }
155 |
156 | static inline void weighted_average_f_sse2(uint8_t *dstp, int dst_pitch, const uint8_t **src_pointers, int *src_pitches, float *weights, int frames_count, int width, int height) {
157 | // width is row_size
158 | int mod_width = width / 16 * 16;
159 |
160 | const int sse_size = 16;
161 |
162 | for (int y = 0; y < height; ++y) {
163 | for (int x = 0; x < mod_width; x += sse_size) {
164 | __m128 acc = _mm_setzero_ps();
165 |
166 | for (int i = 0; i < frames_count; ++i) {
167 | __m128 src;
168 | src = _mm_load_ps(reinterpret_cast(src_pointers[i] + x));
169 | auto weight = _mm_set1_ps(weights[i]);
170 |
171 | auto weighted = _mm_mul_ps(src, weight);
172 |
173 | acc = _mm_add_ps(acc, weighted);
174 | }
175 |
176 | _mm_store_ps(reinterpret_cast(dstp + x), acc);
177 | }
178 |
179 | for (int x = mod_width / 4; x < width / 4; ++x) {
180 | float acc = 0;
181 | for (int i = 0; i < frames_count; ++i) {
182 | acc += reinterpret_cast(src_pointers[i])[x] * weights[i];
183 | }
184 | reinterpret_cast(dstp)[x] = acc; // float: no clamping
185 | }
186 |
187 | for (int i = 0; i < frames_count; ++i) {
188 | src_pointers[i] += src_pitches[i];
189 | }
190 | dstp += dst_pitch;
191 | }
192 | }
193 |
194 |
195 | template
196 | static inline void weighted_average_int_sse2(uint8_t *dstp, int dst_pitch, const uint8_t **src_pointers, int *src_pitches, float *weights, int frames_count, int width, int height) {
197 | int16_t *int_weights = reinterpret_cast(alloca(frames_count*sizeof(int16_t)));
198 | for (int i = 0; i < frames_count; ++i) {
199 | int_weights[i] = static_cast((1 << 14) * weights[i]);
200 | }
201 | int mod8_width = width / 8 * 8;
202 | __m128i zero = _mm_setzero_si128();
203 |
204 | __m128i round_mask = _mm_set1_epi32(0x2000);
205 |
206 | bool even_frames = (frames_count % 2 != 0);
207 |
208 | if (frames_count_2_3_more == 2 || frames_count_2_3_more == 3) {
209 | for (int y = 0; y < height; ++y) {
210 | for (int x = 0; x < mod8_width; x += 8) {
211 | __m128i acc_lo = _mm_setzero_si128();
212 | __m128i acc_hi = _mm_setzero_si128();
213 |
214 | __m128i src = _mm_loadl_epi64(reinterpret_cast(src_pointers[0] + x));
215 | __m128i src2 = _mm_loadl_epi64(reinterpret_cast(src_pointers[1] + x));
216 | __m128i weight = _mm_set1_epi32(*reinterpret_cast(int_weights));
217 |
218 | src = _mm_unpacklo_epi8(src, zero);
219 | src2 = _mm_unpacklo_epi8(src2, zero);
220 | __m128i src_lo = _mm_unpacklo_epi16(src, src2);
221 | __m128i src_hi = _mm_unpackhi_epi16(src, src2);
222 |
223 | __m128i weighted_lo = _mm_madd_epi16(src_lo, weight);
224 | __m128i weighted_hi = _mm_madd_epi16(src_hi, weight);
225 |
226 | acc_lo = _mm_add_epi32(acc_lo, weighted_lo);
227 | acc_hi = _mm_add_epi32(acc_hi, weighted_hi);
228 |
229 | if (frames_count_2_3_more == 3) {
230 | __m128i src = _mm_loadl_epi64(reinterpret_cast(src_pointers[2] + x));
231 | __m128i weight = _mm_set1_epi32(int_weights[2]);
232 |
233 | src = _mm_unpacklo_epi8(src, zero);
234 | __m128i src_lo = _mm_unpacklo_epi16(src, zero);
235 | __m128i src_hi = _mm_unpackhi_epi16(src, zero);
236 |
237 | __m128i weighted_lo = _mm_madd_epi16(src_lo, weight);
238 | __m128i weighted_hi = _mm_madd_epi16(src_hi, weight);
239 |
240 | acc_lo = _mm_add_epi32(acc_lo, weighted_lo);
241 | acc_hi = _mm_add_epi32(acc_hi, weighted_hi);
242 | }
243 |
244 | acc_lo = _mm_add_epi32(acc_lo, round_mask);
245 | acc_hi = _mm_add_epi32(acc_hi, round_mask);
246 |
247 | __m128i dst_lo = _mm_srai_epi32(acc_lo, 14);
248 | __m128i dst_hi = _mm_srai_epi32(acc_hi, 14);
249 |
250 | __m128i dst = _mm_packs_epi32(dst_lo, dst_hi);
251 | dst = _mm_packus_epi16(dst, zero);
252 | _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp + x), dst);
253 | }
254 |
255 | for (int x = mod8_width; x < width; ++x) {
256 | float acc = 0;
257 | acc += src_pointers[0][x] * weights[0];
258 | acc += src_pointers[1][x] * weights[1];
259 | if (frames_count_2_3_more == 3)
260 | acc += src_pointers[2][x] * weights[2];
261 | dstp[x] = static_clip<0, 255>(acc);
262 | }
263 |
264 | src_pointers[0] += src_pitches[0];
265 | src_pointers[1] += src_pitches[1];
266 | if (frames_count_2_3_more == 3)
267 | src_pointers[2] += src_pitches[2];
268 | dstp += dst_pitch;
269 | }
270 | } else {
271 | // generic path
272 | for (int y = 0; y < height; ++y) {
273 | for (int x = 0; x < mod8_width; x += 8) {
274 | __m128i acc_lo = _mm_setzero_si128();
275 | __m128i acc_hi = _mm_setzero_si128();
276 |
277 | for (int i = 0; i < frames_count - 1; i += 2) {
278 | __m128i src = _mm_loadl_epi64(reinterpret_cast(src_pointers[i] + x));
279 | __m128i src2 = _mm_loadl_epi64(reinterpret_cast(src_pointers[i + 1] + x));
280 | __m128i weight = _mm_set1_epi32(*reinterpret_cast(int_weights + i));
281 |
282 | src = _mm_unpacklo_epi8(src, zero);
283 | src2 = _mm_unpacklo_epi8(src2, zero);
284 | __m128i src_lo = _mm_unpacklo_epi16(src, src2);
285 | __m128i src_hi = _mm_unpackhi_epi16(src, src2);
286 |
287 | __m128i weighted_lo = _mm_madd_epi16(src_lo, weight);
288 | __m128i weighted_hi = _mm_madd_epi16(src_hi, weight);
289 |
290 | acc_lo = _mm_add_epi32(acc_lo, weighted_lo);
291 | acc_hi = _mm_add_epi32(acc_hi, weighted_hi);
292 | }
293 |
294 | if (even_frames) {
295 | __m128i src = _mm_loadl_epi64(reinterpret_cast(src_pointers[frames_count - 1] + x));
296 | __m128i weight = _mm_set1_epi32(int_weights[frames_count - 1]);
297 |
298 | src = _mm_unpacklo_epi8(src, zero);
299 | __m128i src_lo = _mm_unpacklo_epi16(src, zero);
300 | __m128i src_hi = _mm_unpackhi_epi16(src, zero);
301 |
302 | __m128i weighted_lo = _mm_madd_epi16(src_lo, weight);
303 | __m128i weighted_hi = _mm_madd_epi16(src_hi, weight);
304 |
305 | acc_lo = _mm_add_epi32(acc_lo, weighted_lo);
306 | acc_hi = _mm_add_epi32(acc_hi, weighted_hi);
307 | }
308 |
309 | acc_lo = _mm_add_epi32(acc_lo, round_mask);
310 | acc_hi = _mm_add_epi32(acc_hi, round_mask);
311 |
312 | __m128i dst_lo = _mm_srai_epi32(acc_lo, 14);
313 | __m128i dst_hi = _mm_srai_epi32(acc_hi, 14);
314 |
315 | __m128i dst = _mm_packs_epi32(dst_lo, dst_hi);
316 | dst = _mm_packus_epi16(dst, zero);
317 | _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp + x), dst);
318 | }
319 |
320 | for (int x = mod8_width; x < width; ++x) {
321 | float acc = 0;
322 | for (int i = 0; i < frames_count; ++i) {
323 | acc += src_pointers[i][x] * weights[i];
324 | }
325 | dstp[x] = static_clip<0, 255>(acc);
326 | }
327 |
328 | for (int i = 0; i < frames_count; ++i) {
329 | src_pointers[i] += src_pitches[i];
330 | }
331 | dstp += dst_pitch;
332 | }
333 | }
334 | }
335 | #endif
336 | // INTEL_INTRINSICS end
337 |
338 | struct WeightedClip {
339 | PClip clip;
340 | float weight;
341 |
342 | WeightedClip(PClip _clip, float _weight) : clip(_clip), weight(_weight) {}
343 | };
344 |
345 |
346 | class Average : public GenericVideoFilter {
347 | public:
348 | Average(std::vector clips, IScriptEnvironment* env)
349 | : GenericVideoFilter(clips[0].clip), clips_(clips) {
350 |
351 | has_at_least_v8 = true;
352 | try { env->CheckVersion(8); }
353 | catch (const AvisynthError&) { has_at_least_v8 = false; }
354 |
355 | int frames_count = (int)clips_.size();
356 |
357 | int pixelsize = vi.ComponentSize();
358 | int bits_per_pixel = vi.BitsPerComponent();
359 |
360 | #ifdef INTEL_INTRINSICS
361 | const bool avx = !!(env->GetCPUFlags() & CPUF_AVX);
362 | const bool avx2 = !!(env->GetCPUFlags() & CPUF_AVX2);
363 | #endif
364 | // we don't know the alignment here. avisynth+: 32 bytes, classic: 16
365 | // decide later (processor_, processor_32aligned)
366 |
367 | #ifdef INTEL_INTRINSICS
368 | if (env->GetCPUFlags() & CPUF_SSE2) {
369 | bool use_weighted_average_f = false;
370 | if (pixelsize == 1) {
371 | if (frames_count == 2)
372 | processor_ = &weighted_average_int_sse2<2>;
373 | else if (frames_count == 3)
374 | processor_ = &weighted_average_int_sse2<3>;
375 | else
376 | processor_ = &weighted_average_int_sse2<0>;
377 | processor_32aligned_ = processor_;
378 | for (const auto& clip : clips) {
379 | if (std::abs(clip.weight) > 1) {
380 | use_weighted_average_f = true;
381 | break;
382 | }
383 | }
384 | if (clips.size() > 255) {
385 | // too many clips, may overflow
386 | use_weighted_average_f = true;
387 | }
388 | }
389 | else {
390 | // uint16 and float: float mode internally
391 | use_weighted_average_f = true;
392 | }
393 |
394 | if (use_weighted_average_f) {
395 | switch(bits_per_pixel) {
396 | case 8:
397 | processor_ = &weighted_average_sse2;
398 | processor_32aligned_ = avx2 ? &weighted_average_avx2 : avx ? &weighted_average_avx : &weighted_average_sse2;
399 | break;
400 | case 10:
401 | processor_ = &weighted_average_sse2;
402 | processor_32aligned_ = avx2 ? &weighted_average_avx2 : avx ? &weighted_average_avx : &weighted_average_sse2;
403 | break;
404 | case 12:
405 | processor_ = &weighted_average_sse2;
406 | processor_32aligned_ = avx2 ? &weighted_average_avx2 : avx ? &weighted_average_avx : &weighted_average_sse2;
407 | break;
408 | case 14:
409 | processor_ = &weighted_average_sse2;
410 | processor_32aligned_ = avx2 ? &weighted_average_avx2 : avx ? &weighted_average_avx : &weighted_average_sse2;
411 | break;
412 | case 16:
413 | processor_ = &weighted_average_sse2;
414 | processor_32aligned_ = avx2 ? &weighted_average_avx2 : avx ? &weighted_average_avx : processor_;
415 | break;
416 | case 32:
417 | processor_ = &weighted_average_f_sse2;
418 | processor_32aligned_ = avx2 ? &weighted_average_f_avx2 : avx ? &weighted_average_f_avx : &weighted_average_f_sse2;
419 | break;
420 | }
421 | }
422 | }
423 | else
424 | #endif
425 | {
426 | switch (bits_per_pixel) {
427 | case 8:
428 | processor_ = &weighted_average_c;
429 | break;
430 | case 10:
431 | processor_ = &weighted_average_c;
432 | break;
433 | case 12:
434 | processor_ = &weighted_average_c;
435 | break;
436 | case 14:
437 | processor_ = &weighted_average_c;
438 | break;
439 | case 16:
440 | processor_ = &weighted_average_c;
441 | break;
442 | case 32:
443 | processor_ = &weighted_average_c; // bits_per_pixel n/a
444 | break;
445 | }
446 | processor_32aligned_ = processor_;
447 | }
448 | }
449 |
450 | PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;
451 |
452 | int __stdcall SetCacheHints(int cachehints, int frame_range) override {
453 | return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;
454 | }
455 |
456 | private:
457 | std::vector clips_;
458 | decltype(&weighted_average_c) processor_;
459 | decltype(&weighted_average_c) processor_32aligned_;
460 | bool has_at_least_v8;
461 | };
462 |
463 |
464 | PVideoFrame Average::GetFrame(int n, IScriptEnvironment *env) {
465 | int frames_count = (int)clips_.size();
466 | PVideoFrame* src_frames = reinterpret_cast(alloca(frames_count * sizeof(PVideoFrame)));
467 | const uint8_t **src_ptrs = reinterpret_cast(alloca(sizeof(uint8_t*)* frames_count));
468 | int *src_pitches = reinterpret_cast(alloca(sizeof(int)* frames_count));
469 | float *weights = reinterpret_cast(alloca(sizeof(float)* frames_count));
470 | if (src_pitches == nullptr || src_frames == nullptr || src_ptrs == nullptr || weights == nullptr) {
471 | env->ThrowError("Average: Couldn't allocate memory on stack. This is a bug, please report");
472 | }
473 | memset(src_frames, 0, frames_count * sizeof(PVideoFrame));
474 |
475 | for (int i = 0; i < frames_count; ++i) {
476 | src_frames[i] = clips_[i].clip->GetFrame(n, env);
477 | weights[i] = clips_[i].weight;
478 | }
479 |
480 | // frame props from the first clip
481 | PVideoFrame dst = has_at_least_v8 ? env->NewVideoFrameP(vi, &src_frames[0]) : env->NewVideoFrame(vi);
482 |
483 | int planes_y[4] = { PLANAR_Y, PLANAR_U, PLANAR_V, PLANAR_A };
484 | int planes_r[4] = { PLANAR_G, PLANAR_B, PLANAR_R, PLANAR_A };
485 | int *planes = (vi.IsPlanarRGB() || vi.IsPlanarRGBA()) ? planes_r : planes_y;
486 |
487 | bool hasAlpha = vi.IsPlanarRGBA() || vi.IsYUVA();
488 |
489 | for (int pid = 0; pid < (vi.IsY() ? 1 : (hasAlpha ? 4 : 3)); pid++) {
490 | int plane = planes[pid];
491 | int width = dst->GetRowSize(plane);
492 | int height = dst->GetHeight(plane);
493 | auto dstp = dst->GetWritePtr(plane);
494 | int dst_pitch = dst->GetPitch(plane);
495 |
496 | bool allSrc32aligned = true;
497 | for (int i = 0; i < frames_count; ++i) {
498 | src_ptrs[i] = src_frames[i]->GetReadPtr(plane);
499 | src_pitches[i] = src_frames[i]->GetPitch(plane);
500 | if (!IsPtrAligned(src_ptrs[i], 32))
501 | allSrc32aligned = false;
502 | if(src_pitches[i] & 0x1F)
503 | allSrc32aligned = false;
504 | }
505 |
506 | if(IsPtrAligned(dstp,32) && (dst_pitch & 0x1F)==0 && allSrc32aligned)
507 | processor_32aligned_(dstp, dst_pitch, src_ptrs, src_pitches, weights, frames_count, width, height);
508 | else
509 | processor_(dstp, dst_pitch, src_ptrs, src_pitches, weights, frames_count, width, height);
510 | }
511 |
512 | for (int i = 0; i < frames_count; ++i) {
513 | src_frames[i].~PVideoFrame();
514 | }
515 |
516 | return dst;
517 | }
518 |
519 |
520 | AVSValue __cdecl create_average(AVSValue args, void* user_data, IScriptEnvironment* env) {
521 | AVSValue args0 = args[0];
522 | int arguments_count = args0.ArraySize();
523 | if (arguments_count == 1 && args0[0].IsArray()) {
524 | args0 = args0[0];
525 | arguments_count = args0.ArraySize();
526 | }
527 |
528 | if (arguments_count % 2 != 0) {
529 | env->ThrowError("Average requires an even number of arguments (clip,weight,...) listed or passed in a single array.");
530 | }
531 | if (arguments_count == 0) {
532 | env->ThrowError("Average: At least one clip has to be supplied.");
533 | }
534 | std::vector clips;
535 | auto first_clip = args0[0].AsClip();
536 | auto first_vi = first_clip->GetVideoInfo();
537 | clips.emplace_back(first_clip, static_cast(args0[1].AsFloat()));
538 |
539 | for (int i = 2; i < arguments_count; i += 2) {
540 | auto clip = args0[i].AsClip();
541 | float weight = static_cast(args0[i+1].AsFloat());
542 | if (std::abs(weight) < 0.00001f) {
543 | continue;
544 | }
545 | auto vi = clip->GetVideoInfo();
546 | if (!vi.IsSameColorspace(first_vi)) {
547 | env->ThrowError("Average: all clips must have the same colorspace.");
548 | }
549 | if (vi.width != first_vi.width || vi.height != first_vi.height) {
550 | env->ThrowError("Average: all clips must have identical width and height.");
551 | }
552 | if (vi.num_frames < first_vi.num_frames) {
553 | env->ThrowError("Average: all clips must be have same or greater number of frames as the first one.");
554 | }
555 |
556 | clips.emplace_back(clip, weight);
557 | }
558 |
559 | return new Average(clips, env);
560 | }
561 |
562 | const AVS_Linkage *AVS_linkage = nullptr;
563 |
564 | extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(IScriptEnvironment* env, const AVS_Linkage* const vectors) {
565 | AVS_linkage = vectors;
566 | env->AddFunction("average", ".*", create_average, 0);
567 | return "Mind your sugar level";
568 | }
569 |
--------------------------------------------------------------------------------
/Average/average.rc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinterf/Average/ec21ee1bdc4164cd3c98ba9b848179e77d083dd7/Average/average.rc
--------------------------------------------------------------------------------
/Average/average_avx.cpp:
--------------------------------------------------------------------------------
1 | #ifdef INTEL_INTRINSICS
2 |
3 | #include "avisynth.h"
4 | #include
5 | #include
6 | #include
7 |
8 | #if defined(__GNUC__) && !defined(__INTEL_COMPILER)
9 | #include
10 | // x86intrin.h includes header files for whatever instruction
11 | // sets are specified on the compiler command line, such as: xopintrin.h, fma4intrin.h
12 | #else
13 | #include // MS version of immintrin.h covers AVX, AVX2 and FMA3
14 | #endif // __GNUC__
15 |
16 | template
17 | static AVS_FORCEINLINE int static_clip(float val) {
18 | if (val > maximum) {
19 | return maximum;
20 | }
21 | if (val < minimum) {
22 | return minimum;
23 | }
24 | return (int)val;
25 | }
26 |
27 | template
28 | void weighted_average_avx(uint8_t *dstp, int dst_pitch, const uint8_t **src_pointers, int *src_pitches, float *weights, int frames_count, int width, int height) {
29 | // width is row_size
30 | int mod_width;
31 | if(sizeof(pixel_t) == 1)
32 | mod_width = width / 16 * 16;
33 | else
34 | mod_width = width / 32 * 32;
35 |
36 | const int sse_size = (sizeof(pixel_t) == 1) ? 16 : 32;
37 |
38 | const int max_pixel_value = (sizeof(pixel_t) == 1) ? 255 : ((1 << bits_per_pixel) - 1);
39 | __m256i pixel_limit;
40 | __m128i pixel_limit_128i;
41 | if (sizeof(pixel_t) == 2 && bits_per_pixel < 16) {
42 | pixel_limit = _mm256_set1_epi16((int16_t)max_pixel_value);
43 | pixel_limit_128i = _mm_set1_epi16((int16_t)max_pixel_value);
44 | }
45 |
46 | __m128i zero128 = _mm_setzero_si128();
47 |
48 | for (int y = 0; y < height; ++y) {
49 | for (int x = 0; x < mod_width; x += sse_size) {
50 | __m256 acc_lo = _mm256_setzero_ps();
51 | __m256 acc_hi = _mm256_setzero_ps();
52 |
53 | for (int i = 0; i < frames_count; ++i) {
54 | __m128i src_lo, src_hi;
55 | __m256 src_lo_ps, src_hi_ps;
56 |
57 | if (sizeof(pixel_t) == 1) {
58 | __m128i src128 = _mm_load_si128(reinterpret_cast(src_pointers[i] + x));
59 | src_lo = _mm_unpacklo_epi8(src128, zero128);
60 | src_hi = _mm_unpackhi_epi8(src128, zero128);
61 | }
62 | else {
63 | src_lo = _mm_load_si128(reinterpret_cast(src_pointers[i] + x));
64 | src_hi = _mm_load_si128(reinterpret_cast(src_pointers[i] + x + 16));
65 | }
66 |
67 | __m128i src_lo_lo = _mm_unpacklo_epi16(src_lo, zero128);
68 | __m128i src_lo_hi = _mm_unpackhi_epi16(src_lo, zero128);
69 | __m256i src_lo_256 = _mm256_set_m128i(src_lo_hi, src_lo_lo); // hi,lo
70 | __m128i src_hi_lo = _mm_unpacklo_epi16(src_hi, zero128);
71 | __m128i src_hi_hi = _mm_unpackhi_epi16(src_hi, zero128);
72 | __m256i src_hi_256 = _mm256_set_m128i(src_hi_hi, src_hi_lo); // hi,lo
73 | src_lo_ps = _mm256_cvtepi32_ps(src_lo_256);
74 | src_hi_ps = _mm256_cvtepi32_ps(src_hi_256);
75 |
76 | auto weight = _mm256_set1_ps(weights[i]);
77 |
78 | auto weighted_lo = _mm256_mul_ps(src_lo_ps, weight);
79 | auto weighted_hi = _mm256_mul_ps(src_hi_ps, weight);
80 |
81 | acc_lo = _mm256_add_ps(acc_lo, weighted_lo);
82 | acc_hi = _mm256_add_ps(acc_hi, weighted_hi);
83 | }
84 | auto dst_lo = _mm256_cvtps_epi32(acc_lo);
85 | auto dst_hi = _mm256_cvtps_epi32(acc_hi);
86 |
87 | if (sizeof(pixel_t) == 1) {
88 | // Pack and store
89 | __m128i result_lo = _mm_packs_epi32(_mm256_extractf128_si256(dst_lo, 0), _mm256_extractf128_si256(dst_lo, 1)); // 4*32+4*32 = 8*16
90 | __m128i result_hi = _mm_packs_epi32(_mm256_extractf128_si256(dst_hi, 0), _mm256_extractf128_si256(dst_hi, 1)); // 4*32+4*32 = 8*16
91 | __m128i result = _mm_packus_epi16(result_lo, result_hi);
92 | _mm_store_si128(reinterpret_cast<__m128i*>(dstp + x), result);
93 | }
94 | else if (sizeof(pixel_t) == 2) {
95 | // Pack and store
96 | __m128i result_lo = _mm_packus_epi32(_mm256_extractf128_si256(dst_lo, 0), _mm256_extractf128_si256(dst_lo, 1)); // 4*32+4*32 = 8*16
97 | __m128i result_hi = _mm_packus_epi32(_mm256_extractf128_si256(dst_hi, 0), _mm256_extractf128_si256(dst_hi, 1)); // 4*32+4*32 = 8*16
98 | if (sizeof(pixel_t) == 2 && bits_per_pixel < 16) {
99 | result_lo = _mm_min_epu16(result_lo, pixel_limit_128i); // unsigned clamp here
100 | result_hi = _mm_min_epu16(result_hi, pixel_limit_128i); // unsigned clamp here
101 | }
102 | _mm_stream_si128(reinterpret_cast<__m128i*>(dstp + x), result_lo);
103 | _mm_stream_si128(reinterpret_cast<__m128i*>(dstp + x + 16), result_hi);
104 | }
105 | }
106 |
107 | int start = mod_width / sizeof(pixel_t);
108 | int end = width / sizeof(pixel_t);
109 | for (int x = start; x < end; ++x) {
110 | float acc = 0;
111 | for (int i = 0; i < frames_count; ++i) {
112 | acc += reinterpret_cast(src_pointers[i])[x] * weights[i];
113 | }
114 | reinterpret_cast(dstp)[x] = static_clip<0, max_pixel_value>(acc);
115 | }
116 |
117 | for (int i = 0; i < frames_count; ++i) {
118 | src_pointers[i] += src_pitches[i];
119 | }
120 | dstp += dst_pitch;
121 | }
122 | _mm256_zeroupper();
123 | }
124 |
125 | // instantiate
126 | template void weighted_average_avx(uint8_t *dstp, int dst_pitch, const uint8_t **src_pointers, int *src_pitches, float *weights, int frames_count, int width, int height);
127 | template void weighted_average_avx(uint8_t *dstp, int dst_pitch, const uint8_t **src_pointers, int *src_pitches, float *weights, int frames_count, int width, int height);
128 | template void weighted_average_avx(uint8_t *dstp, int dst_pitch, const uint8_t **src_pointers, int *src_pitches, float *weights, int frames_count, int width, int height);
129 | template void weighted_average_avx(uint8_t *dstp, int dst_pitch, const uint8_t **src_pointers, int *src_pitches, float *weights, int frames_count, int width, int height);
130 | template void weighted_average_avx(uint8_t *dstp, int dst_pitch, const uint8_t **src_pointers, int *src_pitches, float *weights, int frames_count, int width, int height);
131 |
132 | void weighted_average_f_avx(uint8_t *dstp, int dst_pitch, const uint8_t **src_pointers, int *src_pitches, float *weights, int frames_count, int width, int height) {
133 | // width is row_size
134 | int mod_width = width / 32 * 32;
135 |
136 | const int sse_size = 32;
137 |
138 | for (int y = 0; y < height; ++y) {
139 | for (int x = 0; x < mod_width; x += sse_size) {
140 | __m256 acc = _mm256_setzero_ps();
141 |
142 | for (int i = 0; i < frames_count; ++i) {
143 | __m256 src;
144 | src = _mm256_load_ps(reinterpret_cast(src_pointers[i] + x)); // float 8*32=256 8 pixels at a time
145 | // Here: 256 bit load is faster
146 | // using one 256bit load instead of 2x128bit is sometimes slower on avx-only Ivy, depends on the next instructions (see: ports)
147 | //__m128 src_l_single = _mm_load_ps(reinterpret_cast(src_pointers[i] + x)); // float 4*32=128 4 pixels at a time
148 | //__m128 src_h_single = _mm_load_ps(reinterpret_cast(src_pointers[i] + x + 16)); // float 4*32=128 4 pixels at a time
149 | //src = _mm256_set_m128(src_h_single, src_l_single); // hi, lo
150 |
151 | auto weight = _mm256_set1_ps(weights[i]);
152 | auto weighted = _mm256_mul_ps(src, weight);
153 | acc = _mm256_add_ps(acc, weighted);
154 | }
155 | _mm256_stream_ps(reinterpret_cast(dstp + x), acc);
156 | }
157 |
158 | for (int x = mod_width / 4; x < width / 4; ++x) {
159 | float acc = 0;
160 | for (int i = 0; i < frames_count; ++i) {
161 | acc += reinterpret_cast(src_pointers[i])[x] * weights[i];
162 | }
163 | reinterpret_cast(dstp)[x] = acc; // float: no clamping
164 | }
165 |
166 | for (int i = 0; i < frames_count; ++i) {
167 | src_pointers[i] += src_pitches[i];
168 | }
169 | dstp += dst_pitch;
170 | }
171 | _mm256_zeroupper();
172 | }
173 | #endif
174 |
--------------------------------------------------------------------------------
/Average/average_avx.h:
--------------------------------------------------------------------------------
1 | #include "avisynth.h"
2 | #include
3 |
4 | template
5 | void weighted_average_avx(uint8_t *dstp, int dst_pitch, const uint8_t **src_pointers, int *src_pitches, float *weights, int frames_count, int width, int height);
6 |
7 | void weighted_average_f_avx(uint8_t *dstp, int dst_pitch, const uint8_t **src_pointers, int *src_pitches, float *weights, int frames_count, int width, int height);
8 |
9 |
--------------------------------------------------------------------------------
/Average/average_avx2.cpp:
--------------------------------------------------------------------------------
1 | #ifdef INTEL_INTRINSICS
2 |
3 | #include "avisynth.h"
4 | #include
5 | #include
6 | #include
7 |
8 | // experimental simd includes for avx2 compiled files
9 | #if defined(__GNUC__) && !defined(__INTEL_COMPILER)
10 | #include
11 | // x86intrin.h includes header files for whatever instruction
12 | // sets are specified on the compiler command line, such as: xopintrin.h, fma4intrin.h
13 | #else
14 | #include // MS version of immintrin.h covers AVX, AVX2 and FMA3
15 | #endif // __GNUC__
16 |
17 | #if !defined(__FMA__)
18 | // Assume that all processors that have AVX2 also have FMA3
19 | #if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__)
20 | // Prevent error message in g++ when using FMA intrinsics with avx2:
21 | #pragma message "It is recommended to specify also option -mfma when using -mavx2 or higher"
22 | #else
23 | #define __FMA__ 1
24 | #endif
25 | #endif
26 | // FMA3 instruction set
27 | #if defined(__FMA__) && (defined(__GNUC__) || defined(__clang__)) && !defined(__INTEL_COMPILER)
28 | #include
29 | #endif // __FMA__
30 |
31 | template
32 | static AVS_FORCEINLINE int static_clip(float val) {
33 | if (val > maximum) {
34 | return maximum;
35 | }
36 | if (val < minimum) {
37 | return minimum;
38 | }
39 | return (int)val;
40 | }
41 |
42 | template
43 | void weighted_average_avx2(uint8_t *dstp, int dst_pitch, const uint8_t **src_pointers, int *src_pitches, float *weights, int frames_count, int width, int height) {
44 | // width is row_size
45 | int mod_width;
46 | if(sizeof(pixel_t) == 1)
47 | mod_width = width / 16 * 16;
48 | else
49 | mod_width = width / 32 * 32;
50 |
51 | const int sse_size = (sizeof(pixel_t) == 1) ? 16 : 32;
52 |
53 | const int max_pixel_value = (sizeof(pixel_t) == 1) ? 255 : ((1 << bits_per_pixel) - 1);
54 | __m256i pixel_limit;
55 | __m128i pixel_limit_128i;
56 | if (sizeof(pixel_t) == 2 && bits_per_pixel < 16) {
57 | pixel_limit = _mm256_set1_epi16((int16_t)max_pixel_value);
58 | pixel_limit_128i = _mm_set1_epi16((int16_t)max_pixel_value);
59 | }
60 |
61 | __m128i zero128 = _mm_setzero_si128();
62 | __m256i zero = _mm256_setzero_si256();
63 |
64 | for (int y = 0; y < height; ++y) {
65 | for (int x = 0; x < mod_width; x += sse_size) {
66 | __m256 acc_lo = _mm256_setzero_ps();
67 | __m256 acc_hi = _mm256_setzero_ps();
68 |
69 | for (int i = 0; i < frames_count; ++i) {
70 | __m128i src_lo, src_hi;
71 | __m256i src;
72 | __m256 src_lo_ps, src_hi_ps;
73 |
74 | if (sizeof(pixel_t) == 1) {
75 | __m128i src128 = _mm_load_si128(reinterpret_cast(src_pointers[i] + x));
76 | src_lo = _mm_unpacklo_epi8(src128, zero128);
77 | src_hi = _mm_unpackhi_epi8(src128, zero128);
78 | src = _mm256_set_m128i(src_hi, src_lo);
79 | }
80 | else {
81 | src = _mm256_load_si256(reinterpret_cast(src_pointers[i] + x));
82 | }
83 |
84 | // _mm256_unpacklo_epi16: AVX2
85 | src_lo_ps = _mm256_cvtepi32_ps(_mm256_unpacklo_epi16(src, zero));
86 | src_hi_ps = _mm256_cvtepi32_ps(_mm256_unpackhi_epi16(src, zero));
87 |
88 | auto weight = _mm256_set1_ps(weights[i]);
89 |
90 | auto weighted_lo = _mm256_mul_ps(src_lo_ps, weight);
91 | auto weighted_hi = _mm256_mul_ps(src_hi_ps, weight);
92 |
93 | acc_lo = _mm256_add_ps(acc_lo, weighted_lo);
94 | acc_hi = _mm256_add_ps(acc_hi, weighted_hi);
95 | }
96 | auto dst_lo = _mm256_cvtps_epi32(acc_lo);
97 | auto dst_hi = _mm256_cvtps_epi32(acc_hi);
98 |
99 | __m256i dst;
100 | if (sizeof(pixel_t) == 1) {
101 | dst = _mm256_packs_epi32(dst_lo, dst_hi); // // not real 256, 2x128 schema
102 | dst = _mm256_packus_epi16(dst, zero);
103 | _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp + x), _mm256_extractf128_si256(dst, 0));
104 | _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp + x + 8), _mm256_extractf128_si256(dst, 1));
105 | }
106 | else if (sizeof(pixel_t) == 2) {
107 | dst = _mm256_packus_epi32(dst_lo, dst_hi); // not real 256, 2x128 schema
108 | if (sizeof(pixel_t) == 2 && bits_per_pixel < 16)
109 | dst = _mm256_min_epi16(dst, pixel_limit);
110 | _mm_store_si128(reinterpret_cast<__m128i*>(dstp + x), _mm256_extractf128_si256(dst, 0));
111 | _mm_store_si128(reinterpret_cast<__m128i*>(dstp + x + 16), _mm256_extractf128_si256(dst, 1));
112 | }
113 | }
114 |
115 | int start = mod_width / sizeof(pixel_t);
116 | int end = width / sizeof(pixel_t);
117 | for (int x = start; x < end; ++x) {
118 | float acc = 0;
119 | for (int i = 0; i < frames_count; ++i) {
120 | acc += reinterpret_cast(src_pointers[i])[x] * weights[i];
121 | }
122 | reinterpret_cast(dstp)[x] = static_clip<0, max_pixel_value>(acc);
123 | }
124 |
125 | for (int i = 0; i < frames_count; ++i) {
126 | src_pointers[i] += src_pitches[i];
127 | }
128 | dstp += dst_pitch;
129 | }
130 | _mm256_zeroupper();
131 | }
132 |
133 | // instantiate
134 | template void weighted_average_avx2(uint8_t *dstp, int dst_pitch, const uint8_t **src_pointers, int *src_pitches, float *weights, int frames_count, int width, int height);
135 | template void weighted_average_avx2(uint8_t *dstp, int dst_pitch, const uint8_t **src_pointers, int *src_pitches, float *weights, int frames_count, int width, int height);
136 | template void weighted_average_avx2(uint8_t *dstp, int dst_pitch, const uint8_t **src_pointers, int *src_pitches, float *weights, int frames_count, int width, int height);
137 | template void weighted_average_avx2(uint8_t *dstp, int dst_pitch, const uint8_t **src_pointers, int *src_pitches, float *weights, int frames_count, int width, int height);
138 | template void weighted_average_avx2(uint8_t *dstp, int dst_pitch, const uint8_t **src_pointers, int *src_pitches, float *weights, int frames_count, int width, int height);
139 |
140 | void weighted_average_f_avx2(uint8_t *dstp, int dst_pitch, const uint8_t **src_pointers, int *src_pitches, float *weights, int frames_count, int width, int height) {
141 | // width is row_size
142 | int mod_width = width / 32 * 32;
143 |
144 | const int sse_size = 32;
145 |
146 | for (int y = 0; y < height; ++y) {
147 | for (int x = 0; x < mod_width; x += sse_size) {
148 | __m256 acc = _mm256_setzero_ps();
149 |
150 | for (int i = 0; i < frames_count; ++i) {
151 | __m256 src = _mm256_load_ps(reinterpret_cast(src_pointers[i] + x)); // float 8*32=256 8 pixels at a time
152 | auto weight = _mm256_set1_ps(weights[i]);
153 | auto weighted = _mm256_mul_ps(src, weight);
154 | acc = _mm256_add_ps(acc, weighted);
155 | }
156 | _mm256_stream_ps(reinterpret_cast(dstp + x), acc);
157 | }
158 |
159 | for (int x = mod_width / 4; x < width / 4; ++x) {
160 | float acc = 0;
161 | for (int i = 0; i < frames_count; ++i) {
162 | acc += reinterpret_cast(src_pointers[i])[x] * weights[i];
163 | }
164 | reinterpret_cast(dstp)[x] = acc; // float: no clamping
165 | }
166 |
167 | for (int i = 0; i < frames_count; ++i) {
168 | src_pointers[i] += src_pitches[i];
169 | }
170 | dstp += dst_pitch;
171 | }
172 | _mm256_zeroupper();
173 | }
174 |
175 | #endif
176 |
--------------------------------------------------------------------------------
/Average/average_avx2.h:
--------------------------------------------------------------------------------
1 | #include "avisynth.h"
2 | #include
3 |
4 | template
5 | void weighted_average_avx2(uint8_t *dstp, int dst_pitch, const uint8_t **src_pointers, int *src_pitches, float *weights, int frames_count, int width, int height);
6 |
7 | void weighted_average_f_avx2(uint8_t *dstp, int dst_pitch, const uint8_t **src_pointers, int *src_pitches, float *weights, int frames_count, int width, int height);
8 |
9 |
--------------------------------------------------------------------------------
/Average/avisynth.h:
--------------------------------------------------------------------------------
1 | // Avisynth v2.5. Copyright 2002 Ben Rudiak-Gould et al.
2 | // Avisynth v2.6. Copyright 2006 Klaus Post.
3 | // Avisynth v2.6. Copyright 2009 Ian Brabham.
4 | // Avisynth+ project
5 | // 20160613: new 16 bit planar pixel_type constants go live!
6 | // 20160725: pixel_type constants 10-12-14 bit + planar RGB + BRG48/64
7 | // 20161005: Fallback of VideoInfo functions to defaults if no function exists
8 | // 20170117: global variables for VfW output OPT_xxxx
9 | // 20170310: new MT mode: MT_SPECIAL_MT
10 | // 20171103: (test with SIZETMOD define: Videoframe offsets to size_t, may affect x64)
11 | // 20171207: C++ Standard Conformance (no change for plugin writers)
12 | // 20180525: AVS_UNUSED define to supress parameter not used warnings
13 | // 2020xxxx: AVS_WINDOWS and AVS_POSIX option see avs/config.h
14 | // 20200305: ScriptEnvironment::VSprintf parameter (void *) changed back to va_list
15 | // 20200330: removed __stdcall from variadic argument functions (Sprintf)
16 | // (remove test SIZETMOD define for clarity)
17 | // Integrate Avisynth Neo structures and interface, PFunction, PDevice
18 | // 20200501: frame property support (NewVideoFrameP and other helpers) to legacy IScriptEnvironment.
19 | // move some former IScriptEnvironment2 functions to IScriptEnvironment:
20 | // GetEnvProperty (system prop), Allocate, Free (buffer pool)
21 | // GetVarTry, GetVarBool/Int/String/Double/Long
22 | // Invoke2, Invoke3, InvokeTry, Invoke2Try, Invoke3Try
23 | // Interface Version to 8 (classic 2.6 = 6)
24 | // 20200527 Add IScriptEnvironment_Avs25, used internally
25 | // 20200607 AVS frame property enums to match existing Avisynth enum style
26 |
27 | // http://www.avisynth.org
28 |
29 | // This program is free software; you can redistribute it and/or modify
30 | // it under the terms of the GNU General Public License as published by
31 | // the Free Software Foundation; either version 2 of the License, or
32 | // (at your option) any later version.
33 | //
34 | // This program is distributed in the hope that it will be useful,
35 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
36 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37 | // GNU General Public License for more details.
38 | //
39 | // You should have received a copy of the GNU General Public License
40 | // along with this program; if not, write to the Free Software
41 | // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit
42 | // http://www.gnu.org/copyleft/gpl.html .
43 | //
44 | // Linking Avisynth statically or dynamically with other modules is making
45 | // a combined work based on Avisynth. Thus, the terms and conditions of
46 | // the GNU General Public License cover the whole combination.
47 | //
48 | // As a special exception, the copyright holders of Avisynth give you
49 | // permission to link Avisynth with independent modules that communicate
50 | // with Avisynth solely through the interfaces defined in avisynth.h,
51 | // regardless of the license terms of these independent modules, and to
52 | // copy and distribute the resulting combined work under terms of your
53 | // choice, provided that every copy of the combined work is accompanied
54 | // by a complete copy of the source code of Avisynth (the version of
55 | // Avisynth used to produce the combined work), being distributed under
56 | // the terms of the GNU General Public License plus this exception. An
57 | // independent module is a module which is not derived from or based on
58 | // Avisynth, such as 3rd-party filters, import and export plugins, or
59 | // graphical user interfaces.
60 |
61 |
62 | #ifndef __AVISYNTH_8_H__
63 | #define __AVISYNTH_8_H__
64 |
65 | #include "avs/config.h"
66 | #include "avs/capi.h"
67 | #include "avs/types.h"
68 |
69 | #ifdef AVS_POSIX
70 | # include "avs/posix.h"
71 | #endif
72 |
73 | #if defined(AVS_POSIX)
74 | #if defined(AVS_HAIKU)
75 | #undef __stdcall
76 | #undef __cdecl
77 | #endif
78 | #define __stdcall
79 | #define __cdecl
80 | #endif
81 |
82 | // Important note on AVISYNTH_INTERFACE_VERSION V6->V8 change:
83 | // Note 1: Those few plugins which were using earlier IScriptEnvironment2 despite the big Warning will crash have to be rebuilt.
84 | // Note 2: How to support earlier avisynth interface with an up-to-date avisynth.h:
85 | // Use the new frame property features adaptively after querying that at least v8 is supported
86 | // AviSynth property support can be queried (cpp iface example):
87 | // has_at_least_v8 = true;
88 | // try { env->CheckVersion(8); } catch (const AvisynthError&) { has_at_least_v8 = false; }
89 | // and use it:
90 | // if (has_at_least_v8) dst = env->NewVideoFrameP(vi, &src); else dst = env->NewVideoFrame(vi);
91 |
92 | enum {
93 | AVISYNTH_CLASSIC_INTERFACE_VERSION_25 = 3,
94 | AVISYNTH_CLASSIC_INTERFACE_VERSION_26BETA = 5,
95 | AVISYNTH_CLASSIC_INTERFACE_VERSION = 6,
96 | AVISYNTH_INTERFACE_VERSION = 8
97 | };
98 |
99 | /* Compiler-specific crap */
100 |
101 | // Tell MSVC to stop precompiling here
102 | #if defined(_MSC_VER) && !defined(__clang__)
103 | #pragma hdrstop
104 | #endif
105 |
106 | // Set up debugging macros for MS compilers; for others, step down to the
107 | // standard interface
108 | #ifdef _MSC_VER
109 | #include
110 | #else
111 | #undef _RPT0
112 | #undef _RPT1
113 | #undef _RPT2
114 | #undef _RPT3
115 | #undef _RPT4
116 | #undef _RPT5
117 | #define _RPT0(a,b) ((void)0)
118 | #define _RPT1(a,b,c) ((void)0)
119 | #define _RPT2(a,b,c,d) ((void)0)
120 | #define _RPT3(a,b,c,d,e) ((void)0)
121 | #define _RPT4(a,b,c,d,e,f) ((void)0)
122 | #define _RPT5(a,b,c,d,e,f,g) ((void)0)
123 |
124 | #include
125 | #undef _ASSERTE
126 | #undef _ASSERT
127 | #define _ASSERTE(x) assert(x)
128 | #define _ASSERT(x) assert(x)
129 | #endif
130 |
131 |
132 |
133 | // I had problems with Premiere wanting 1-byte alignment for its structures,
134 | // so I now set the Avisynth struct alignment explicitly here.
135 | #pragma pack(push,8)
136 |
137 | // The VideoInfo struct holds global information about a clip (i.e.
138 | // information that does not depend on the frame number). The GetVideoInfo
139 | // method in IClip returns this struct.
140 |
141 | enum {SAMPLE_INT8 = 1<<0,
142 | SAMPLE_INT16 = 1<<1,
143 | SAMPLE_INT24 = 1<<2, // Int24 is a very stupid thing to code, but it's supported by some hardware.
144 | SAMPLE_INT32 = 1<<3,
145 | SAMPLE_FLOAT = 1<<4};
146 |
147 | enum {
148 | PLANAR_Y=1<<0,
149 | PLANAR_U=1<<1,
150 | PLANAR_V=1<<2,
151 | PLANAR_ALIGNED=1<<3,
152 | PLANAR_Y_ALIGNED=PLANAR_Y|PLANAR_ALIGNED,
153 | PLANAR_U_ALIGNED=PLANAR_U|PLANAR_ALIGNED,
154 | PLANAR_V_ALIGNED=PLANAR_V|PLANAR_ALIGNED,
155 | PLANAR_A=1<<4,
156 | PLANAR_R=1<<5,
157 | PLANAR_G=1<<6,
158 | PLANAR_B=1<<7,
159 | PLANAR_A_ALIGNED=PLANAR_A|PLANAR_ALIGNED,
160 | PLANAR_R_ALIGNED=PLANAR_R|PLANAR_ALIGNED,
161 | PLANAR_G_ALIGNED=PLANAR_G|PLANAR_ALIGNED,
162 | PLANAR_B_ALIGNED=PLANAR_B|PLANAR_ALIGNED,
163 | };
164 |
165 | class AvisynthError /* exception */ {
166 | public:
167 | const char* const msg;
168 | AvisynthError(const char* _msg) : msg(_msg) {}
169 |
170 | // Ensure AvisynthError cannot be publicly assigned!
171 | private:
172 | AvisynthError& operator=(const AvisynthError&);
173 | }; // end class AvisynthError
174 |
175 | enum AvsDeviceType {
176 | DEV_TYPE_NONE = 0,
177 | DEV_TYPE_CPU = 1,
178 | DEV_TYPE_CUDA = 2,
179 | DEV_TYPE_ANY = 0xFFFF
180 | };
181 |
182 | /* Forward references */
183 | #if defined(MSVC)
184 | #define SINGLE_INHERITANCE __single_inheritance
185 | #else
186 | #define SINGLE_INHERITANCE
187 | #endif
188 | struct SINGLE_INHERITANCE VideoInfo;
189 | class SINGLE_INHERITANCE VideoFrameBuffer;
190 | class SINGLE_INHERITANCE VideoFrame;
191 | class IClip;
192 | class SINGLE_INHERITANCE PClip;
193 | class SINGLE_INHERITANCE PVideoFrame;
194 | class IScriptEnvironment;
195 | class SINGLE_INHERITANCE AVSValue;
196 | class INeoEnv;
197 | class IFunction;
198 | class SINGLE_INHERITANCE PFunction;
199 | class Device;
200 | class SINGLE_INHERITANCE PDevice;
201 | class AVSMap;
202 |
203 |
204 |
205 | /*
206 | * Avisynth C++ plugin API code function pointers.
207 | *
208 | * In order to maintain binary compatibility with
209 | * future version do not change the order of the
210 | * existing function pointers. It will be baked
211 | * into all existing plugins.
212 | *
213 | * Add new function pointers to the end of the
214 | * structure. The linkage macros generate some
215 | * protection code to ensure newer plugin do not
216 | * call non-existing functions in an older host.
217 | */
218 |
219 | struct AVS_Linkage {
220 |
221 | int Size;
222 |
223 | /**********************************************************************/
224 |
225 | // struct VideoInfo
226 | bool (VideoInfo::*HasVideo)() const;
227 | bool (VideoInfo::*HasAudio)() const;
228 | bool (VideoInfo::*IsRGB)() const;
229 | bool (VideoInfo::*IsRGB24)() const;
230 | bool (VideoInfo::*IsRGB32)() const;
231 | bool (VideoInfo::*IsYUV)() const;
232 | bool (VideoInfo::*IsYUY2)() const;
233 | bool (VideoInfo::*IsYV24)() const;
234 | bool (VideoInfo::*IsYV16)() const;
235 | bool (VideoInfo::*IsYV12)() const;
236 | bool (VideoInfo::*IsYV411)() const;
237 | bool (VideoInfo::*IsY8)() const;
238 | bool (VideoInfo::*IsColorSpace)(int c_space) const;
239 | bool (VideoInfo::*Is)(int property) const;
240 | bool (VideoInfo::*IsPlanar)() const;
241 | bool (VideoInfo::*IsFieldBased)() const;
242 | bool (VideoInfo::*IsParityKnown)() const;
243 | bool (VideoInfo::*IsBFF)() const;
244 | bool (VideoInfo::*IsTFF)() const;
245 | bool (VideoInfo::*IsVPlaneFirst)() const;
246 | int (VideoInfo::*BytesFromPixels)(int pixels) const;
247 | int (VideoInfo::*RowSize)(int plane) const;
248 | int (VideoInfo::*BMPSize)() const;
249 | int64_t (VideoInfo::*AudioSamplesFromFrames)(int frames) const;
250 | int (VideoInfo::*FramesFromAudioSamples)(int64_t samples) const;
251 | int64_t (VideoInfo::*AudioSamplesFromBytes)(int64_t bytes) const;
252 | int64_t (VideoInfo::*BytesFromAudioSamples)(int64_t samples) const;
253 | int (VideoInfo::*AudioChannels)() const;
254 | int (VideoInfo::*SampleType)() const;
255 | bool (VideoInfo::*IsSampleType)(int testtype) const;
256 | int (VideoInfo::*SamplesPerSecond)() const;
257 | int (VideoInfo::*BytesPerAudioSample)() const;
258 | void (VideoInfo::*SetFieldBased)(bool isfieldbased);
259 | void (VideoInfo::*Set)(int property);
260 | void (VideoInfo::*Clear)(int property);
261 | int (VideoInfo::*GetPlaneWidthSubsampling)(int plane) const;
262 | int (VideoInfo::*GetPlaneHeightSubsampling)(int plane) const;
263 | int (VideoInfo::*BitsPerPixel)() const;
264 | int (VideoInfo::*BytesPerChannelSample)() const;
265 | void (VideoInfo::*SetFPS)(unsigned numerator, unsigned denominator);
266 | void (VideoInfo::*MulDivFPS)(unsigned multiplier, unsigned divisor);
267 | bool (VideoInfo::*IsSameColorspace)(const VideoInfo& vi) const;
268 | // end struct VideoInfo
269 |
270 | /**********************************************************************/
271 |
272 | // class VideoFrameBuffer
273 | const BYTE* (VideoFrameBuffer::*VFBGetReadPtr)() const;
274 | BYTE* (VideoFrameBuffer::*VFBGetWritePtr)();
275 | int (VideoFrameBuffer::*GetDataSize)() const;
276 | int (VideoFrameBuffer::*GetSequenceNumber)() const;
277 | int (VideoFrameBuffer::*GetRefcount)() const;
278 | // end class VideoFrameBuffer
279 |
280 | /**********************************************************************/
281 |
282 | // class VideoFrame
283 | int (VideoFrame::*GetPitch)(int plane) const;
284 | int (VideoFrame::*GetRowSize)(int plane) const;
285 | int (VideoFrame::*GetHeight)(int plane) const;
286 | VideoFrameBuffer* (VideoFrame::*GetFrameBuffer)() const;
287 | int (VideoFrame::*GetOffset)(int plane) const;
288 | const BYTE* (VideoFrame::*VFGetReadPtr)(int plane) const;
289 | bool (VideoFrame::*IsWritable)() const;
290 | BYTE* (VideoFrame::*VFGetWritePtr)(int plane) const;
291 | void (VideoFrame::*VideoFrame_DESTRUCTOR)();
292 | // end class VideoFrame
293 |
294 | /**********************************************************************/
295 |
296 | // class IClip
297 | /* nothing */
298 | // end class IClip
299 |
300 | /**********************************************************************/
301 |
302 | // class PClip
303 | void (PClip::*PClip_CONSTRUCTOR0)();
304 | void (PClip::*PClip_CONSTRUCTOR1)(const PClip& x);
305 | void (PClip::*PClip_CONSTRUCTOR2)(IClip* x);
306 | void (PClip::*PClip_OPERATOR_ASSIGN0)(IClip* x);
307 | void (PClip::*PClip_OPERATOR_ASSIGN1)(const PClip& x);
308 | void (PClip::*PClip_DESTRUCTOR)();
309 | // end class PClip
310 |
311 | /**********************************************************************/
312 |
313 | // class PVideoFrame
314 | void (PVideoFrame::*PVideoFrame_CONSTRUCTOR0)();
315 | void (PVideoFrame::*PVideoFrame_CONSTRUCTOR1)(const PVideoFrame& x);
316 | void (PVideoFrame::*PVideoFrame_CONSTRUCTOR2)(VideoFrame* x);
317 | void (PVideoFrame::*PVideoFrame_OPERATOR_ASSIGN0)(VideoFrame* x);
318 | void (PVideoFrame::*PVideoFrame_OPERATOR_ASSIGN1)(const PVideoFrame& x);
319 | void (PVideoFrame::*PVideoFrame_DESTRUCTOR)();
320 | // end class PVideoFrame
321 |
322 | /**********************************************************************/
323 |
324 | // class AVSValue
325 | void (AVSValue::*AVSValue_CONSTRUCTOR0)();
326 | void (AVSValue::*AVSValue_CONSTRUCTOR1)(IClip* c);
327 | void (AVSValue::*AVSValue_CONSTRUCTOR2)(const PClip& c);
328 | void (AVSValue::*AVSValue_CONSTRUCTOR3)(bool b);
329 | void (AVSValue::*AVSValue_CONSTRUCTOR4)(int i);
330 | void (AVSValue::*AVSValue_CONSTRUCTOR5)(float f);
331 | void (AVSValue::*AVSValue_CONSTRUCTOR6)(double f);
332 | void (AVSValue::*AVSValue_CONSTRUCTOR7)(const char* s);
333 | void (AVSValue::*AVSValue_CONSTRUCTOR8)(const AVSValue* a, int size);
334 | void (AVSValue::*AVSValue_CONSTRUCTOR9)(const AVSValue& v);
335 | void (AVSValue::*AVSValue_DESTRUCTOR)();
336 | AVSValue& (AVSValue::*AVSValue_OPERATOR_ASSIGN)(const AVSValue& v);
337 | const AVSValue& (AVSValue::*AVSValue_OPERATOR_INDEX)(int index) const;
338 | bool (AVSValue::*Defined)() const;
339 | bool (AVSValue::*IsClip)() const;
340 | bool (AVSValue::*IsBool)() const;
341 | bool (AVSValue::*IsInt)() const;
342 | bool (AVSValue::*IsFloat)() const;
343 | bool (AVSValue::*IsString)() const;
344 | bool (AVSValue::*IsArray)() const;
345 | PClip (AVSValue::*AsClip)() const;
346 | bool (AVSValue::*AsBool1)() const;
347 | int (AVSValue::*AsInt1)() const;
348 | const char* (AVSValue::*AsString1)() const;
349 | double (AVSValue::*AsFloat1)() const;
350 | bool (AVSValue::*AsBool2)(bool def) const;
351 | int (AVSValue::*AsInt2)(int def) const;
352 | double (AVSValue::*AsDblDef)(double def) const;
353 | double (AVSValue::*AsFloat2)(float def) const;
354 | const char* (AVSValue::*AsString2)(const char* def) const;
355 | int (AVSValue::*ArraySize)() const;
356 | // end class AVSValue
357 |
358 | /**********************************************************************/
359 | // Reserve pointer space so that we can keep compatibility with Avs "classic" even if it adds functions on its own
360 | void (VideoInfo::*reserved[32])();
361 | /**********************************************************************/
362 | // AviSynth+ additions
363 | int (VideoInfo::*NumComponents)() const;
364 | int (VideoInfo::*ComponentSize)() const;
365 | int (VideoInfo::*BitsPerComponent)() const;
366 | bool (VideoInfo::*Is444)() const;
367 | bool (VideoInfo::*Is422)() const;
368 | bool (VideoInfo::*Is420)() const;
369 | bool (VideoInfo::*IsY)() const;
370 | bool (VideoInfo::*IsRGB48)() const;
371 | bool (VideoInfo::*IsRGB64)() const;
372 | bool (VideoInfo::*IsYUVA)() const;
373 | bool (VideoInfo::*IsPlanarRGB)() const;
374 | bool (VideoInfo::*IsPlanarRGBA)() const;
375 | /**********************************************************************/
376 |
377 | // frame property access
378 | AVSMap& (VideoFrame::* getProperties)();
379 | const AVSMap& (VideoFrame::* getConstProperties)();
380 | void (VideoFrame::* setProperties)(const AVSMap& properties);
381 |
382 | // PFunction
383 | void (AVSValue::* AVSValue_CONSTRUCTOR11)(const PFunction& o);
384 | bool (AVSValue::* IsFunction)() const;
385 | void (PFunction::* PFunction_CONSTRUCTOR0)();
386 | void (PFunction::* PFunction_CONSTRUCTOR1)(IFunction* p);
387 | void (PFunction::* PFunction_CONSTRUCTOR2)(const PFunction& p);
388 | PFunction& (PFunction::* PFunction_OPERATOR_ASSIGN0)(IFunction* other);
389 | PFunction& (PFunction::* PFunction_OPERATOR_ASSIGN1)(const PFunction& other);
390 | void (PFunction::* PFunction_DESTRUCTOR)();
391 | // end PFunction
392 |
393 | // extra VideoFrame functions
394 | int (VideoFrame::* VideoFrame_CheckMemory)() const;
395 | PDevice (VideoFrame::* VideoFrame_GetDevice)() const;
396 |
397 | // class PDevice, even if only CPU device
398 | void (PDevice::* PDevice_CONSTRUCTOR0)();
399 | void (PDevice::* PDevice_CONSTRUCTOR1)(Device* p);
400 | void (PDevice::* PDevice_CONSTRUCTOR2)(const PDevice& p);
401 | PDevice& (PDevice::* PDevice_OPERATOR_ASSIGN0)(Device* other);
402 | PDevice& (PDevice::* PDevice_OPERATOR_ASSIGN1)(const PDevice& other);
403 | void (PDevice::* PDevice_DESTRUCTOR)();
404 | AvsDeviceType (PDevice::* PDevice_GetType)() const;
405 | int (PDevice::* PDevice_GetId)() const;
406 | int (PDevice::* PDevice_GetIndex)() const;
407 | const char* (PDevice::* PDevice_GetName)() const;
408 | // end class PDevice
409 |
410 | /**********************************************************************/
411 | // Reserve pointer space for Avisynth+
412 | void (VideoInfo::* reserved2[64 - 23])();
413 | /**********************************************************************/
414 |
415 | // AviSynth Neo additions
416 | INeoEnv* (__stdcall *GetNeoEnv)(IScriptEnvironment* env);
417 | // As of V8 most PDevice, PFunction linkage entries are moved to standard avs+ place.
418 | /**********************************************************************/
419 |
420 | // this part should be identical with AVS_Linkage entries in interface.cpp
421 | };
422 |
423 | #if defined(BUILDING_AVSCORE) || defined(AVS_STATIC_LIB)
424 | /* Macro resolution for code inside Avisynth.dll */
425 | # define AVS_BakedCode(arg) ;
426 | # define AVS_LinkCall(arg)
427 | # define AVS_LinkCallV(arg)
428 | # define AVS_LinkCallOpt(arg, argOpt) AVSLinkCall(arg)
429 | # define AVS_LinkCallOptDefault(arg, argDefaultValue) AVSLinkCall(arg())
430 | # define CALL_MEMBER_FN(object,ptrToMember)
431 |
432 | #else
433 | /* Macro resolution for code inside user plugin */
434 | # ifdef AVS_LINKAGE_DLLIMPORT
435 | extern __declspec(dllimport) const AVS_Linkage* const AVS_linkage;
436 | # else
437 | extern const AVS_Linkage* AVS_linkage;
438 | # endif
439 |
440 | # ifndef offsetof
441 | # include
442 | # endif
443 |
444 | # define AVS_BakedCode(arg) { arg ; }
445 | # define AVS_LinkCall(arg) !AVS_linkage || offsetof(AVS_Linkage, arg) >= AVS_linkage->Size ? 0 : (this->*(AVS_linkage->arg))
446 | # define AVS_LinkCall_Void(arg) !AVS_linkage || offsetof(AVS_Linkage, arg) >= AVS_linkage->Size ? (void)0 : (this->*(AVS_linkage->arg))
447 | # define AVS_LinkCallV(arg) !AVS_linkage || offsetof(AVS_Linkage, arg) >= AVS_linkage->Size ? *this : (this->*(AVS_linkage->arg))
448 | // Helper macros for fallback option when a function does not exists
449 | #define CALL_MEMBER_FN(object,ptrToMember) ((object)->*(ptrToMember))
450 | #define AVS_LinkCallOpt(arg, argOpt) !AVS_linkage ? 0 : \
451 | ( offsetof(AVS_Linkage, arg) >= AVS_linkage->Size ? \
452 | (offsetof(AVS_Linkage, argOpt) >= AVS_linkage->Size ? 0 : CALL_MEMBER_FN(this, AVS_linkage->argOpt)() ) : \
453 | CALL_MEMBER_FN(this, AVS_linkage->arg)() )
454 | // AVS_LinkCallOptDefault puts automatically () only after arg
455 | # define AVS_LinkCallOptDefault(arg, argDefaultValue) !AVS_linkage || offsetof(AVS_Linkage, arg) >= AVS_linkage->Size ? (argDefaultValue) : ((this->*(AVS_linkage->arg))())
456 |
457 | #endif
458 |
459 | class PDevice
460 | {
461 | public:
462 | PDevice() AVS_BakedCode(AVS_LinkCall_Void(PDevice_CONSTRUCTOR0)())
463 | PDevice(Device* p) AVS_BakedCode(AVS_LinkCall_Void(PDevice_CONSTRUCTOR1)(p))
464 | PDevice(const PDevice& p) AVS_BakedCode(AVS_LinkCall_Void(PDevice_CONSTRUCTOR2)(p))
465 | PDevice& operator=(Device* p) AVS_BakedCode(return AVS_LinkCallV(PDevice_OPERATOR_ASSIGN0)(p))
466 | PDevice& operator=(const PDevice& p) AVS_BakedCode(return AVS_LinkCallV(PDevice_OPERATOR_ASSIGN1)(p))
467 | ~PDevice() AVS_BakedCode(AVS_LinkCall_Void(PDevice_DESTRUCTOR)())
468 |
469 | int operator!() const { return !e; }
470 | operator void*() const { return e; }
471 | Device* operator->() const { return e; }
472 |
473 | AvsDeviceType GetType() const AVS_BakedCode(return AVS_LinkCallOptDefault(PDevice_GetType, DEV_TYPE_NONE))
474 | int GetId() const AVS_BakedCode(return AVS_LinkCall(PDevice_GetId)())
475 | int GetIndex() const AVS_BakedCode(return AVS_LinkCall(PDevice_GetIndex)())
476 | const char* GetName() const AVS_BakedCode(return AVS_LinkCall(PDevice_GetName)())
477 |
478 | private:
479 | Device * e;
480 |
481 | #ifdef BUILDING_AVSCORE
482 | public:
483 | void CONSTRUCTOR0(); /* Damn compiler won't allow taking the address of reserved constructs, make a dummy interlude */
484 | void CONSTRUCTOR1(Device* p);
485 | void CONSTRUCTOR2(const PDevice& p);
486 | PDevice& OPERATOR_ASSIGN0(Device* p);
487 | PDevice& OPERATOR_ASSIGN1(const PDevice& p);
488 | void DESTRUCTOR();
489 | #endif
490 | };
491 | struct VideoInfo {
492 | int width, height; // width=0 means no video
493 | unsigned fps_numerator, fps_denominator;
494 | int num_frames;
495 | // This is more extensible than previous versions. More properties can be added seeminglesly.
496 |
497 | // Colorspace properties.
498 | /*
499 |
500 | Planar match mask 1111.1000.0000.0111.0000.0111.0000.0111
501 | Planar signature 10xx.1000.0000.00xx.0000.00xx.00xx.00xx ?
502 | Planar signature 10xx.1000.0000.0xxx.0000.00xx.000x.x0xx ? *new
503 | Planar filter mask 1111.1111.1111.1111.1111.1111.1110.0111 (typo from old header fixed)
504 |
505 | pixel_type mapping
506 | ==================
507 | pixel_type bit-map PIYB.Z000.0???.0SSS.0000.0???.????.????
508 | planar YUV CCC HHH.000u.vWWW
509 | planar RGB(A) CCC AR
510 | nonplanar CCC 000.00wx xyAR
511 | Legend
512 | ======
513 | Planar YUV:
514 | Code Bits Remark
515 | W 0-2 Planar Width Subsampling bits
516 | Use (X+1) & 3 for GetPlaneWidthSubsampling
517 | 000 => 1 YV12, YV16, YUV420, YUV422
518 | 001 => 2 YV411, YUV9
519 | 010 => reserved
520 | 011 => 0 YV24, YUV444, RGBP
521 | 1xx => reserved
522 | v 3 VPlaneFirst YV12, YV16, YV24, YV411, YUV9
523 | u 4 UPlaneFirst I420
524 | H 7-9 Planar Height Subsampling bits
525 | Use ((X>>8)+1) & 3 for GetPlaneHeightSubsampling
526 | 000 => 1 YV12, YUV420
527 | 001 => 2 YUV9
528 | 010 => reserved
529 | 011 => 0 YV16, YV24, YV411, YUV422, YUV444, RGBP
530 | 1xx => reserved
531 |
532 | Planar RGB
533 | Code Bits Remark
534 | R 0 BGR, (with SSS bits for 8/16 bit/sample or float)
535 | A 1 BGRA, (with SSS bits for 8/16 bit/sample or float)
536 |
537 |
538 | Not Planar, Interleaved (I flag)
539 | Code Bits Remark
540 | R 0 BGR24, and BGRx in future (with SSS bits for 8/16 bit/sample or float)
541 | A 1 BGR32, and BGRAx in future (with SSS bits for 8/16 bit/sample or float)
542 | y 2 YUY2
543 | x 3-4 reserved
544 | w 5 Raw32
545 |
546 | General
547 | Code Bits Remark
548 | S 16-18 Sample resolution bits
549 | 000 => 8
550 | 001 => 16
551 | 010 => 32 (float)
552 | 011,100 => reserved
553 | 101 => 10 bits
554 | 110 => 12 bits
555 | 111 => 14 bits
556 | for packed RGB(A): only 8 and 16 bits are valid
557 |
558 | Other YV12 specific (not used?)
559 | C 20-22 Chroma Placement values 0-4 see CS_xxx_CHROMA_PLACEMENT
560 |
561 | Color family and layout
562 | Packed Planar Planar Planar
563 | Code Bits Remark RGB/RGBA YUV YUY2 Y_Grey RGB/RGBA YUVA
564 | R 0 1/0 - 0 - 1/0 -
565 | A 1 0/1 - 0 - 0/1 -
566 | y 2 - - 1 - 0 -
567 | Z 27 YUVA 0 0 0 0 1 1
568 | B 28 BGR 1 0 0 0 1* 0
569 | Y 29 YUV 0 1 1 1 0 0
570 | I 30 Interleaved 1 0 1 1 0 0
571 | P 31 Planar 0 1 0 1 1 1
572 | * Planar RGB plane order: G,B,R(,A)
573 |
574 | */
575 | enum {
576 | CS_YUVA = 1<<27,
577 | CS_BGR = 1<<28,
578 | CS_YUV = 1<<29,
579 | CS_INTERLEAVED = 1<<30,
580 | CS_PLANAR = 1<<31,
581 |
582 | CS_Shift_Sub_Width = 0,
583 | CS_Shift_Sub_Height = 8,
584 | CS_Shift_Sample_Bits = 16,
585 |
586 | CS_Sub_Width_Mask = 7 << CS_Shift_Sub_Width,
587 | CS_Sub_Width_1 = 3 << CS_Shift_Sub_Width, // YV24
588 | CS_Sub_Width_2 = 0 << CS_Shift_Sub_Width, // YV12, I420, YV16
589 | CS_Sub_Width_4 = 1 << CS_Shift_Sub_Width, // YUV9, YV411
590 |
591 | CS_VPlaneFirst = 1 << 3, // YV12, YV16, YV24, YV411, YUV9
592 | CS_UPlaneFirst = 1 << 4, // I420
593 |
594 | CS_Sub_Height_Mask = 7 << CS_Shift_Sub_Height,
595 | CS_Sub_Height_1 = 3 << CS_Shift_Sub_Height, // YV16, YV24, YV411
596 | CS_Sub_Height_2 = 0 << CS_Shift_Sub_Height, // YV12, I420
597 | CS_Sub_Height_4 = 1 << CS_Shift_Sub_Height, // YUV9
598 |
599 | CS_Sample_Bits_Mask = 7 << CS_Shift_Sample_Bits,
600 | CS_Sample_Bits_8 = 0 << CS_Shift_Sample_Bits,
601 | CS_Sample_Bits_10 = 5 << CS_Shift_Sample_Bits,
602 | CS_Sample_Bits_12 = 6 << CS_Shift_Sample_Bits,
603 | CS_Sample_Bits_14 = 7 << CS_Shift_Sample_Bits,
604 | CS_Sample_Bits_16 = 1 << CS_Shift_Sample_Bits,
605 | CS_Sample_Bits_32 = 2 << CS_Shift_Sample_Bits,
606 |
607 | CS_PLANAR_MASK = CS_PLANAR | CS_INTERLEAVED | CS_YUV | CS_BGR | CS_YUVA | CS_Sample_Bits_Mask
608 | | CS_Sub_Height_Mask | CS_Sub_Width_Mask,
609 | CS_PLANAR_FILTER = ~( CS_VPlaneFirst | CS_UPlaneFirst ),
610 |
611 | CS_RGB_TYPE = 1 << 0,
612 | CS_RGBA_TYPE = 1 << 1,
613 |
614 | // Specific colorformats
615 | CS_UNKNOWN = 0,
616 |
617 | CS_BGR24 = CS_RGB_TYPE | CS_BGR | CS_INTERLEAVED,
618 | CS_BGR32 = CS_RGBA_TYPE | CS_BGR | CS_INTERLEAVED,
619 | CS_YUY2 = 1<<2 | CS_YUV | CS_INTERLEAVED,
620 | // CS_YV12 = 1<<3 Reserved
621 | // CS_I420 = 1<<4 Reserved
622 | CS_RAW32 = 1<<5 | CS_INTERLEAVED,
623 |
624 | // YV12 must be 0xA000008 2.5 Baked API will see all new planar as YV12
625 | // I420 must be 0xA000010
626 |
627 | CS_GENERIC_YUV420 = CS_PLANAR | CS_YUV | CS_VPlaneFirst | CS_Sub_Height_2 | CS_Sub_Width_2, // 4:2:0 planar
628 | CS_GENERIC_YUV422 = CS_PLANAR | CS_YUV | CS_VPlaneFirst | CS_Sub_Height_1 | CS_Sub_Width_2, // 4:2:2 planar
629 | CS_GENERIC_YUV444 = CS_PLANAR | CS_YUV | CS_VPlaneFirst | CS_Sub_Height_1 | CS_Sub_Width_1, // 4:4:4 planar
630 | CS_GENERIC_Y = CS_PLANAR | CS_INTERLEAVED | CS_YUV, // Y only (4:0:0)
631 | CS_GENERIC_RGBP = CS_PLANAR | CS_BGR | CS_RGB_TYPE, // planar RGB. Though name is RGB but plane order G,B,R
632 | CS_GENERIC_RGBAP = CS_PLANAR | CS_BGR | CS_RGBA_TYPE, // planar RGBA
633 | CS_GENERIC_YUVA420 = CS_PLANAR | CS_YUVA | CS_VPlaneFirst | CS_Sub_Height_2 | CS_Sub_Width_2, // 4:2:0:A planar
634 | CS_GENERIC_YUVA422 = CS_PLANAR | CS_YUVA | CS_VPlaneFirst | CS_Sub_Height_1 | CS_Sub_Width_2, // 4:2:2:A planar
635 | CS_GENERIC_YUVA444 = CS_PLANAR | CS_YUVA | CS_VPlaneFirst | CS_Sub_Height_1 | CS_Sub_Width_1, // 4:4:4:A planar
636 |
637 | CS_YV24 = CS_GENERIC_YUV444 | CS_Sample_Bits_8, // YVU 4:4:4 planar
638 | CS_YV16 = CS_GENERIC_YUV422 | CS_Sample_Bits_8, // YVU 4:2:2 planar
639 | CS_YV12 = CS_GENERIC_YUV420 | CS_Sample_Bits_8, // YVU 4:2:0 planar
640 | CS_I420 = CS_PLANAR | CS_YUV | CS_Sample_Bits_8 | CS_UPlaneFirst | CS_Sub_Height_2 | CS_Sub_Width_2, // YUV 4:2:0 planar
641 | CS_IYUV = CS_I420,
642 | CS_YUV9 = CS_PLANAR | CS_YUV | CS_Sample_Bits_8 | CS_VPlaneFirst | CS_Sub_Height_4 | CS_Sub_Width_4, // YUV 4:1:0 planar
643 | CS_YV411 = CS_PLANAR | CS_YUV | CS_Sample_Bits_8 | CS_VPlaneFirst | CS_Sub_Height_1 | CS_Sub_Width_4, // YUV 4:1:1 planar
644 |
645 | CS_Y8 = CS_GENERIC_Y | CS_Sample_Bits_8, // Y 4:0:0 planar
646 |
647 | //-------------------------
648 | // AVS16: new planar constants go live! Experimental PF 160613
649 | // 10-12-14 bit + planar RGB + BRG48/64 160725
650 |
651 | CS_YUV444P10 = CS_GENERIC_YUV444 | CS_Sample_Bits_10, // YUV 4:4:4 10bit samples
652 | CS_YUV422P10 = CS_GENERIC_YUV422 | CS_Sample_Bits_10, // YUV 4:2:2 10bit samples
653 | CS_YUV420P10 = CS_GENERIC_YUV420 | CS_Sample_Bits_10, // YUV 4:2:0 10bit samples
654 | CS_Y10 = CS_GENERIC_Y | CS_Sample_Bits_10, // Y 4:0:0 10bit samples
655 |
656 | CS_YUV444P12 = CS_GENERIC_YUV444 | CS_Sample_Bits_12, // YUV 4:4:4 12bit samples
657 | CS_YUV422P12 = CS_GENERIC_YUV422 | CS_Sample_Bits_12, // YUV 4:2:2 12bit samples
658 | CS_YUV420P12 = CS_GENERIC_YUV420 | CS_Sample_Bits_12, // YUV 4:2:0 12bit samples
659 | CS_Y12 = CS_GENERIC_Y | CS_Sample_Bits_12, // Y 4:0:0 12bit samples
660 |
661 | CS_YUV444P14 = CS_GENERIC_YUV444 | CS_Sample_Bits_14, // YUV 4:4:4 14bit samples
662 | CS_YUV422P14 = CS_GENERIC_YUV422 | CS_Sample_Bits_14, // YUV 4:2:2 14bit samples
663 | CS_YUV420P14 = CS_GENERIC_YUV420 | CS_Sample_Bits_14, // YUV 4:2:0 14bit samples
664 | CS_Y14 = CS_GENERIC_Y | CS_Sample_Bits_14, // Y 4:0:0 14bit samples
665 |
666 | CS_YUV444P16 = CS_GENERIC_YUV444 | CS_Sample_Bits_16, // YUV 4:4:4 16bit samples
667 | CS_YUV422P16 = CS_GENERIC_YUV422 | CS_Sample_Bits_16, // YUV 4:2:2 16bit samples
668 | CS_YUV420P16 = CS_GENERIC_YUV420 | CS_Sample_Bits_16, // YUV 4:2:0 16bit samples
669 | CS_Y16 = CS_GENERIC_Y | CS_Sample_Bits_16, // Y 4:0:0 16bit samples
670 |
671 | // 32 bit samples (float)
672 | CS_YUV444PS = CS_GENERIC_YUV444 | CS_Sample_Bits_32, // YUV 4:4:4 32bit samples
673 | CS_YUV422PS = CS_GENERIC_YUV422 | CS_Sample_Bits_32, // YUV 4:2:2 32bit samples
674 | CS_YUV420PS = CS_GENERIC_YUV420 | CS_Sample_Bits_32, // YUV 4:2:0 32bit samples
675 | CS_Y32 = CS_GENERIC_Y | CS_Sample_Bits_32, // Y 4:0:0 32bit samples
676 |
677 | // RGB packed
678 | CS_BGR48 = CS_RGB_TYPE | CS_BGR | CS_INTERLEAVED | CS_Sample_Bits_16, // BGR 3x16 bit
679 | CS_BGR64 = CS_RGBA_TYPE | CS_BGR | CS_INTERLEAVED | CS_Sample_Bits_16, // BGR 4x16 bit
680 | // no packed 32 bit (float) support for these legacy types
681 |
682 | // RGB planar
683 | CS_RGBP = CS_GENERIC_RGBP | CS_Sample_Bits_8, // Planar RGB 8 bit samples
684 | CS_RGBP8 = CS_GENERIC_RGBP | CS_Sample_Bits_8, // Planar RGB 8 bit samples
685 | CS_RGBP10 = CS_GENERIC_RGBP | CS_Sample_Bits_10, // Planar RGB 10bit samples
686 | CS_RGBP12 = CS_GENERIC_RGBP | CS_Sample_Bits_12, // Planar RGB 12bit samples
687 | CS_RGBP14 = CS_GENERIC_RGBP | CS_Sample_Bits_14, // Planar RGB 14bit samples
688 | CS_RGBP16 = CS_GENERIC_RGBP | CS_Sample_Bits_16, // Planar RGB 16bit samples
689 | CS_RGBPS = CS_GENERIC_RGBP | CS_Sample_Bits_32, // Planar RGB 32bit samples
690 |
691 | // RGBA planar
692 | CS_RGBAP = CS_GENERIC_RGBAP | CS_Sample_Bits_8, // Planar RGBA 8 bit samples
693 | CS_RGBAP8 = CS_GENERIC_RGBAP | CS_Sample_Bits_8, // Planar RGBA 8 bit samples
694 | CS_RGBAP10 = CS_GENERIC_RGBAP | CS_Sample_Bits_10, // Planar RGBA 10bit samples
695 | CS_RGBAP12 = CS_GENERIC_RGBAP | CS_Sample_Bits_12, // Planar RGBA 12bit samples
696 | CS_RGBAP14 = CS_GENERIC_RGBAP | CS_Sample_Bits_14, // Planar RGBA 14bit samples
697 | CS_RGBAP16 = CS_GENERIC_RGBAP | CS_Sample_Bits_16, // Planar RGBA 16bit samples
698 | CS_RGBAPS = CS_GENERIC_RGBAP | CS_Sample_Bits_32, // Planar RGBA 32bit samples
699 |
700 | // Planar YUVA
701 | CS_YUVA444 = CS_GENERIC_YUVA444 | CS_Sample_Bits_8, // YUVA 4:4:4 8bit samples
702 | CS_YUVA422 = CS_GENERIC_YUVA422 | CS_Sample_Bits_8, // YUVA 4:2:2 8bit samples
703 | CS_YUVA420 = CS_GENERIC_YUVA420 | CS_Sample_Bits_8, // YUVA 4:2:0 8bit samples
704 |
705 | CS_YUVA444P10 = CS_GENERIC_YUVA444 | CS_Sample_Bits_10, // YUVA 4:4:4 10bit samples
706 | CS_YUVA422P10 = CS_GENERIC_YUVA422 | CS_Sample_Bits_10, // YUVA 4:2:2 10bit samples
707 | CS_YUVA420P10 = CS_GENERIC_YUVA420 | CS_Sample_Bits_10, // YUVA 4:2:0 10bit samples
708 |
709 | CS_YUVA444P12 = CS_GENERIC_YUVA444 | CS_Sample_Bits_12, // YUVA 4:4:4 12bit samples
710 | CS_YUVA422P12 = CS_GENERIC_YUVA422 | CS_Sample_Bits_12, // YUVA 4:2:2 12bit samples
711 | CS_YUVA420P12 = CS_GENERIC_YUVA420 | CS_Sample_Bits_12, // YUVA 4:2:0 12bit samples
712 |
713 | CS_YUVA444P14 = CS_GENERIC_YUVA444 | CS_Sample_Bits_14, // YUVA 4:4:4 14bit samples
714 | CS_YUVA422P14 = CS_GENERIC_YUVA422 | CS_Sample_Bits_14, // YUVA 4:2:2 14bit samples
715 | CS_YUVA420P14 = CS_GENERIC_YUVA420 | CS_Sample_Bits_14, // YUVA 4:2:0 14bit samples
716 |
717 | CS_YUVA444P16 = CS_GENERIC_YUVA444 | CS_Sample_Bits_16, // YUVA 4:4:4 16bit samples
718 | CS_YUVA422P16 = CS_GENERIC_YUVA422 | CS_Sample_Bits_16, // YUVA 4:2:2 16bit samples
719 | CS_YUVA420P16 = CS_GENERIC_YUVA420 | CS_Sample_Bits_16, // YUVA 4:2:0 16bit samples
720 |
721 | CS_YUVA444PS = CS_GENERIC_YUVA444 | CS_Sample_Bits_32, // YUVA 4:4:4 32bit samples
722 | CS_YUVA422PS = CS_GENERIC_YUVA422 | CS_Sample_Bits_32, // YUVA 4:2:2 32bit samples
723 | CS_YUVA420PS = CS_GENERIC_YUVA420 | CS_Sample_Bits_32, // YUVA 4:2:0 32bit samples
724 |
725 | };
726 |
727 | int pixel_type; // changed to int as of 2.5
728 |
729 |
730 | int audio_samples_per_second; // 0 means no audio
731 | int sample_type; // as of 2.5
732 | int64_t num_audio_samples; // changed as of 2.5
733 | int nchannels; // as of 2.5
734 |
735 | // Imagetype properties
736 |
737 | int image_type;
738 |
739 | enum {
740 | IT_BFF = 1<<0,
741 | IT_TFF = 1<<1,
742 | IT_FIELDBASED = 1<<2
743 | };
744 |
745 | // Chroma placement bits 20 -> 23 ::FIXME:: Really want a Class to support this
746 | enum {
747 | CS_UNKNOWN_CHROMA_PLACEMENT = 0 << 20,
748 | CS_MPEG1_CHROMA_PLACEMENT = 1 << 20,
749 | CS_MPEG2_CHROMA_PLACEMENT = 2 << 20,
750 | CS_YUY2_CHROMA_PLACEMENT = 3 << 20,
751 | CS_TOPLEFT_CHROMA_PLACEMENT = 4 << 20
752 | };
753 |
754 | // useful functions of the above
755 | bool HasVideo() const AVS_BakedCode(return AVS_LinkCall(HasVideo)())
756 | bool HasAudio() const AVS_BakedCode(return AVS_LinkCall(HasAudio)())
757 | bool IsRGB() const AVS_BakedCode(return AVS_LinkCall(IsRGB)())
758 | bool IsRGB24() const AVS_BakedCode(return AVS_LinkCall(IsRGB24)())
759 | bool IsRGB32() const AVS_BakedCode(return AVS_LinkCall(IsRGB32)())
760 | bool IsYUV() const AVS_BakedCode(return AVS_LinkCall(IsYUV)())
761 | bool IsYUY2() const AVS_BakedCode(return AVS_LinkCall(IsYUY2)())
762 |
763 | bool IsYV24() const AVS_BakedCode(return AVS_LinkCall(IsYV24)())
764 | bool IsYV16() const AVS_BakedCode(return AVS_LinkCall(IsYV16)())
765 | bool IsYV12() const AVS_BakedCode(return AVS_LinkCall(IsYV12)())
766 | bool IsYV411() const AVS_BakedCode(return AVS_LinkCall(IsYV411)())
767 | //bool IsYUV9() const;
768 | bool IsY8() const AVS_BakedCode(return AVS_LinkCall(IsY8)())
769 |
770 | bool IsColorSpace(int c_space) const AVS_BakedCode(return AVS_LinkCall(IsColorSpace)(c_space))
771 |
772 | bool Is(int property) const AVS_BakedCode(return AVS_LinkCall(Is)(property))
773 | bool IsPlanar() const AVS_BakedCode(return AVS_LinkCall(IsPlanar)())
774 | bool IsFieldBased() const AVS_BakedCode(return AVS_LinkCall(IsFieldBased)())
775 | bool IsParityKnown() const AVS_BakedCode(return AVS_LinkCall(IsParityKnown)())
776 | bool IsBFF() const AVS_BakedCode(return AVS_LinkCall(IsBFF)())
777 | bool IsTFF() const AVS_BakedCode(return AVS_LinkCall(IsTFF)())
778 |
779 | bool IsVPlaneFirst() const AVS_BakedCode(return AVS_LinkCall(IsVPlaneFirst)()) // Don't use this
780 | // Will not work on planar images, but will return only luma planes
781 | int BytesFromPixels(int pixels) const AVS_BakedCode(return AVS_LinkCall(BytesFromPixels)(pixels))
782 | int RowSize(int plane = 0) const AVS_BakedCode(return AVS_LinkCall(RowSize)(plane))
783 | int BMPSize() const AVS_BakedCode(return AVS_LinkCall(BMPSize)())
784 |
785 | int64_t AudioSamplesFromFrames(int frames) const AVS_BakedCode(return AVS_LinkCall(AudioSamplesFromFrames)(frames))
786 | int FramesFromAudioSamples(int64_t samples) const AVS_BakedCode(return AVS_LinkCall(FramesFromAudioSamples)(samples))
787 | int64_t AudioSamplesFromBytes(int64_t bytes) const AVS_BakedCode(return AVS_LinkCall(AudioSamplesFromBytes)(bytes))
788 | int64_t BytesFromAudioSamples(int64_t samples) const AVS_BakedCode(return AVS_LinkCall(BytesFromAudioSamples)(samples))
789 | int AudioChannels() const AVS_BakedCode(return AVS_LinkCall(AudioChannels)())
790 | int SampleType() const AVS_BakedCode(return AVS_LinkCall(SampleType)())
791 | bool IsSampleType(int testtype) const AVS_BakedCode(return AVS_LinkCall(IsSampleType)(testtype))
792 | int SamplesPerSecond() const AVS_BakedCode(return AVS_LinkCall(SamplesPerSecond)())
793 | int BytesPerAudioSample() const AVS_BakedCode(return AVS_LinkCall(BytesPerAudioSample)())
794 | void SetFieldBased(bool isfieldbased) AVS_BakedCode(AVS_LinkCall_Void(SetFieldBased)(isfieldbased))
795 | void Set(int property) AVS_BakedCode(AVS_LinkCall_Void(Set)(property))
796 | void Clear(int property) AVS_BakedCode(AVS_LinkCall_Void(Clear)(property))
797 | // Subsampling in bitshifts!
798 | int GetPlaneWidthSubsampling(int plane) const AVS_BakedCode(return AVS_LinkCall(GetPlaneWidthSubsampling)(plane))
799 | int GetPlaneHeightSubsampling(int plane) const AVS_BakedCode(return AVS_LinkCall(GetPlaneHeightSubsampling)(plane))
800 | int BitsPerPixel() const AVS_BakedCode(return AVS_LinkCall(BitsPerPixel)())
801 |
802 | int BytesPerChannelSample() const AVS_BakedCode(return AVS_LinkCall(BytesPerChannelSample)())
803 |
804 | // useful mutator
805 | void SetFPS(unsigned numerator, unsigned denominator) AVS_BakedCode(AVS_LinkCall_Void(SetFPS)(numerator, denominator))
806 |
807 | // Range protected multiply-divide of FPS
808 | void MulDivFPS(unsigned multiplier, unsigned divisor) AVS_BakedCode(AVS_LinkCall_Void(MulDivFPS)(multiplier, divisor))
809 |
810 | // Test for same colorspace
811 | bool IsSameColorspace(const VideoInfo& vi) const AVS_BakedCode(return AVS_LinkCall(IsSameColorspace)(vi))
812 |
813 | // AVS+ extensions
814 | // 20161005:
815 | // Mapping of AVS+ extensions to classic 2.6 functions.
816 | // In order to use these extended AVS+ functions for plugins that should work
817 | // either with AVS+ or with Classic (8 bit) Avs 2.6 ans earlier AVS+ versions, there is an
818 | // automatic fallback mechanism.
819 | // From AVS+'s point of view these are not "baked" codes, the primary functions should exist.
820 | // Examples:
821 | // Is444() is mapped to IsYV24() for classic AVS2.6
822 | // ComponentSize() returns constant 1 (1 bytes per pixel component)
823 | // BitsPerComponent() returns constant 8 (Classic AVS2.6 is 8 bit only)
824 |
825 | // Returns the number of color channels or planes in a frame
826 | int NumComponents() const AVS_BakedCode(return AVS_LinkCallOptDefault(NumComponents, (((AVS_LinkCall(IsYUV)()) && !(AVS_LinkCall(IsY8)())) ? 3 : AVS_LinkCall(BytesFromPixels)(1)) ) )
827 |
828 | // Returns the size in bytes of a single component of a pixel
829 | int ComponentSize() const AVS_BakedCode(return AVS_LinkCallOptDefault(ComponentSize, 1))
830 |
831 | // Returns the bit depth of a single component of a pixel
832 | int BitsPerComponent() const AVS_BakedCode(return AVS_LinkCallOptDefault(BitsPerComponent, 8))
833 |
834 | // like IsYV24, but bit-depth independent also for YUVA
835 | bool Is444() const AVS_BakedCode(return AVS_LinkCallOpt(Is444, IsYV24) )
836 |
837 | // like IsYV16, but bit-depth independent also for YUVA
838 | bool Is422() const AVS_BakedCode(return AVS_LinkCallOpt(Is422, IsYV16) )
839 |
840 | // like IsYV12, but bit-depth independent also for YUVA
841 | bool Is420() const AVS_BakedCode( return AVS_LinkCallOpt(Is420, IsYV12) )
842 |
843 | // like IsY8, but bit-depth independent
844 | bool IsY() const AVS_BakedCode( return AVS_LinkCallOpt(IsY, IsY8) )
845 |
846 | // like IsRGB24 for 16 bit samples
847 | bool IsRGB48() const AVS_BakedCode( return AVS_LinkCallOptDefault(IsRGB48, false) )
848 |
849 | // like IsRGB32 for 16 bit samples
850 | bool IsRGB64() const AVS_BakedCode( return AVS_LinkCallOptDefault(IsRGB64, false) )
851 |
852 | // YUVA?
853 | bool IsYUVA() const AVS_BakedCode( return AVS_LinkCallOptDefault(IsYUVA, false) )
854 |
855 | // Planar RGB?
856 | bool IsPlanarRGB() const AVS_BakedCode( return AVS_LinkCallOptDefault(IsPlanarRGB, false) )
857 |
858 | // Planar RGBA?
859 | bool IsPlanarRGBA() const AVS_BakedCode( return AVS_LinkCallOptDefault(IsPlanarRGBA, false) )
860 |
861 | }; // end struct VideoInfo
862 |
863 |
864 |
865 |
866 | // VideoFrameBuffer holds information about a memory block which is used
867 | // for video data. For efficiency, instances of this class are not deleted
868 | // when the refcount reaches zero; instead they're stored in a linked list
869 | // to be reused. The instances are deleted when the corresponding AVS
870 | // file is closed.
871 |
872 | class VideoFrameBuffer {
873 | BYTE* data;
874 | int data_size;
875 | // sequence_number is incremented every time the buffer is changed, so
876 | // that stale views can tell they're no longer valid.
877 | volatile long sequence_number;
878 |
879 | friend class VideoFrame;
880 | friend class Cache;
881 | friend class ScriptEnvironment;
882 | volatile long refcount;
883 |
884 | // AVS+CUDA extension, does not break plugins if appended here
885 | Device* device;
886 |
887 | protected:
888 | VideoFrameBuffer(int size, int margin, Device* device);
889 | VideoFrameBuffer();
890 | ~VideoFrameBuffer();
891 |
892 | public:
893 | const BYTE* GetReadPtr() const AVS_BakedCode( return AVS_LinkCall(VFBGetReadPtr)() )
894 | BYTE* GetWritePtr() AVS_BakedCode( return AVS_LinkCall(VFBGetWritePtr)() )
895 | int GetDataSize() const AVS_BakedCode( return AVS_LinkCall(GetDataSize)() )
896 | int GetSequenceNumber() const AVS_BakedCode( return AVS_LinkCall(GetSequenceNumber)() )
897 | int GetRefcount() const AVS_BakedCode( return AVS_LinkCall(GetRefcount)() )
898 |
899 | // Ensure VideoFrameBuffer cannot be publicly assigned
900 | private:
901 | VideoFrameBuffer& operator=(const VideoFrameBuffer&);
902 |
903 | }; // end class VideoFrameBuffer
904 |
905 |
906 | // smart pointer to VideoFrame
907 | class PVideoFrame {
908 |
909 | VideoFrame* p;
910 |
911 | void Init(VideoFrame* x);
912 | void Set(VideoFrame* x);
913 |
914 | public:
915 | PVideoFrame() AVS_BakedCode(AVS_LinkCall_Void(PVideoFrame_CONSTRUCTOR0)())
916 | PVideoFrame(const PVideoFrame& x) AVS_BakedCode(AVS_LinkCall_Void(PVideoFrame_CONSTRUCTOR1)(x))
917 | PVideoFrame(VideoFrame* x) AVS_BakedCode(AVS_LinkCall_Void(PVideoFrame_CONSTRUCTOR2)(x))
918 | void operator=(VideoFrame* x) AVS_BakedCode(AVS_LinkCall_Void(PVideoFrame_OPERATOR_ASSIGN0)(x))
919 | void operator=(const PVideoFrame& x) AVS_BakedCode(AVS_LinkCall_Void(PVideoFrame_OPERATOR_ASSIGN1)(x))
920 |
921 | VideoFrame* operator->() const { return p; }
922 |
923 | // for conditional expressions
924 | operator void*() const { return p; }
925 | bool operator!() const { return !p; }
926 |
927 | ~PVideoFrame() AVS_BakedCode(AVS_LinkCall_Void(PVideoFrame_DESTRUCTOR)())
928 | #ifdef BUILDING_AVSCORE
929 | public:
930 | void CONSTRUCTOR0(); /* Damn compiler won't allow taking the address of reserved constructs, make a dummy interlude */
931 | void CONSTRUCTOR1(const PVideoFrame& x);
932 | void CONSTRUCTOR2(VideoFrame* x);
933 | void OPERATOR_ASSIGN0(VideoFrame* x);
934 | void OPERATOR_ASSIGN1(const PVideoFrame& x);
935 | void DESTRUCTOR();
936 | #endif
937 | }; // end class PVideoFrame
938 |
939 |
940 | // VideoFrame holds a "window" into a VideoFrameBuffer. Operator new
941 | // is overloaded to recycle class instances.
942 |
943 | class VideoFrame {
944 | volatile long refcount;
945 | VideoFrameBuffer* vfb;
946 |
947 | // Due to technical reasons these members are not const, but should be treated as such.
948 | // That means do not modify them once the class has been constructed.
949 | int offset;
950 | int pitch, row_size, height;
951 | int offsetU, offsetV; // U&V offsets are from top of picture.
952 | int pitchUV, row_sizeUV, heightUV; // for Planar RGB offsetU, offsetV is for the 2nd and 3rd Plane.
953 | // for Planar RGB pitchUV and row_sizeUV = 0, because when no VideoInfo (MakeWriteable)
954 | // the decision on existance of UV is checked by zero pitch
955 | // AVS+ extension, does not break plugins if appended here
956 | int offsetA;
957 | int pitchA, row_sizeA; // 4th alpha plane support, pitch and row_size is 0 is none
958 |
959 | AVSMap *properties;
960 |
961 | friend class PVideoFrame;
962 | void AddRef();
963 | void Release();
964 |
965 | friend class ScriptEnvironment;
966 | friend class Cache;
967 |
968 | VideoFrame(VideoFrameBuffer* _vfb, AVSMap* avsmap, int _offset, int _pitch, int _row_size, int _height);
969 | VideoFrame(VideoFrameBuffer* _vfb, AVSMap* avsmap, int _offset, int _pitch, int _row_size, int _height, int _offsetU, int _offsetV, int _pitchUV, int _row_sizeUV, int _heightUV);
970 | // for Alpha
971 | VideoFrame(VideoFrameBuffer* _vfb, AVSMap* avsmap, int _offset, int _pitch, int _row_size, int _height, int _offsetU, int _offsetV, int _pitchUV, int _row_sizeUV, int _heightUV, int _offsetA);
972 | void* operator new(size_t size);
973 | // TESTME: OFFSET U/V may be switched to what could be expected from AVI standard!
974 | public:
975 | int GetPitch(int plane=0) const AVS_BakedCode( return AVS_LinkCall(GetPitch)(plane) )
976 | int GetRowSize(int plane=0) const AVS_BakedCode( return AVS_LinkCall(GetRowSize)(plane) )
977 | int GetHeight(int plane=0) const AVS_BakedCode( return AVS_LinkCall(GetHeight)(plane) )
978 |
979 | // generally you shouldn't use these three
980 | VideoFrameBuffer* GetFrameBuffer() const AVS_BakedCode( return AVS_LinkCall(GetFrameBuffer)() )
981 | int GetOffset(int plane=0) const AVS_BakedCode( return AVS_LinkCall(GetOffset)(plane) )
982 |
983 | // in plugins use env->SubFrame() -- because implementation code is only available inside avisynth.dll. Doh!
984 | VideoFrame* Subframe(int rel_offset, int new_pitch, int new_row_size, int new_height) const;
985 | VideoFrame* Subframe(int rel_offset, int new_pitch, int new_row_size, int new_height, int rel_offsetU, int rel_offsetV, int pitchUV) const;
986 | // for Alpha
987 | VideoFrame* Subframe(int rel_offset, int new_pitch, int new_row_size, int new_height, int rel_offsetU, int rel_offsetV, int pitchUV, int rel_offsetA) const;
988 |
989 | const BYTE* GetReadPtr(int plane=0) const AVS_BakedCode( return AVS_LinkCall(VFGetReadPtr)(plane) )
990 | bool IsWritable() const AVS_BakedCode( return AVS_LinkCall(IsWritable)() )
991 | BYTE* GetWritePtr(int plane=0) const AVS_BakedCode( return AVS_LinkCall(VFGetWritePtr)(plane) )
992 |
993 | AVSMap& getProperties() AVS_BakedCode(return AVS_LinkCallOptDefault(getProperties, (AVSMap&)*(AVSMap*)0))
994 | const AVSMap& getConstProperties() AVS_BakedCode(return AVS_LinkCallOptDefault(getConstProperties, (const AVSMap&)*(const AVSMap*)0))
995 | void setProperties(const AVSMap & _properties) AVS_BakedCode(AVS_LinkCall_Void(setProperties)(_properties))
996 |
997 | PDevice GetDevice() const AVS_BakedCode(return AVS_LinkCall(VideoFrame_GetDevice)())
998 |
999 | // 0: OK, 1: NG, -1: disabled or non CPU frame
1000 | int CheckMemory() const AVS_BakedCode(return AVS_LinkCall(VideoFrame_CheckMemory)())
1001 |
1002 | ~VideoFrame() AVS_BakedCode( AVS_LinkCall_Void(VideoFrame_DESTRUCTOR)() )
1003 | #ifdef BUILDING_AVSCORE
1004 | public:
1005 | void DESTRUCTOR(); /* Damn compiler won't allow taking the address of reserved constructs, make a dummy interlude */
1006 | #endif
1007 |
1008 | // Ensure VideoFrame cannot be publicly assigned
1009 | private:
1010 | VideoFrame& operator=(const VideoFrame&);
1011 |
1012 | }; // end class VideoFrame
1013 |
1014 | enum CachePolicyHint {
1015 | // Values 0 to 5 are reserved for old 2.5 plugins
1016 | // do not use them in new plugins
1017 |
1018 | // New 2.6 explicitly defined cache hints.
1019 | CACHE_NOTHING=10, // Do not cache video.
1020 | CACHE_WINDOW=11, // Hard protect upto X frames within a range of X from the current frame N.
1021 | CACHE_GENERIC=12, // LRU cache upto X frames.
1022 | CACHE_FORCE_GENERIC=13, // LRU cache upto X frames, override any previous CACHE_WINDOW.
1023 |
1024 | CACHE_GET_POLICY=30, // Get the current policy.
1025 | CACHE_GET_WINDOW=31, // Get the current window h_span.
1026 | CACHE_GET_RANGE=32, // Get the current generic frame range.
1027 |
1028 | CACHE_AUDIO=50, // Explicitly cache audio, X byte cache.
1029 | CACHE_AUDIO_NOTHING=51, // Explicitly do not cache audio.
1030 | CACHE_AUDIO_NONE=52, // Audio cache off (auto mode), X byte intial cache.
1031 | CACHE_AUDIO_AUTO=53, // Audio cache on (auto mode), X byte intial cache.
1032 |
1033 | CACHE_GET_AUDIO_POLICY=70, // Get the current audio policy.
1034 | CACHE_GET_AUDIO_SIZE=71, // Get the current audio cache size.
1035 |
1036 | CACHE_PREFETCH_FRAME=100, // Queue request to prefetch frame N.
1037 | CACHE_PREFETCH_GO=101, // Action video prefetches.
1038 |
1039 | CACHE_PREFETCH_AUDIO_BEGIN=120, // Begin queue request transaction to prefetch audio (take critical section).
1040 | CACHE_PREFETCH_AUDIO_STARTLO=121, // Set low 32 bits of start.
1041 | CACHE_PREFETCH_AUDIO_STARTHI=122, // Set high 32 bits of start.
1042 | CACHE_PREFETCH_AUDIO_COUNT=123, // Set low 32 bits of length.
1043 | CACHE_PREFETCH_AUDIO_COMMIT=124, // Enqueue request transaction to prefetch audio (release critical section).
1044 | CACHE_PREFETCH_AUDIO_GO=125, // Action audio prefetches.
1045 |
1046 | CACHE_GETCHILD_CACHE_MODE=200, // Cache ask Child for desired video cache mode.
1047 | CACHE_GETCHILD_CACHE_SIZE=201, // Cache ask Child for desired video cache size.
1048 | CACHE_GETCHILD_AUDIO_MODE=202, // Cache ask Child for desired audio cache mode.
1049 | CACHE_GETCHILD_AUDIO_SIZE=203, // Cache ask Child for desired audio cache size.
1050 |
1051 | CACHE_GETCHILD_COST=220, // Cache ask Child for estimated processing cost.
1052 | CACHE_COST_ZERO=221, // Child response of zero cost (ptr arithmetic only).
1053 | CACHE_COST_UNIT=222, // Child response of unit cost (less than or equal 1 full frame blit).
1054 | CACHE_COST_LOW=223, // Child response of light cost. (Fast)
1055 | CACHE_COST_MED=224, // Child response of medium cost. (Real time)
1056 | CACHE_COST_HI=225, // Child response of heavy cost. (Slow)
1057 |
1058 | CACHE_GETCHILD_THREAD_MODE=240, // Cache ask Child for thread safetyness.
1059 | CACHE_THREAD_UNSAFE=241, // Only 1 thread allowed for all instances. 2.5 filters default!
1060 | CACHE_THREAD_CLASS=242, // Only 1 thread allowed for each instance. 2.6 filters default!
1061 | CACHE_THREAD_SAFE=243, // Allow all threads in any instance.
1062 | CACHE_THREAD_OWN=244, // Safe but limit to 1 thread, internally threaded.
1063 |
1064 | CACHE_GETCHILD_ACCESS_COST=260, // Cache ask Child for preferred access pattern.
1065 | CACHE_ACCESS_RAND=261, // Filter is access order agnostic.
1066 | CACHE_ACCESS_SEQ0=262, // Filter prefers sequential access (low cost)
1067 | CACHE_ACCESS_SEQ1=263, // Filter needs sequential access (high cost)
1068 |
1069 | CACHE_AVSPLUS_CONSTANTS = 500, // Smaller values are reserved for classic Avisynth
1070 |
1071 | CACHE_DONT_CACHE_ME, // Filters that don't need caching (eg. trim, cache etc.) should return 1 to this request
1072 | CACHE_SET_MIN_CAPACITY,
1073 | CACHE_SET_MAX_CAPACITY,
1074 | CACHE_GET_MIN_CAPACITY,
1075 | CACHE_GET_MAX_CAPACITY,
1076 | CACHE_GET_SIZE,
1077 | CACHE_GET_REQUESTED_CAP,
1078 | CACHE_GET_CAPACITY,
1079 | CACHE_GET_MTMODE,
1080 |
1081 | CACHE_IS_CACHE_REQ,
1082 | CACHE_IS_CACHE_ANS,
1083 | CACHE_IS_MTGUARD_REQ,
1084 | CACHE_IS_MTGUARD_ANS,
1085 |
1086 | CACHE_AVSPLUS_CUDA_CONSTANTS = 600,
1087 |
1088 | CACHE_GET_DEV_TYPE, // Device types a filter can return
1089 | CACHE_GET_CHILD_DEV_TYPE, // Device types a fitler can receive
1090 |
1091 | CACHE_USER_CONSTANTS = 1000 // Smaller values are reserved for the core
1092 |
1093 | };
1094 |
1095 | // Base class for all filters.
1096 | class IClip {
1097 | friend class PClip;
1098 | friend class AVSValue;
1099 | volatile long refcnt;
1100 | void AddRef();
1101 | #if BUILDING_AVSCORE
1102 | public:
1103 | #endif
1104 | void Release();
1105 | public:
1106 | IClip() : refcnt(0) {}
1107 | virtual int __stdcall GetVersion() { return AVISYNTH_INTERFACE_VERSION; }
1108 | virtual PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) = 0;
1109 | virtual bool __stdcall GetParity(int n) = 0; // return field parity if field_based, else parity of first field in frame
1110 | virtual void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) = 0; // start and count are in samples
1111 | /* Need to check GetVersion first, pre v5 will return random crap from EAX reg. */
1112 | virtual int __stdcall SetCacheHints(int cachehints,int frame_range) = 0 ; // We do not pass cache requests upwards, only to the next filter.
1113 | virtual const VideoInfo& __stdcall GetVideoInfo() = 0;
1114 | virtual ~IClip() {}
1115 | }; // end class IClip
1116 |
1117 |
1118 | // smart pointer to IClip
1119 | class PClip {
1120 |
1121 | IClip* p;
1122 |
1123 | IClip* GetPointerWithAddRef() const;
1124 | friend class AVSValue;
1125 | friend class VideoFrame;
1126 |
1127 | void Init(IClip* x);
1128 | void Set(IClip* x);
1129 |
1130 | public:
1131 | PClip() AVS_BakedCode( AVS_LinkCall_Void(PClip_CONSTRUCTOR0)() )
1132 | PClip(const PClip& x) AVS_BakedCode( AVS_LinkCall_Void(PClip_CONSTRUCTOR1)(x) )
1133 | PClip(IClip* x) AVS_BakedCode( AVS_LinkCall_Void(PClip_CONSTRUCTOR2)(x) )
1134 | void operator=(IClip* x) AVS_BakedCode( AVS_LinkCall_Void(PClip_OPERATOR_ASSIGN0)(x) )
1135 | void operator=(const PClip& x) AVS_BakedCode( AVS_LinkCall_Void(PClip_OPERATOR_ASSIGN1)(x) )
1136 |
1137 | IClip* operator->() const { return p; }
1138 |
1139 | // useful in conditional expressions
1140 | operator void*() const { return p; }
1141 | bool operator!() const { return !p; }
1142 |
1143 | ~PClip() AVS_BakedCode( AVS_LinkCall_Void(PClip_DESTRUCTOR)() )
1144 | #ifdef BUILDING_AVSCORE
1145 | public:
1146 | void CONSTRUCTOR0(); /* Damn compiler won't allow taking the address of reserved constructs, make a dummy interlude */
1147 | void CONSTRUCTOR1(const PClip& x);
1148 | void CONSTRUCTOR2(IClip* x);
1149 | void OPERATOR_ASSIGN0(IClip* x);
1150 | void OPERATOR_ASSIGN1(const PClip& x);
1151 | void DESTRUCTOR();
1152 | #endif
1153 | }; // end class PClip
1154 |
1155 | // enums for frame property functions
1156 | enum AVSPropTypes {
1157 | PROPTYPE_UNSET = 'u', // ptUnset
1158 | PROPTYPE_INT = 'i', // peType
1159 | PROPTYPE_FLOAT = 'f', // ptFloat
1160 | PROPTYPE_DATA = 's', // ptData
1161 | PROPTYPE_CLIP = 'c', // ptClip
1162 | PROPTYPE_FRAME = 'v' // ptFrame
1163 | // ptFunction = 'm'
1164 | };
1165 |
1166 | enum AVSGetPropErrors {
1167 | GETPROPERROR_UNSET = 1, // peUnset
1168 | GETPROPERROR_TYPE = 2, // peType
1169 | GETPROPERROR_INDEX = 4 // peIndex
1170 | };
1171 |
1172 | enum AVSPropAppendMode {
1173 | PROPAPPENDMODE_REPLACE = 0, // paReplace
1174 | PROPAPPENDMODE_APPEND = 1, // paAppend
1175 | PROPAPPENDMODE_TOUCH = 2 // paTouch
1176 | };
1177 |
1178 |
1179 | class AVSValue {
1180 | public:
1181 |
1182 | AVSValue() AVS_BakedCode( AVS_LinkCall_Void(AVSValue_CONSTRUCTOR0)() )
1183 | AVSValue(IClip* c) AVS_BakedCode( AVS_LinkCall_Void(AVSValue_CONSTRUCTOR1)(c) )
1184 | AVSValue(const PClip& c) AVS_BakedCode( AVS_LinkCall_Void(AVSValue_CONSTRUCTOR2)(c) )
1185 | AVSValue(bool b) AVS_BakedCode( AVS_LinkCall_Void(AVSValue_CONSTRUCTOR3)(b) )
1186 | AVSValue(int i) AVS_BakedCode( AVS_LinkCall_Void(AVSValue_CONSTRUCTOR4)(i) )
1187 | // AVSValue(int64_t l);
1188 | AVSValue(float f) AVS_BakedCode( AVS_LinkCall_Void(AVSValue_CONSTRUCTOR5)(f) )
1189 | AVSValue(double f) AVS_BakedCode( AVS_LinkCall_Void(AVSValue_CONSTRUCTOR6)(f) )
1190 | AVSValue(const char* s) AVS_BakedCode( AVS_LinkCall_Void(AVSValue_CONSTRUCTOR7)(s) )
1191 | AVSValue(const AVSValue* a, int size) AVS_BakedCode( AVS_LinkCall_Void(AVSValue_CONSTRUCTOR8)(a, size) )
1192 | AVSValue(const AVSValue& a, int size) AVS_BakedCode( AVS_LinkCall_Void(AVSValue_CONSTRUCTOR8)(&a, size) )
1193 | AVSValue(const AVSValue& v) AVS_BakedCode( AVS_LinkCall_Void(AVSValue_CONSTRUCTOR9)(v) )
1194 | AVSValue(const PFunction& n) AVS_BakedCode(AVS_LinkCall_Void(AVSValue_CONSTRUCTOR11)(n))
1195 |
1196 | ~AVSValue() AVS_BakedCode( AVS_LinkCall_Void(AVSValue_DESTRUCTOR)() )
1197 | AVSValue& operator=(const AVSValue& v) AVS_BakedCode( return AVS_LinkCallV(AVSValue_OPERATOR_ASSIGN)(v) )
1198 |
1199 | // Note that we transparently allow 'int' to be treated as 'float'.
1200 | // There are no int<->bool conversions, though.
1201 |
1202 | bool Defined() const AVS_BakedCode( return AVS_LinkCall(Defined)() )
1203 | bool IsClip() const AVS_BakedCode( return AVS_LinkCall(IsClip)() )
1204 | bool IsBool() const AVS_BakedCode( return AVS_LinkCall(IsBool)() )
1205 | bool IsInt() const AVS_BakedCode( return AVS_LinkCall(IsInt)() )
1206 | // bool IsLong() const;
1207 | bool IsFloat() const AVS_BakedCode( return AVS_LinkCall(IsFloat)() )
1208 | bool IsString() const AVS_BakedCode( return AVS_LinkCall(IsString)() )
1209 | bool IsArray() const AVS_BakedCode(return AVS_LinkCall(IsArray)())
1210 | bool IsFunction() const AVS_BakedCode( return AVS_LinkCall(IsFunction)() )
1211 |
1212 | PClip AsClip() const AVS_BakedCode( return AVS_LinkCall(AsClip)() )
1213 | bool AsBool() const AVS_BakedCode( return AVS_LinkCall(AsBool1)() )
1214 | int AsInt() const AVS_BakedCode( return AVS_LinkCall(AsInt1)() )
1215 | // int AsLong() const;
1216 | const char* AsString() const AVS_BakedCode( return AVS_LinkCall(AsString1)() )
1217 | double AsFloat() const AVS_BakedCode( return AVS_LinkCall(AsFloat1)() )
1218 | float AsFloatf() const AVS_BakedCode( return float( AVS_LinkCall(AsFloat1)() ) )
1219 |
1220 | bool AsBool(bool def) const AVS_BakedCode( return AVS_LinkCall(AsBool2)(def) )
1221 | int AsInt(int def) const AVS_BakedCode( return AVS_LinkCall(AsInt2)(def) )
1222 | double AsDblDef(double def) const AVS_BakedCode( return AVS_LinkCall(AsDblDef)(def) ) // Value is still a float
1223 | double AsFloat(float def) const AVS_BakedCode( return AVS_LinkCall(AsFloat2)(def) )
1224 | float AsFloatf(float def) const AVS_BakedCode( return float( AVS_LinkCall(AsFloat2)(def) ) )
1225 | const char* AsString(const char* def) const AVS_BakedCode( return AVS_LinkCall(AsString2)(def) )
1226 | PFunction AsFunction() const; // internal use only
1227 |
1228 | int ArraySize() const AVS_BakedCode( return AVS_LinkCall(ArraySize)() )
1229 |
1230 | const AVSValue& operator[](int index) const AVS_BakedCode( return AVS_LinkCallV(AVSValue_OPERATOR_INDEX)(index) )
1231 |
1232 | private:
1233 |
1234 | short type; // 'a'rray, 'c'lip, 'b'ool, 'i'nt, 'f'loat, 's'tring, 'v'oid, fu'n'ction, or RFU: 'l'ong ('d'ouble)
1235 | short array_size;
1236 | union {
1237 | IClip* clip;
1238 | bool boolean;
1239 | int integer;
1240 | float floating_pt;
1241 | const char* string;
1242 | const AVSValue* array;
1243 | IFunction* function;
1244 | #ifdef X86_64
1245 | // if ever, only x64 will support. It breaks struct size on 32 bit
1246 | int64_t longlong; // 8 bytes
1247 | double double_pt; // 8 bytes
1248 | #endif
1249 | };
1250 |
1251 | void Assign(const AVSValue* src, bool init);
1252 | #ifdef BUILDING_AVSCORE
1253 | public:
1254 | void CONSTRUCTOR0(); /* Damn compiler won't allow taking the address of reserved constructs, make a dummy interlude */
1255 | void CONSTRUCTOR1(IClip* c);
1256 | void CONSTRUCTOR2(const PClip& c);
1257 | void CONSTRUCTOR3(bool b);
1258 | void CONSTRUCTOR4(int i);
1259 | void CONSTRUCTOR5(float f);
1260 | void CONSTRUCTOR6(double f);
1261 | void CONSTRUCTOR7(const char* s);
1262 | void CONSTRUCTOR8(const AVSValue* a, int size);
1263 | void CONSTRUCTOR9(const AVSValue& v);
1264 | void CONSTRUCTOR11(const PFunction& n);
1265 | void DESTRUCTOR();
1266 | AVSValue& OPERATOR_ASSIGN(const AVSValue& v);
1267 | const AVSValue& OPERATOR_INDEX(int index) const;
1268 |
1269 | bool AsBool1() const;
1270 | int AsInt1() const;
1271 | const char* AsString1() const;
1272 | double AsFloat1() const;
1273 |
1274 | bool AsBool2(bool def) const;
1275 | int AsInt2(int def) const;
1276 | double AsFloat2(float def) const;
1277 | const char* AsString2(const char* def) const;
1278 |
1279 | #ifdef NEW_AVSVALUE
1280 | void MarkArrayAsC(); // for C interface, no deep-copy and deep-free
1281 | void CONSTRUCTOR10(const AVSValue& v, bool c_arrays);
1282 | AVSValue(const AVSValue& v, bool c_arrays);
1283 | void Assign2(const AVSValue* src, bool init, bool c_arrays);
1284 | #endif
1285 |
1286 | #endif
1287 | }; // end class AVSValue
1288 |
1289 | #define AVS_UNUSED(x) (void)(x)
1290 |
1291 | // instantiable null filter
1292 | class GenericVideoFilter : public IClip {
1293 | protected:
1294 | PClip child;
1295 | VideoInfo vi;
1296 | public:
1297 | GenericVideoFilter(PClip _child) : child(_child) { vi = child->GetVideoInfo(); }
1298 | PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) { return child->GetFrame(n, env); }
1299 | void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) { child->GetAudio(buf, start, count, env); }
1300 | const VideoInfo& __stdcall GetVideoInfo() { return vi; }
1301 | bool __stdcall GetParity(int n) { return child->GetParity(n); }
1302 | int __stdcall SetCacheHints(int cachehints, int frame_range) { AVS_UNUSED(cachehints); AVS_UNUSED(frame_range); return 0; }; // We do not pass cache requests upwards, only to the next filter.
1303 | };
1304 |
1305 |
1306 | class PFunction
1307 | {
1308 | public:
1309 | PFunction() AVS_BakedCode(AVS_LinkCall_Void(PFunction_CONSTRUCTOR0)())
1310 | PFunction(IFunction* p) AVS_BakedCode(AVS_LinkCall_Void(PFunction_CONSTRUCTOR1)(p))
1311 | PFunction(const PFunction& p) AVS_BakedCode(AVS_LinkCall_Void(PFunction_CONSTRUCTOR2)(p))
1312 | PFunction& operator=(IFunction* p) AVS_BakedCode(return AVS_LinkCallV(PFunction_OPERATOR_ASSIGN0)(p))
1313 | PFunction& operator=(const PFunction& p) AVS_BakedCode(return AVS_LinkCallV(PFunction_OPERATOR_ASSIGN1)(p))
1314 | ~PFunction() AVS_BakedCode(AVS_LinkCall_Void(PFunction_DESTRUCTOR)())
1315 |
1316 | int operator!() const { return !e; }
1317 | operator void*() const { return e; }
1318 | IFunction* operator->() const { return e; }
1319 |
1320 | private:
1321 | IFunction * e;
1322 |
1323 | friend class AVSValue;
1324 | IFunction * GetPointerWithAddRef() const;
1325 | void Init(IFunction* p);
1326 | void Set(IFunction* p);
1327 |
1328 | #ifdef BUILDING_AVSCORE
1329 | public:
1330 | void CONSTRUCTOR0(); /* Damn compiler won't allow taking the address of reserved constructs, make a dummy interlude */
1331 | void CONSTRUCTOR1(IFunction* p);
1332 | void CONSTRUCTOR2(const PFunction& p);
1333 | PFunction& OPERATOR_ASSIGN0(IFunction* p);
1334 | PFunction& OPERATOR_ASSIGN1(const PFunction& p);
1335 | void DESTRUCTOR();
1336 | #endif
1337 | };
1338 |
1339 |
1340 | #undef CALL_MEMBER_FN
1341 | #undef AVS_LinkCallOptDefault
1342 | #undef AVS_LinkCallOpt
1343 | #undef AVS_LinkCallV
1344 | #undef AVS_LinkCall
1345 | #undef AVS_BakedCode
1346 |
1347 |
1348 | #include "avs/cpuid.h"
1349 |
1350 | // IScriptEnvironment GetEnvProperty
1351 | enum AvsEnvProperty
1352 | {
1353 | AEP_PHYSICAL_CPUS = 1,
1354 | AEP_LOGICAL_CPUS = 2,
1355 | AEP_THREADPOOL_THREADS = 3,
1356 | AEP_FILTERCHAIN_THREADS = 4,
1357 | AEP_THREAD_ID = 5,
1358 | AEP_VERSION = 6,
1359 |
1360 | // Neo additionals
1361 | AEP_NUM_DEVICES = 901,
1362 | AEP_FRAME_ALIGN = 902,
1363 | AEP_PLANE_ALIGN = 903,
1364 |
1365 | AEP_SUPPRESS_THREAD = 921,
1366 | AEP_GETFRAME_RECURSIVE = 922,
1367 | };
1368 |
1369 | // IScriptEnvironment Allocate
1370 | enum AvsAllocType
1371 | {
1372 | AVS_NORMAL_ALLOC = 1,
1373 | AVS_POOLED_ALLOC = 2
1374 | };
1375 |
1376 |
1377 | class IScriptEnvironment {
1378 | public:
1379 | virtual ~IScriptEnvironment() {}
1380 |
1381 | virtual /*static*/ int __stdcall GetCPUFlags() = 0;
1382 |
1383 | virtual char* __stdcall SaveString(const char* s, int length = -1) = 0;
1384 | virtual char* Sprintf(const char* fmt, ...) = 0;
1385 | // note: val is really a va_list; I hope everyone typedefs va_list to a pointer
1386 | // 20200305: (void *) changed back to va_list
1387 | virtual char* __stdcall VSprintf(const char* fmt, va_list val) = 0;
1388 |
1389 | #ifdef AVS_WINDOWS
1390 | __declspec(noreturn) virtual void ThrowError(const char* fmt, ...) = 0;
1391 | #else
1392 | virtual void ThrowError(const char* fmt, ...) = 0;
1393 | #endif
1394 |
1395 | class NotFound /*exception*/ {}; // thrown by Invoke and GetVar
1396 |
1397 | typedef AVSValue (__cdecl *ApplyFunc)(AVSValue args, void* user_data, IScriptEnvironment* env);
1398 |
1399 | virtual void __stdcall AddFunction(const char* name, const char* params, ApplyFunc apply, void* user_data) = 0;
1400 | virtual bool __stdcall FunctionExists(const char* name) = 0;
1401 | virtual AVSValue __stdcall Invoke(const char* name, const AVSValue args, const char* const* arg_names=0) = 0;
1402 |
1403 | virtual AVSValue __stdcall GetVar(const char* name) = 0;
1404 | virtual bool __stdcall SetVar(const char* name, const AVSValue& val) = 0;
1405 | virtual bool __stdcall SetGlobalVar(const char* name, const AVSValue& val) = 0;
1406 |
1407 | virtual void __stdcall PushContext(int level=0) = 0;
1408 | virtual void __stdcall PopContext() = 0;
1409 |
1410 | // note v8: deprecated in most cases, use NewVideoFrameP is possible
1411 | virtual PVideoFrame __stdcall NewVideoFrame(const VideoInfo& vi, int align=FRAME_ALIGN) = 0;
1412 |
1413 | virtual bool __stdcall MakeWritable(PVideoFrame* pvf) = 0;
1414 |
1415 | virtual void __stdcall BitBlt(BYTE* dstp, int dst_pitch, const BYTE* srcp, int src_pitch, int row_size, int height) = 0;
1416 |
1417 | typedef void (__cdecl *ShutdownFunc)(void* user_data, IScriptEnvironment* env);
1418 | virtual void __stdcall AtExit(ShutdownFunc function, void* user_data) = 0;
1419 |
1420 | virtual void __stdcall CheckVersion(int version = AVISYNTH_INTERFACE_VERSION) = 0;
1421 |
1422 | virtual PVideoFrame __stdcall Subframe(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size, int new_height) = 0;
1423 |
1424 | virtual int __stdcall SetMemoryMax(int mem) = 0;
1425 |
1426 | virtual int __stdcall SetWorkingDir(const char * newdir) = 0;
1427 |
1428 | virtual void* __stdcall ManageCache(int key, void* data) = 0;
1429 |
1430 | enum PlanarChromaAlignmentMode {
1431 | PlanarChromaAlignmentOff,
1432 | PlanarChromaAlignmentOn,
1433 | PlanarChromaAlignmentTest };
1434 |
1435 | virtual bool __stdcall PlanarChromaAlignment(PlanarChromaAlignmentMode key) = 0;
1436 |
1437 | virtual PVideoFrame __stdcall SubframePlanar(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size,
1438 | int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV) = 0;
1439 |
1440 | // **** AVISYNTH_INTERFACE_VERSION 5 **** defined since classic Avisynth 2.6 beta
1441 | virtual void __stdcall DeleteScriptEnvironment() = 0;
1442 |
1443 | virtual void __stdcall ApplyMessage(PVideoFrame* frame, const VideoInfo& vi, const char* message, int size,
1444 | int textcolor, int halocolor, int bgcolor) = 0;
1445 |
1446 | virtual const AVS_Linkage* __stdcall GetAVSLinkage() = 0;
1447 |
1448 | // **** AVISYNTH_INTERFACE_VERSION 6 **** defined since classic Avisynth 2.6
1449 | // noThrow version of GetVar
1450 | virtual AVSValue __stdcall GetVarDef(const char* name, const AVSValue& def = AVSValue()) = 0;
1451 |
1452 | // **** AVISYNTH_INTERFACE_VERSION 8 **** AviSynth+ 3.6.0-
1453 | virtual PVideoFrame __stdcall SubframePlanarA(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size,
1454 | int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV, int rel_offsetA) = 0;
1455 |
1456 | virtual void __stdcall copyFrameProps(const PVideoFrame& src, PVideoFrame& dst) = 0;
1457 | virtual const AVSMap* __stdcall getFramePropsRO(const PVideoFrame& frame) = 0;
1458 | virtual AVSMap* __stdcall getFramePropsRW(PVideoFrame& frame) = 0;
1459 |
1460 | virtual int __stdcall propNumKeys(const AVSMap* map) = 0;
1461 |
1462 | virtual const char* __stdcall propGetKey(const AVSMap* map, int index) = 0;
1463 | virtual int __stdcall propNumElements(const AVSMap* map, const char* key) = 0;
1464 | virtual char __stdcall propGetType(const AVSMap* map, const char* key) = 0;
1465 |
1466 | virtual int64_t __stdcall propGetInt(const AVSMap* map, const char* key, int index, int* error) = 0;
1467 | virtual double __stdcall propGetFloat(const AVSMap* map, const char* key, int index, int* error) = 0;
1468 | virtual const char* __stdcall propGetData(const AVSMap* map, const char* key, int index, int* error) = 0;
1469 | virtual int __stdcall propGetDataSize(const AVSMap* map, const char* key, int index, int* error) = 0;
1470 | virtual PClip __stdcall propGetClip(const AVSMap* map, const char* key, int index, int* error) = 0;
1471 | virtual const PVideoFrame __stdcall propGetFrame(const AVSMap* map, const char* key, int index, int* error) = 0;
1472 |
1473 | virtual int __stdcall propDeleteKey(AVSMap* map, const char* key) = 0;
1474 |
1475 | virtual int __stdcall propSetInt(AVSMap* map, const char* key, int64_t i, int append) = 0;
1476 | virtual int __stdcall propSetFloat(AVSMap* map, const char* key, double d, int append) = 0;
1477 | virtual int __stdcall propSetData(AVSMap* map, const char* key, const char* d, int length, int append) = 0;
1478 | virtual int __stdcall propSetClip(AVSMap* map, const char* key, PClip& clip, int append) = 0;
1479 | virtual int __stdcall propSetFrame(AVSMap* map, const char* key, const PVideoFrame& frame, int append) = 0;
1480 |
1481 | virtual const int64_t* __stdcall propGetIntArray(const AVSMap* map, const char* key, int* error) = 0;
1482 | virtual const double* __stdcall propGetFloatArray(const AVSMap* map, const char* key, int* error) = 0;
1483 | virtual int __stdcall propSetIntArray(AVSMap* map, const char* key, const int64_t* i, int size) = 0;
1484 | virtual int __stdcall propSetFloatArray(AVSMap* map, const char* key, const double* d, int size) = 0;
1485 |
1486 | virtual AVSMap* __stdcall createMap() = 0;
1487 | virtual void __stdcall freeMap(AVSMap* map) = 0;
1488 | virtual void __stdcall clearMap(AVSMap* map) = 0;
1489 |
1490 | // NewVideoFrame with frame property source.
1491 | virtual PVideoFrame __stdcall NewVideoFrameP(const VideoInfo& vi, PVideoFrame* propSrc, int align = FRAME_ALIGN) = 0;
1492 |
1493 | // Note: do not declare existing names like 'NewVideoFrame' again with different parameters since MSVC will reorder it
1494 | // in the vtable and group it together with the first NewVideoFrame variant.
1495 | // This results in shifting all vtable method pointers after NewVideoFrame and breaks all plugins who expect the old order.
1496 | // E.g. ApplyMessage will be called instead of GetAVSLinkage
1497 |
1498 | // Generic query to ask for various system properties
1499 | virtual size_t __stdcall GetEnvProperty(AvsEnvProperty prop) = 0;
1500 |
1501 | // Support functions
1502 | virtual void* __stdcall Allocate(size_t nBytes, size_t alignment, AvsAllocType type) = 0;
1503 | virtual void __stdcall Free(void* ptr) = 0;
1504 |
1505 | // these GetVar versions (renamed differently) were moved from IScriptEnvironment2
1506 |
1507 | // Returns TRUE and the requested variable. If the method fails, returns FALSE and does not touch 'val'.
1508 | virtual bool __stdcall GetVarTry(const char* name, AVSValue* val) const = 0; // ex virtual bool __stdcall GetVar(const char* name, AVSValue* val) const = 0;
1509 | // Return the value of the requested variable.
1510 | // If the variable was not found or had the wrong type,
1511 | // return the supplied default value.
1512 | virtual bool __stdcall GetVarBool(const char* name, bool def) const = 0;
1513 | virtual int __stdcall GetVarInt(const char* name, int def) const = 0;
1514 | virtual double __stdcall GetVarDouble(const char* name, double def) const = 0;
1515 | virtual const char* __stdcall GetVarString(const char* name, const char* def) const = 0;
1516 | // brand new in v8 - though no real int64 support yet
1517 | virtual int64_t __stdcall GetVarLong(const char* name, int64_t def) const = 0;
1518 |
1519 | // 'Invoke' functions moved here from internal ScriptEnvironments are renamed in order to keep vtable order
1520 | // Invoke functions with 'Try' will return false instead of throwing NotFound().
1521 | // ex-IScriptEnvironment2
1522 | virtual bool __stdcall InvokeTry(AVSValue* result, const char* name, const AVSValue& args, const char* const* arg_names = 0) = 0;
1523 | // Since V8
1524 | virtual AVSValue __stdcall Invoke2(const AVSValue& implicit_last, const char* name, const AVSValue args, const char* const* arg_names = 0) = 0;
1525 | // Ex-INeo
1526 | virtual bool __stdcall Invoke2Try(AVSValue* result, const AVSValue& implicit_last, const char* name, const AVSValue args, const char* const* arg_names = 0) = 0;
1527 | virtual AVSValue __stdcall Invoke3(const AVSValue& implicit_last, const PFunction& func, const AVSValue args, const char* const* arg_names = 0) = 0;
1528 | virtual bool __stdcall Invoke3Try(AVSValue* result, const AVSValue& implicit_last, const PFunction& func, const AVSValue args, const char* const* arg_names = 0) = 0;
1529 |
1530 | }; // end class IScriptEnvironment
1531 |
1532 | // used internally
1533 | class IScriptEnvironment_Avs25 {
1534 | public:
1535 | virtual ~IScriptEnvironment_Avs25() {}
1536 |
1537 | virtual /*static*/ int __stdcall GetCPUFlags() = 0;
1538 |
1539 | virtual char* __stdcall SaveString(const char* s, int length = -1) = 0;
1540 | virtual char* Sprintf(const char* fmt, ...) = 0;
1541 | virtual char* __stdcall VSprintf(const char* fmt, va_list val) = 0;
1542 |
1543 | #ifdef AVS_WINDOWS
1544 | __declspec(noreturn) virtual void ThrowError(const char* fmt, ...) = 0;
1545 | #else
1546 | virtual void ThrowError(const char* fmt, ...) = 0;
1547 | #endif
1548 |
1549 | class NotFound /*exception*/ {}; // thrown by Invoke and GetVar
1550 |
1551 | typedef AVSValue(__cdecl* ApplyFunc)(AVSValue args, void* user_data, IScriptEnvironment* env);
1552 |
1553 | virtual void __stdcall AddFunction25(const char* name, const char* params, ApplyFunc apply, void* user_data) = 0;
1554 | virtual bool __stdcall FunctionExists(const char* name) = 0;
1555 | virtual AVSValue __stdcall Invoke25(const char* name, const AVSValue args, const char* const* arg_names = 0) = 0;
1556 |
1557 | virtual AVSValue __stdcall GetVar(const char* name) = 0;
1558 | virtual bool __stdcall SetVar(const char* name, const AVSValue& val) = 0;
1559 | virtual bool __stdcall SetGlobalVar(const char* name, const AVSValue& val) = 0;
1560 |
1561 | virtual void __stdcall PushContext(int level = 0) = 0;
1562 | virtual void __stdcall PopContext() = 0;
1563 |
1564 | virtual PVideoFrame __stdcall NewVideoFrame(const VideoInfo& vi, int align = FRAME_ALIGN) = 0;
1565 |
1566 | virtual bool __stdcall MakeWritable(PVideoFrame* pvf) = 0;
1567 |
1568 | virtual void __stdcall BitBlt(BYTE* dstp, int dst_pitch, const BYTE* srcp, int src_pitch, int row_size, int height) = 0;
1569 |
1570 | typedef void(__cdecl* ShutdownFunc)(void* user_data, IScriptEnvironment* env);
1571 | virtual void __stdcall AtExit(ShutdownFunc function, void* user_data) = 0;
1572 |
1573 | virtual void __stdcall CheckVersion(int version = AVISYNTH_CLASSIC_INTERFACE_VERSION_25) = 0;
1574 |
1575 | virtual PVideoFrame __stdcall Subframe(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size, int new_height) = 0;
1576 |
1577 | virtual int __stdcall SetMemoryMax(int mem) = 0;
1578 |
1579 | virtual int __stdcall SetWorkingDir(const char* newdir) = 0;
1580 |
1581 | // specially returns 1 for key MC_QueryAvs25 to check if called from AVS2.5 interface
1582 | virtual void* __stdcall ManageCache25(int key, void* data) = 0;
1583 |
1584 | enum PlanarChromaAlignmentMode {
1585 | PlanarChromaAlignmentOff,
1586 | PlanarChromaAlignmentOn,
1587 | PlanarChromaAlignmentTest
1588 | };
1589 |
1590 | virtual bool __stdcall PlanarChromaAlignment(IScriptEnvironment::PlanarChromaAlignmentMode key) = 0;
1591 |
1592 | virtual PVideoFrame __stdcall SubframePlanar(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size,
1593 | int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV) = 0;
1594 |
1595 | // Despite the name, we provide entries up to V6 in case someone requests
1596 | // a V3 interface and still wants to use V5-V6 functions
1597 |
1598 | // **** AVISYNTH_INTERFACE_VERSION 5 **** defined since classic Avisynth 2.6 beta
1599 | virtual void __stdcall DeleteScriptEnvironment() = 0;
1600 |
1601 | virtual void __stdcall ApplyMessage(PVideoFrame* frame, const VideoInfo& vi, const char* message, int size,
1602 | int textcolor, int halocolor, int bgcolor) = 0;
1603 |
1604 | virtual const AVS_Linkage* __stdcall GetAVSLinkage() = 0;
1605 |
1606 | // **** AVISYNTH_INTERFACE_VERSION 6 **** defined since classic Avisynth 2.6
1607 | // noThrow version of GetVar
1608 | virtual AVSValue __stdcall GetVarDef(const char* name, const AVSValue& def = AVSValue()) = 0;
1609 |
1610 | }; // end class IScriptEnvironment_Avs25
1611 |
1612 |
1613 | enum MtMode
1614 | {
1615 | MT_INVALID = 0,
1616 | MT_NICE_FILTER = 1,
1617 | MT_MULTI_INSTANCE = 2,
1618 | MT_SERIALIZED = 3,
1619 | MT_SPECIAL_MT = 4,
1620 | MT_MODE_COUNT = 5
1621 | };
1622 |
1623 | class IJobCompletion
1624 | {
1625 | public:
1626 |
1627 | virtual ~IJobCompletion() {}
1628 | virtual void __stdcall Wait() = 0;
1629 | virtual AVSValue __stdcall Get(size_t i) = 0;
1630 | virtual size_t __stdcall Size() const = 0;
1631 | virtual size_t __stdcall Capacity() const = 0;
1632 | virtual void __stdcall Reset() = 0;
1633 | virtual void __stdcall Destroy() = 0;
1634 | };
1635 |
1636 | class IScriptEnvironment2;
1637 | class Prefetcher;
1638 | typedef AVSValue (*ThreadWorkerFuncPtr)(IScriptEnvironment2* env, void* data);
1639 |
1640 |
1641 | /* -----------------------------------------------------------------------------
1642 | Note to plugin authors: The interface in IScriptEnvironment2 is
1643 | preliminary / under construction / only for testing / non-final etc.!
1644 | As long as you see this note here, IScriptEnvironment2 might still change,
1645 | in which case your plugin WILL break. This also means that you are welcome
1646 | to test it and give your feedback about any ideas, improvements, or issues
1647 | you might have.
1648 | ----------------------------------------------------------------------------- */
1649 | class IScriptEnvironment2 : public IScriptEnvironment{
1650 | public:
1651 | virtual ~IScriptEnvironment2() {}
1652 |
1653 | // V8: SubframePlanarA, GetEnvProperty, GetVar versions, Allocate, Free, no-throw Invoke moved to IScriptEnvironment
1654 |
1655 | // Plugin functions
1656 | virtual bool __stdcall LoadPlugin(const char* filePath, bool throwOnError, AVSValue *result) = 0;
1657 | virtual void __stdcall AddAutoloadDir(const char* dirPath, bool toFront) = 0;
1658 | virtual void __stdcall ClearAutoloadDirs() = 0;
1659 | virtual void __stdcall AutoloadPlugins() = 0;
1660 | virtual void __stdcall AddFunction(const char* name, const char* params, ApplyFunc apply, void* user_data, const char *exportVar) = 0;
1661 | virtual bool __stdcall InternalFunctionExists(const char* name) = 0;
1662 |
1663 | // Threading
1664 | virtual void __stdcall SetFilterMTMode(const char* filter, MtMode mode, bool force) = 0; // If filter is "DEFAULT_MT_MODE", sets the default MT mode
1665 | virtual IJobCompletion* __stdcall NewCompletion(size_t capacity) = 0;
1666 | virtual void __stdcall ParallelJob(ThreadWorkerFuncPtr jobFunc, void* jobData, IJobCompletion* completion) = 0;
1667 |
1668 | // These lines are needed so that we can overload the older functions from IScriptEnvironment.
1669 | using IScriptEnvironment::Invoke;
1670 | using IScriptEnvironment::AddFunction;
1671 |
1672 | }; // end class IScriptEnvironment2
1673 |
1674 |
1675 | // To allow Avisynth+ add functions to IScriptEnvironment2,
1676 | // Neo defines another new interface, INeoEnv.
1677 | // INeoEnv and the legacy interfaces (IScriptEnvironment/IScriptEnvironment2)
1678 | // share the same ScriptEnvironment instance. The function with the same signature
1679 | // is exactly identical and there is no limitation to switch interfaces.
1680 | // You can use any interface you like.
1681 | // Note to plugin authors : The interface is not stable, see comments in IScriptEnvironment2
1682 | class INeoEnv {
1683 | public:
1684 | virtual ~INeoEnv() {}
1685 |
1686 | typedef IScriptEnvironment::NotFound NotFound;
1687 | typedef IScriptEnvironment::ApplyFunc ApplyFunc;
1688 | typedef IScriptEnvironment::ShutdownFunc ShutdownFunc;
1689 |
1690 | virtual void __stdcall DeleteScriptEnvironment() = 0;
1691 |
1692 | virtual const AVS_Linkage* __stdcall GetAVSLinkage() = 0;
1693 |
1694 | // Get legacy interface (Avisynth+)
1695 | virtual IScriptEnvironment2* __stdcall GetEnv2() = 0;
1696 | // Get compatibility interface for AVS CPP 2.5 plugins
1697 | virtual IScriptEnvironment_Avs25* __stdcall GetEnv25() = 0;
1698 |
1699 | // Generic system to ask for various properties
1700 | virtual size_t __stdcall GetEnvProperty(AvsEnvProperty prop) = 0;
1701 | virtual int __stdcall GetCPUFlags() = 0;
1702 |
1703 | // Plugin functions
1704 | virtual bool __stdcall LoadPlugin(const char* filePath, bool throwOnError, AVSValue *result) = 0;
1705 | virtual void __stdcall AddAutoloadDir(const char* dirPath, bool toFront) = 0;
1706 | virtual void __stdcall ClearAutoloadDirs() = 0;
1707 | virtual void __stdcall AutoloadPlugins() = 0;
1708 |
1709 | virtual void __stdcall AddFunction(
1710 | const char* name, const char* params, ApplyFunc apply, void* user_data) = 0;
1711 | virtual void __stdcall AddFunction(
1712 | const char* name, const char* params, ApplyFunc apply, void* user_data, const char *exportVar) = 0;
1713 | virtual bool __stdcall FunctionExists(const char* name) = 0;
1714 | virtual bool __stdcall InternalFunctionExists(const char* name) = 0;
1715 |
1716 | // Invoke function. Throws NotFound exception when the specified function does not exist.
1717 | virtual AVSValue __stdcall Invoke(
1718 | const char* name, const AVSValue args, const char* const* arg_names = 0) = 0;
1719 | virtual AVSValue __stdcall Invoke2(
1720 | const AVSValue& implicit_last, const char* name, const AVSValue args, const char* const* arg_names = 0) = 0;
1721 | virtual AVSValue __stdcall Invoke3(
1722 | const AVSValue& implicit_last,
1723 | const PFunction& func, const AVSValue args, const char* const* arg_names = 0) = 0;
1724 |
1725 | // These versions of Invoke will return false instead of throwing NotFound().
1726 | virtual bool __stdcall InvokeTry(
1727 | AVSValue* result, const char* name, const AVSValue& args, const char* const* arg_names = 0) = 0;
1728 | virtual bool __stdcall Invoke2Try(
1729 | AVSValue* result, const AVSValue& implicit_last,
1730 | const char* name, const AVSValue args, const char* const* arg_names = 0) = 0;
1731 | virtual bool __stdcall Invoke3Try(
1732 | AVSValue* result, const AVSValue& implicit_last,
1733 | const PFunction& func, const AVSValue args, const char* const* arg_names = 0) = 0;
1734 |
1735 | // Throws exception when the requested variable is not found.
1736 | virtual AVSValue __stdcall GetVar(const char* name) = 0;
1737 |
1738 | // noThrow version of GetVar
1739 | virtual AVSValue __stdcall GetVarDef(const char* name, const AVSValue& def = AVSValue()) = 0;
1740 |
1741 | // Returns TRUE and the requested variable. If the method fails, returns FALSE and does not touch 'val'.
1742 | virtual bool __stdcall GetVarTry(const char* name, AVSValue* val) const = 0;
1743 |
1744 | // Return the value of the requested variable.
1745 | // If the variable was not found or had the wrong type,
1746 | // return the supplied default value.
1747 | virtual bool __stdcall GetVarBool(const char* name, bool def) const = 0;
1748 | virtual int __stdcall GetVarInt(const char* name, int def) const = 0;
1749 | virtual double __stdcall GetVarDouble(const char* name, double def) const = 0;
1750 | virtual const char* __stdcall GetVarString(const char* name, const char* def) const = 0;
1751 | virtual int64_t __stdcall GetVarLong(const char* name, int64_t def) const = 0;
1752 |
1753 | virtual bool __stdcall SetVar(const char* name, const AVSValue& val) = 0;
1754 | virtual bool __stdcall SetGlobalVar(const char* name, const AVSValue& val) = 0;
1755 |
1756 | // Switch local variables
1757 | virtual void __stdcall PushContext(int level = 0) = 0;
1758 | virtual void __stdcall PopContext() = 0;
1759 |
1760 | // Global variable frame support
1761 | virtual void __stdcall PushContextGlobal() = 0;
1762 | virtual void __stdcall PopContextGlobal() = 0;
1763 |
1764 | // Allocate new video frame
1765 | // in PNeoEnv: align parameter is no longer supported
1766 | virtual PVideoFrame __stdcall NewVideoFrame(const VideoInfo& vi) = 0; // current device is used
1767 | virtual PVideoFrame __stdcall NewVideoFrame(const VideoInfo& vi, const PDevice& device) = 0;
1768 | // as above but with property sources
1769 | virtual PVideoFrame __stdcall NewVideoFrame(const VideoInfo& vi, PVideoFrame *propSrc) = 0; // current device is used + frame property source
1770 | virtual PVideoFrame __stdcall NewVideoFrame(const VideoInfo& vi, const PDevice& device, PVideoFrame* propSrc) = 0; // current device is used + frame property source
1771 |
1772 | // Frame related operations
1773 | virtual bool __stdcall MakeWritable(PVideoFrame* pvf) = 0;
1774 | virtual void __stdcall BitBlt(BYTE* dstp, int dst_pitch, const BYTE* srcp, int src_pitch, int row_size, int height) = 0;
1775 |
1776 | virtual PVideoFrame __stdcall Subframe(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size, int new_height) = 0;
1777 | virtual PVideoFrame __stdcall SubframePlanar(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size,
1778 | int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV) = 0;
1779 | virtual PVideoFrame __stdcall SubframePlanarA(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size,
1780 | int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV, int rel_offsetA) = 0;
1781 |
1782 | // frame properties support
1783 | virtual void __stdcall copyFrameProps(const PVideoFrame& src, PVideoFrame& dst) = 0;
1784 | virtual const AVSMap* __stdcall getFramePropsRO(const PVideoFrame& frame) = 0;
1785 | virtual AVSMap* __stdcall getFramePropsRW(PVideoFrame& frame) = 0;
1786 |
1787 | virtual int __stdcall propNumKeys(const AVSMap* map) = 0;
1788 | virtual const char* __stdcall propGetKey(const AVSMap* map, int index) = 0;
1789 | virtual int __stdcall propNumElements(const AVSMap* map, const char* key) = 0;
1790 | virtual char __stdcall propGetType(const AVSMap* map, const char* key) = 0;
1791 |
1792 | virtual int64_t __stdcall propGetInt(const AVSMap* map, const char* key, int index, int* error) = 0;
1793 | virtual double __stdcall propGetFloat(const AVSMap* map, const char* key, int index, int* error) = 0;
1794 | virtual const char* __stdcall propGetData(const AVSMap* map, const char* key, int index, int* error) = 0;
1795 | virtual int __stdcall propGetDataSize(const AVSMap* map, const char* key, int index, int* error) = 0;
1796 | virtual PClip __stdcall propGetClip(const AVSMap* map, const char* key, int index, int* error) = 0;
1797 | virtual const PVideoFrame __stdcall propGetFrame(const AVSMap* map, const char* key, int index, int* error) = 0;
1798 |
1799 | virtual int __stdcall propDeleteKey(AVSMap* map, const char* key) = 0;
1800 |
1801 | virtual int __stdcall propSetInt(AVSMap* map, const char* key, int64_t i, int append) = 0;
1802 | virtual int __stdcall propSetFloat(AVSMap* map, const char* key, double d, int append) = 0;
1803 | virtual int __stdcall propSetData(AVSMap* map, const char* key, const char* d, int length, int append) = 0;
1804 | virtual int __stdcall propSetClip(AVSMap* map, const char* key, PClip& clip, int append) = 0;
1805 | virtual int __stdcall propSetFrame(AVSMap* map, const char* key, const PVideoFrame& frame, int append) = 0;
1806 |
1807 | virtual const int64_t *__stdcall propGetIntArray(const AVSMap* map, const char* key, int* error) = 0;
1808 | virtual const double *__stdcall propGetFloatArray(const AVSMap* map, const char* key, int* error) = 0;
1809 | virtual int __stdcall propSetIntArray(AVSMap* map, const char* key, const int64_t* i, int size) = 0;
1810 | virtual int __stdcall propSetFloatArray(AVSMap* map, const char* key, const double* d, int size) = 0;
1811 |
1812 | virtual AVSMap* __stdcall createMap() = 0;
1813 | virtual void __stdcall freeMap(AVSMap* map) = 0;
1814 | virtual void __stdcall clearMap(AVSMap* map) = 0;
1815 |
1816 | // Support functions
1817 | virtual void* __stdcall Allocate(size_t nBytes, size_t alignment, AvsAllocType type) = 0;
1818 | virtual void __stdcall Free(void* ptr) = 0;
1819 |
1820 | virtual char* __stdcall SaveString(const char* s, int length = -1) = 0;
1821 | virtual char* __stdcall SaveString(const char* s, int length, bool escape) = 0;
1822 | virtual char* Sprintf(const char* fmt, ...) = 0;
1823 | virtual char* __stdcall VSprintf(const char* fmt, va_list val) = 0;
1824 |
1825 | __declspec(noreturn) virtual void ThrowError(const char* fmt, ...) = 0;
1826 |
1827 | virtual void __stdcall ApplyMessage(PVideoFrame* frame, const VideoInfo& vi, const char* message, int size,
1828 | int textcolor, int halocolor, int bgcolor) = 0;
1829 |
1830 | // Setting
1831 | virtual int __stdcall SetMemoryMax(int mem) = 0;
1832 | virtual int __stdcall SetMemoryMax(AvsDeviceType type, int index, int mem) = 0;
1833 |
1834 | virtual bool __stdcall PlanarChromaAlignment(IScriptEnvironment::PlanarChromaAlignmentMode key) = 0;
1835 | virtual int __stdcall SetWorkingDir(const char * newdir) = 0;
1836 | virtual void* __stdcall ManageCache(int key, void* data) = 0;
1837 |
1838 | virtual void __stdcall AtExit(ShutdownFunc function, void* user_data) = 0;
1839 | virtual void __stdcall CheckVersion(int version = AVISYNTH_INTERFACE_VERSION) = 0;
1840 |
1841 | // Threading
1842 | virtual void __stdcall SetFilterMTMode(const char* filter, MtMode mode, bool force) = 0;
1843 | virtual IJobCompletion* __stdcall NewCompletion(size_t capacity) = 0;
1844 | virtual void __stdcall ParallelJob(ThreadWorkerFuncPtr jobFunc, void* jobData, IJobCompletion* completion) = 0;
1845 |
1846 | // CUDA Support
1847 | virtual PDevice __stdcall GetDevice(AvsDeviceType dev_type, int dev_index) const = 0;
1848 | virtual PDevice __stdcall GetDevice() const = 0; // get current device
1849 | virtual AvsDeviceType __stdcall GetDeviceType() const = 0;
1850 | virtual int __stdcall GetDeviceId() const = 0;
1851 | virtual int __stdcall GetDeviceIndex() const = 0;
1852 | virtual void* __stdcall GetDeviceStream() const = 0;
1853 | virtual void __stdcall DeviceAddCallback(void(*cb)(void*), void* user_data) = 0;
1854 |
1855 | virtual PVideoFrame __stdcall GetFrame(PClip c, int n, const PDevice& device) = 0;
1856 |
1857 | };
1858 |
1859 | // support interface conversion
1860 | struct PNeoEnv {
1861 | INeoEnv* p;
1862 | PNeoEnv() : p() { }
1863 | PNeoEnv(IScriptEnvironment* env)
1864 | #if defined(BUILDING_AVSCORE) || defined(AVS_STATIC_LIB)
1865 | ;
1866 | #else
1867 | : p(!AVS_linkage || offsetof(AVS_Linkage, GetNeoEnv) >= AVS_linkage->Size ? 0 : AVS_linkage->GetNeoEnv(env)) { }
1868 | #endif
1869 |
1870 | int operator!() const { return !p; }
1871 | operator void*() const { return p; }
1872 | INeoEnv* operator->() const { return p; }
1873 | #ifdef BUILDING_AVSCORE
1874 | inline operator IScriptEnvironment2*();
1875 | inline operator IScriptEnvironment_Avs25* ();
1876 | #else
1877 | operator IScriptEnvironment2*() { return p->GetEnv2(); }
1878 | operator IScriptEnvironment_Avs25* () { return p->GetEnv25(); }
1879 | #endif
1880 | };
1881 |
1882 |
1883 | // avisynth.dll exports this; it's a way to use it as a library, without
1884 | // writing an AVS script or without going through AVIFile.
1885 | AVSC_API(IScriptEnvironment*, CreateScriptEnvironment)(int version = AVISYNTH_INTERFACE_VERSION);
1886 |
1887 |
1888 | // These are some global variables you can set in your script to change AviSynth's behavior.
1889 | #define VARNAME_AllowFloatAudio "OPT_AllowFloatAudio" // Allow WAVE_FORMAT_IEEE_FLOAT audio output
1890 | #define VARNAME_VDubPlanarHack "OPT_VDubPlanarHack" // Hack YV16 and YV24 chroma plane order for old VDub's
1891 | #define VARNAME_AVIPadScanlines "OPT_AVIPadScanlines" // Have scanlines mod4 padded in all pixel formats
1892 | #define VARNAME_UseWaveExtensible "OPT_UseWaveExtensible" // Use WAVEFORMATEXTENSIBLE when describing audio to Windows
1893 | #define VARNAME_dwChannelMask "OPT_dwChannelMask" // Integer audio channel mask. See description of WAVEFORMATEXTENSIBLE for more info.
1894 | #define VARNAME_Enable_V210 "OPT_Enable_V210" // AVS+ use V210 instead of P210 (VfW)
1895 | #define VARNAME_Enable_Y3_10_10 "OPT_Enable_Y3_10_10" // AVS+ use Y3[10][10] instead of P210 (VfW)
1896 | #define VARNAME_Enable_Y3_10_16 "OPT_Enable_Y3_10_16" // AVS+ use Y3[10][16] instead of P216 (VfW)
1897 | #define VARNAME_Enable_b64a "OPT_Enable_b64a" // AVS+ use b64a instead of BRA[64] (VfW)
1898 | #define VARNAME_Enable_PlanarToPackedRGB "OPT_Enable_PlanarToPackedRGB" // AVS+ convert Planar RGB to packed RGB (VfW)
1899 |
1900 | // C exports
1901 | #include "avs/capi.h"
1902 | AVSC_API(IScriptEnvironment2*, CreateScriptEnvironment2)(int version = AVISYNTH_INTERFACE_VERSION);
1903 |
1904 | #ifndef BUILDING_AVSCORE
1905 | #undef AVS_UNUSED
1906 | #endif
1907 |
1908 | #pragma pack(pop)
1909 |
1910 | #endif //__AVISYNTH_8_H__
1911 |
--------------------------------------------------------------------------------
/Average/avs/alignment.h:
--------------------------------------------------------------------------------
1 | // Avisynth C Interface Version 0.20
2 | // Copyright 2003 Kevin Atkinson
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 | // As a special exception, I give you permission to link to the
20 | // Avisynth C interface with independent modules that communicate with
21 | // the Avisynth C interface solely through the interfaces defined in
22 | // avisynth_c.h, regardless of the license terms of these independent
23 | // modules, and to copy and distribute the resulting combined work
24 | // under terms of your choice, provided that every copy of the
25 | // combined work is accompanied by a complete copy of the source code
26 | // of the Avisynth C interface and Avisynth itself (with the version
27 | // used to produce the combined work), being distributed under the
28 | // terms of the GNU General Public License plus this exception. An
29 | // independent module is a module which is not derived from or based
30 | // on Avisynth C Interface, such as 3rd-party filters, import and
31 | // export plugins, or graphical user interfaces.
32 |
33 | #ifndef AVS_ALIGNMENT_H
34 | #define AVS_ALIGNMENT_H
35 |
36 | // Functions and macros to help work with alignment requirements.
37 |
38 | // Tells if a number is a power of two.
39 | #define IS_POWER2(n) ((n) && !((n) & ((n) - 1)))
40 |
41 | // Tells if the pointer "ptr" is aligned to "align" bytes.
42 | #define IS_PTR_ALIGNED(ptr, align) (((uintptr_t)ptr & ((uintptr_t)(align-1))) == 0)
43 |
44 | // Rounds up the number "n" to the next greater multiple of "align"
45 | #define ALIGN_NUMBER(n, align) (((n) + (align)-1) & (~((align)-1)))
46 |
47 | // Rounds up the pointer address "ptr" to the next greater multiple of "align"
48 | #define ALIGN_POINTER(ptr, align) (((uintptr_t)(ptr) + (align)-1) & (~(uintptr_t)((align)-1)))
49 |
50 | #ifdef __cplusplus
51 |
52 | #include
53 | #include
54 | #include
55 | #include "config.h"
56 |
57 | #if defined(MSVC) && _MSC_VER<1400
58 | // needed for VS2013, otherwise C++11 'alignas' works
59 | #define avs_alignas(x) __declspec(align(x))
60 | #else
61 | // assumes C++11 support
62 | #define avs_alignas(x) alignas(x)
63 | #endif
64 |
65 | template
66 | static bool IsPtrAligned(T* ptr, size_t align)
67 | {
68 | assert(IS_POWER2(align));
69 | return (bool)IS_PTR_ALIGNED(ptr, align);
70 | }
71 |
72 | template
73 | static T AlignNumber(T n, T align)
74 | {
75 | assert(IS_POWER2(align));
76 | return ALIGN_NUMBER(n, align);
77 | }
78 |
79 | template
80 | static T* AlignPointer(T* ptr, size_t align)
81 | {
82 | assert(IS_POWER2(align));
83 | return (T*)ALIGN_POINTER(ptr, align);
84 | }
85 |
86 | extern "C"
87 | {
88 | #else
89 | #include
90 | #endif // __cplusplus
91 |
92 | // Returns a new buffer that is at least the size "nbytes".
93 | // The buffer will be aligned to "align" bytes.
94 | // Returns NULL on error. On successful allocation,
95 | // the returned buffer must be freed using "avs_free".
96 | inline void* avs_malloc(size_t nbytes, size_t align)
97 | {
98 | if (!IS_POWER2(align))
99 | return NULL;
100 |
101 | size_t offset = sizeof(void*) + align - 1;
102 |
103 | void *orig = malloc(nbytes + offset);
104 | if (orig == NULL)
105 | return NULL;
106 |
107 | void **aligned = (void**)(((uintptr_t)orig + (uintptr_t)offset) & (~(uintptr_t)(align-1)));
108 | aligned[-1] = orig;
109 | return aligned;
110 | }
111 |
112 | // Buffers allocated using "avs_malloc" must be freed
113 | // using "avs_free" instead of "free".
114 | inline void avs_free(void *ptr)
115 | {
116 | // Mirroring free()'s semantic requires us to accept NULLs
117 | if (ptr == NULL)
118 | return;
119 |
120 | free(((void**)ptr)[-1]);
121 | }
122 |
123 | #ifdef __cplusplus
124 | } // extern "C"
125 |
126 | // The point of these undef's is to force using the template functions
127 | // if we are in C++ mode. For C, the user can rely only on the macros.
128 | #undef IS_PTR_ALIGNED
129 | #undef ALIGN_NUMBER
130 | #undef ALIGN_POINTER
131 |
132 | #endif // __cplusplus
133 |
134 | #endif //AVS_ALIGNMENT_H
135 |
--------------------------------------------------------------------------------
/Average/avs/capi.h:
--------------------------------------------------------------------------------
1 | // Avisynth C Interface Version 0.20
2 | // Copyright 2003 Kevin Atkinson
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 | // As a special exception, I give you permission to link to the
20 | // Avisynth C interface with independent modules that communicate with
21 | // the Avisynth C interface solely through the interfaces defined in
22 | // avisynth_c.h, regardless of the license terms of these independent
23 | // modules, and to copy and distribute the resulting combined work
24 | // under terms of your choice, provided that every copy of the
25 | // combined work is accompanied by a complete copy of the source code
26 | // of the Avisynth C interface and Avisynth itself (with the version
27 | // used to produce the combined work), being distributed under the
28 | // terms of the GNU General Public License plus this exception. An
29 | // independent module is a module which is not derived from or based
30 | // on Avisynth C Interface, such as 3rd-party filters, import and
31 | // export plugins, or graphical user interfaces.
32 |
33 | #ifndef AVS_CAPI_H
34 | #define AVS_CAPI_H
35 |
36 | #include "config.h"
37 |
38 | #ifdef AVS_POSIX
39 | // this is also defined in avs/posix.h
40 | #ifndef AVS_HAIKU
41 | #define __declspec(x)
42 | #endif
43 | #endif
44 |
45 | #ifdef __cplusplus
46 | # define EXTERN_C extern "C"
47 | #else
48 | # define EXTERN_C
49 | #endif
50 |
51 | #ifdef AVS_WINDOWS
52 | #ifdef BUILDING_AVSCORE
53 | # if defined(GCC) && defined(X86_32)
54 | # define AVSC_CC
55 | # else // MSVC builds and 64-bit GCC
56 | # ifndef AVSC_USE_STDCALL
57 | # define AVSC_CC __cdecl
58 | # else
59 | # define AVSC_CC __stdcall
60 | # endif
61 | # endif
62 | #else // needed for programs that talk to AviSynth+
63 | # ifndef AVSC_WIN32_GCC32 // see comment below
64 | # ifndef AVSC_USE_STDCALL
65 | # define AVSC_CC __cdecl
66 | # else
67 | # define AVSC_CC __stdcall
68 | # endif
69 | # else
70 | # define AVSC_CC
71 | # endif
72 | #endif
73 | # else
74 | # define AVSC_CC
75 | #endif
76 |
77 | // On 64-bit Windows, there's only one calling convention,
78 | // so there is no difference between MSVC and GCC. On 32-bit,
79 | // this isn't true. The convention that GCC needs to use to
80 | // even build AviSynth+ as 32-bit makes anything that uses
81 | // it incompatible with 32-bit MSVC builds of AviSynth+.
82 | // The AVSC_WIN32_GCC32 define is meant to provide a user
83 | // switchable way to make builds of FFmpeg to test 32-bit
84 | // GCC builds of AviSynth+ without having to screw around
85 | // with alternate headers, while still default to the usual
86 | // situation of using 32-bit MSVC builds of AviSynth+.
87 |
88 | // Hopefully, this situation will eventually be resolved
89 | // and a broadly compatible solution will arise so the
90 | // same 32-bit FFmpeg build can handle either MSVC or GCC
91 | // builds of AviSynth+.
92 |
93 | #define AVSC_INLINE static __inline
94 |
95 | #ifdef BUILDING_AVSCORE
96 | #ifdef AVS_WINDOWS
97 | # ifndef AVS_STATIC_LIB
98 | # define AVSC_EXPORT __declspec(dllexport)
99 | # else
100 | # define AVSC_EXPORT
101 | # endif
102 | # define AVSC_API(ret, name) EXTERN_C AVSC_EXPORT ret AVSC_CC name
103 | #else
104 | # define AVSC_EXPORT EXTERN_C
105 | # define AVSC_API(ret, name) EXTERN_C ret AVSC_CC name
106 | #endif
107 | #else
108 | # define AVSC_EXPORT EXTERN_C __declspec(dllexport)
109 | # ifndef AVS_STATIC_LIB
110 | # define AVSC_IMPORT __declspec(dllimport)
111 | # else
112 | # define AVSC_IMPORT
113 | # endif
114 | # ifndef AVSC_NO_DECLSPEC
115 | # define AVSC_API(ret, name) EXTERN_C AVSC_IMPORT ret AVSC_CC name
116 | # else
117 | # define AVSC_API(ret, name) typedef ret (AVSC_CC *name##_func)
118 | # endif
119 | #endif
120 |
121 | #endif //AVS_CAPI_H
122 |
--------------------------------------------------------------------------------
/Average/avs/config.h:
--------------------------------------------------------------------------------
1 | // Avisynth C Interface Version 0.20
2 | // Copyright 2003 Kevin Atkinson
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 | // As a special exception, I give you permission to link to the
20 | // Avisynth C interface with independent modules that communicate with
21 | // the Avisynth C interface solely through the interfaces defined in
22 | // avisynth_c.h, regardless of the license terms of these independent
23 | // modules, and to copy and distribute the resulting combined work
24 | // under terms of your choice, provided that every copy of the
25 | // combined work is accompanied by a complete copy of the source code
26 | // of the Avisynth C interface and Avisynth itself (with the version
27 | // used to produce the combined work), being distributed under the
28 | // terms of the GNU General Public License plus this exception. An
29 | // independent module is a module which is not derived from or based
30 | // on Avisynth C Interface, such as 3rd-party filters, import and
31 | // export plugins, or graphical user interfaces.
32 |
33 | #ifndef AVS_CONFIG_H
34 | #define AVS_CONFIG_H
35 |
36 | // Undefine this to get cdecl calling convention
37 | #define AVSC_USE_STDCALL 1
38 |
39 | // NOTE TO PLUGIN AUTHORS:
40 | // Because FRAME_ALIGN can be substantially higher than the alignment
41 | // a plugin actually needs, plugins should not use FRAME_ALIGN to check for
42 | // alignment. They should always request the exact alignment value they need.
43 | // This is to make sure that plugins work over the widest range of AviSynth
44 | // builds possible.
45 | #define FRAME_ALIGN 64
46 |
47 | #if defined(_M_AMD64) || defined(__x86_64)
48 | # define X86_64
49 | #elif defined(_M_IX86) || defined(__i386__)
50 | # define X86_32
51 | // VS2017 introduced _M_ARM64
52 | #elif defined(_M_ARM64) || defined(__aarch64__)
53 | # define ARM64
54 | #elif defined(_M_ARM) || defined(__arm__)
55 | # define ARM32
56 | #elif defined(__PPC64__)
57 | # define PPC64
58 | #elif defined(_M_PPC) || defined(__PPC__) || defined(__POWERPC__)
59 | # define PPC32
60 | #elif defined(__riscv)
61 | # define RISCV
62 | #elif defined(__sparc_v9__)
63 | # define SPARC
64 | #else
65 | # error Unsupported CPU architecture.
66 | #endif
67 |
68 | // VC++ LLVM-Clang-cl MinGW-Gnu
69 | // MSVC x x
70 | // MSVC_PURE x
71 | // CLANG x
72 | // GCC x
73 |
74 | #if defined(__clang__)
75 | // Check clang first. clang-cl also defines __MSC_VER
76 | // We set MSVC because they are mostly compatible
77 | # define CLANG
78 | #if defined(_MSC_VER)
79 | # define MSVC
80 | # define AVS_FORCEINLINE __attribute__((always_inline))
81 | #else
82 | # define AVS_FORCEINLINE __attribute__((always_inline)) inline
83 | #endif
84 | #elif defined(_MSC_VER)
85 | # define MSVC
86 | # define MSVC_PURE
87 | # define AVS_FORCEINLINE __forceinline
88 | #elif defined(__GNUC__)
89 | # define GCC
90 | # define AVS_FORCEINLINE __attribute__((always_inline)) inline
91 | #else
92 | # error Unsupported compiler.
93 | # define AVS_FORCEINLINE inline
94 | # undef __forceinline
95 | # define __forceinline inline
96 | #endif
97 |
98 | #if defined(_WIN32)
99 | # define AVS_WINDOWS
100 | #elif defined(__linux__)
101 | # define AVS_LINUX
102 | # define AVS_POSIX
103 | #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
104 | # define AVS_BSD
105 | # define AVS_POSIX
106 | #elif defined(__APPLE__)
107 | # define AVS_MACOS
108 | # define AVS_POSIX
109 | #elif defined(__HAIKU__)
110 | # define AVS_HAIKU
111 | # define AVS_POSIX
112 | #else
113 | # error Operating system unsupported.
114 | #endif
115 |
116 | // useful warnings disabler macros for supported compilers
117 |
118 | #if defined(_MSC_VER)
119 | #define DISABLE_WARNING_PUSH __pragma(warning( push ))
120 | #define DISABLE_WARNING_POP __pragma(warning( pop ))
121 | #define DISABLE_WARNING(warningNumber) __pragma(warning( disable : warningNumber ))
122 |
123 | #define DISABLE_WARNING_UNREFERENCED_LOCAL_VARIABLE DISABLE_WARNING(4101)
124 | #define DISABLE_WARNING_UNREFERENCED_FUNCTION DISABLE_WARNING(4505)
125 | // other warnings you want to deactivate...
126 |
127 | #elif defined(__GNUC__) || defined(__clang__)
128 | #define DO_PRAGMA(X) _Pragma(#X)
129 | #define DISABLE_WARNING_PUSH DO_PRAGMA(GCC diagnostic push)
130 | #define DISABLE_WARNING_POP DO_PRAGMA(GCC diagnostic pop)
131 | #define DISABLE_WARNING(warningName) DO_PRAGMA(GCC diagnostic ignored #warningName)
132 |
133 | #define DISABLE_WARNING_UNREFERENCED_LOCAL_VARIABLE DISABLE_WARNING(-Wunused-variable)
134 | #define DISABLE_WARNING_UNREFERENCED_FUNCTION DISABLE_WARNING(-Wunused-function)
135 | // other warnings you want to deactivate...
136 |
137 | #else
138 | #define DISABLE_WARNING_PUSH
139 | #define DISABLE_WARNING_POP
140 | #define DISABLE_WARNING_UNREFERENCED_LOCAL_VARIABLE
141 | #define DISABLE_WARNING_UNREFERENCED_FUNCTION
142 | // other warnings you want to deactivate...
143 |
144 | #endif
145 |
146 | #if defined(AVS_POSIX)
147 | #define NEW_AVSVALUE
148 | #else
149 | #define NEW_AVSVALUE
150 | #endif
151 |
152 | #if defined(AVS_WINDOWS) && defined(_USING_V110_SDK71_)
153 | // Windows XP does not have proper initialization for
154 | // thread local variables.
155 | // Use workaround instead __declspec(thread)
156 | #define XP_TLS
157 | #endif
158 |
159 | #endif //AVS_CONFIG_H
160 |
--------------------------------------------------------------------------------
/Average/avs/cpuid.h:
--------------------------------------------------------------------------------
1 | // This program is free software; you can redistribute it and/or modify
2 | // it under the terms of the GNU General Public License as published by
3 | // the Free Software Foundation; either version 2 of the License, or
4 | // (at your option) any later version.
5 | //
6 | // This program is distributed in the hope that it will be useful,
7 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
8 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 | // GNU General Public License for more details.
10 | //
11 | // You should have received a copy of the GNU General Public License
12 | // along with this program; if not, write to the Free Software
13 | // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit
14 | // http://www.gnu.org/copyleft/gpl.html .
15 | //
16 | // Linking Avisynth statically or dynamically with other modules is making a
17 | // combined work based on Avisynth. Thus, the terms and conditions of the GNU
18 | // General Public License cover the whole combination.
19 | //
20 | // As a special exception, the copyright holders of Avisynth give you
21 | // permission to link Avisynth with independent modules that communicate with
22 | // Avisynth solely through the interfaces defined in avisynth.h, regardless of the license
23 | // terms of these independent modules, and to copy and distribute the
24 | // resulting combined work under terms of your choice, provided that
25 | // every copy of the combined work is accompanied by a complete copy of
26 | // the source code of Avisynth (the version of Avisynth used to produce the
27 | // combined work), being distributed under the terms of the GNU General
28 | // Public License plus this exception. An independent module is a module
29 | // which is not derived from or based on Avisynth, such as 3rd-party filters,
30 | // import and export plugins, or graphical user interfaces.
31 |
32 | #ifndef AVSCORE_CPUID_H
33 | #define AVSCORE_CPUID_H
34 |
35 | // For GetCPUFlags. These are backwards-compatible with those in VirtualDub.
36 | // ending with SSE4_2
37 | // For emulation see https://software.intel.com/en-us/articles/intel-software-development-emulator
38 | enum {
39 | /* oldest CPU to support extension */
40 | CPUF_FORCE = 0x01, // N/A
41 | CPUF_FPU = 0x02, // 386/486DX
42 | CPUF_MMX = 0x04, // P55C, K6, PII
43 | CPUF_INTEGER_SSE = 0x08, // PIII, Athlon
44 | CPUF_SSE = 0x10, // PIII, Athlon XP/MP
45 | CPUF_SSE2 = 0x20, // PIV, K8
46 | CPUF_3DNOW = 0x40, // K6-2
47 | CPUF_3DNOW_EXT = 0x80, // Athlon
48 | CPUF_X86_64 = 0xA0, // Hammer (note: equiv. to 3DNow + SSE2, which
49 | // only Hammer will have anyway)
50 | CPUF_SSE3 = 0x100, // PIV+, K8 Venice
51 | CPUF_SSSE3 = 0x200, // Core 2
52 | CPUF_SSE4 = 0x400,
53 | CPUF_SSE4_1 = 0x400, // Penryn, Wolfdale, Yorkfield
54 | CPUF_AVX = 0x800, // Sandy Bridge, Bulldozer
55 | CPUF_SSE4_2 = 0x1000, // Nehalem
56 | // AVS+
57 | CPUF_AVX2 = 0x2000, // Haswell
58 | CPUF_FMA3 = 0x4000,
59 | CPUF_F16C = 0x8000,
60 | CPUF_MOVBE = 0x10000, // Big Endian move
61 | CPUF_POPCNT = 0x20000,
62 | CPUF_AES = 0x40000,
63 | CPUF_FMA4 = 0x80000,
64 |
65 | CPUF_AVX512F = 0x100000, // AVX-512 Foundation.
66 | CPUF_AVX512DQ = 0x200000, // AVX-512 DQ (Double/Quad granular) Instructions
67 | CPUF_AVX512PF = 0x400000, // AVX-512 Prefetch
68 | CPUF_AVX512ER = 0x800000, // AVX-512 Exponential and Reciprocal
69 | CPUF_AVX512CD = 0x1000000, // AVX-512 Conflict Detection
70 | CPUF_AVX512BW = 0x2000000, // AVX-512 BW (Byte/Word granular) Instructions
71 | CPUF_AVX512VL = 0x4000000, // AVX-512 VL (128/256 Vector Length) Extensions
72 | CPUF_AVX512IFMA = 0x8000000, // AVX-512 IFMA integer 52 bit
73 | CPUF_AVX512VBMI = 0x10000000,// AVX-512 VBMI
74 | };
75 |
76 | #ifdef BUILDING_AVSCORE
77 | int GetCPUFlags();
78 | void SetMaxCPU(int new_flags);
79 | #endif
80 |
81 | #endif // AVSCORE_CPUID_H
82 |
--------------------------------------------------------------------------------
/Average/avs/filesystem.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | // Snippet copied from filesystem/README.md
4 |
5 | #if defined(__cplusplus) && __cplusplus >= 201703L && defined(__has_include)
6 | #if __has_include()
7 | #define GHC_USE_STD_FS
8 | #include
9 | namespace fs = std::filesystem;
10 | #endif
11 | #endif
12 | #ifndef GHC_USE_STD_FS
13 | #include
14 | namespace fs = ghc::filesystem;
15 | #endif
16 |
--------------------------------------------------------------------------------
/Average/avs/minmax.h:
--------------------------------------------------------------------------------
1 | // This program is free software; you can redistribute it and/or modify
2 | // it under the terms of the GNU General Public License as published by
3 | // the Free Software Foundation; either version 2 of the License, or
4 | // (at your option) any later version.
5 | //
6 | // This program is distributed in the hope that it will be useful,
7 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
8 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 | // GNU General Public License for more details.
10 | //
11 | // You should have received a copy of the GNU General Public License
12 | // along with this program; if not, write to the Free Software
13 | // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit
14 | // http://www.gnu.org/copyleft/gpl.html .
15 | //
16 | // Linking Avisynth statically or dynamically with other modules is making a
17 | // combined work based on Avisynth. Thus, the terms and conditions of the GNU
18 | // General Public License cover the whole combination.
19 | //
20 | // As a special exception, the copyright holders of Avisynth give you
21 | // permission to link Avisynth with independent modules that communicate with
22 | // Avisynth solely through the interfaces defined in avisynth.h, regardless of the license
23 | // terms of these independent modules, and to copy and distribute the
24 | // resulting combined work under terms of your choice, provided that
25 | // every copy of the combined work is accompanied by a complete copy of
26 | // the source code of Avisynth (the version of Avisynth used to produce the
27 | // combined work), being distributed under the terms of the GNU General
28 | // Public License plus this exception. An independent module is a module
29 | // which is not derived from or based on Avisynth, such as 3rd-party filters,
30 | // import and export plugins, or graphical user interfaces.
31 |
32 | #ifndef AVSCORE_MINMAX_H
33 | #define AVSCORE_MINMAX_H
34 |
35 | template
36 | T min(T v1, T v2)
37 | {
38 | return v1 < v2 ? v1 : v2;
39 | }
40 |
41 | template
42 | T max(T v1, T v2)
43 | {
44 | return v1 > v2 ? v1 : v2;
45 | }
46 |
47 | template
48 | T clamp(T n, T min, T max)
49 | {
50 | n = n > max ? max : n;
51 | return n < min ? min : n;
52 | }
53 |
54 | #endif // AVSCORE_MINMAX_H
55 |
--------------------------------------------------------------------------------
/Average/avs/posix.h:
--------------------------------------------------------------------------------
1 | // This program is free software; you can redistribute it and/or modify
2 | // it under the terms of the GNU General Public License as published by
3 | // the Free Software Foundation; either version 2 of the License, or
4 | // (at your option) any later version.
5 | //
6 | // This program is distributed in the hope that it will be useful,
7 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
8 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 | // GNU General Public License for more details.
10 | //
11 | // You should have received a copy of the GNU General Public License
12 | // along with this program; if not, write to the Free Software
13 | // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit
14 | // http://www.gnu.org/copyleft/gpl.html .
15 | //
16 | // Linking Avisynth statically or dynamically with other modules is making a
17 | // combined work based on Avisynth. Thus, the terms and conditions of the GNU
18 | // General Public License cover the whole combination.
19 | //
20 | // As a special exception, the copyright holders of Avisynth give you
21 | // permission to link Avisynth with independent modules that communicate with
22 | // Avisynth solely through the interfaces defined in avisynth.h, regardless of the license
23 | // terms of these independent modules, and to copy and distribute the
24 | // resulting combined work under terms of your choice, provided that
25 | // every copy of the combined work is accompanied by a complete copy of
26 | // the source code of Avisynth (the version of Avisynth used to produce the
27 | // combined work), being distributed under the terms of the GNU General
28 | // Public License plus this exception. An independent module is a module
29 | // which is not derived from or based on Avisynth, such as 3rd-party filters,
30 | // import and export plugins, or graphical user interfaces.
31 |
32 | #ifdef AVS_POSIX
33 | #ifndef AVSCORE_POSIX_H
34 | #define AVSCORE_POSIX_H
35 |
36 | #ifdef __cplusplus
37 | #include
38 | #endif
39 | #include
40 | #include
41 |
42 | // Define these MSVC-extension used in Avisynth
43 | #define __single_inheritance
44 |
45 | // These things don't exist in Linux
46 | #if defined(AVS_HAIKU)
47 | #undef __declspec
48 | #endif
49 | #define __declspec(x)
50 | #define lstrlen strlen
51 | #define lstrcmp strcmp
52 | #define lstrcmpi strcasecmp
53 | #define _stricmp strcasecmp
54 | #define _strnicmp strncasecmp
55 | #define _strdup strdup
56 | #define SetCurrentDirectory(x) chdir(x)
57 | #define SetCurrentDirectoryW(x) chdir(x)
58 | #define GetCurrentDirectoryW(x) getcwd(x)
59 | #define _putenv putenv
60 | #define _alloca alloca
61 |
62 | // Borrowing some compatibility macros from AvxSynth, slightly modified
63 | #define UInt32x32To64(a, b) ((uint64_t)(((uint64_t)((uint32_t)(a))) * ((uint32_t)(b))))
64 | #define Int64ShrlMod32(a, b) ((uint64_t)((uint64_t)(a) >> (b)))
65 | #define Int32x32To64(a, b) ((int64_t)(((int64_t)((long)(a))) * ((long)(b))))
66 |
67 | #define InterlockedIncrement(x) __sync_add_and_fetch((x), 1)
68 | #define InterlockedDecrement(x) __sync_sub_and_fetch((x), 1)
69 | #define MulDiv(nNumber, nNumerator, nDenominator) (int32_t) (((int64_t) (nNumber) * (int64_t) (nNumerator) + (int64_t) ((nDenominator)/2)) / (int64_t) (nDenominator))
70 |
71 | #ifndef TRUE
72 | #define TRUE true
73 | #endif
74 |
75 | #ifndef FALSE
76 | #define FALSE false
77 | #endif
78 |
79 | #define S_FALSE (0x00000001)
80 | #define E_FAIL (0x80004005)
81 | #define FAILED(hr) ((hr) & 0x80000000)
82 | #define SUCCEEDED(hr) (!FAILED(hr))
83 |
84 | // Statuses copied from comments in exception.cpp
85 | #define STATUS_GUARD_PAGE_VIOLATION 0x80000001
86 | #define STATUS_DATATYPE_MISALIGNMENT 0x80000002
87 | #define STATUS_BREAKPOINT 0x80000003
88 | #define STATUS_SINGLE_STEP 0x80000004
89 | #define STATUS_ACCESS_VIOLATION 0xc0000005
90 | #define STATUS_IN_PAGE_ERROR 0xc0000006
91 | #define STATUS_INVALID_HANDLE 0xc0000008
92 | #define STATUS_NO_MEMORY 0xc0000017
93 | #define STATUS_ILLEGAL_INSTRUCTION 0xc000001d
94 | #define STATUS_NONCONTINUABLE_EXCEPTION 0xc0000025
95 | #define STATUS_INVALID_DISPOSITION 0xc0000026
96 | #define STATUS_ARRAY_BOUNDS_EXCEEDED 0xc000008c
97 | #define STATUS_FLOAT_DENORMAL_OPERAND 0xc000008d
98 | #define STATUS_FLOAT_DIVIDE_BY_ZERO 0xc000008e
99 | #define STATUS_FLOAT_INEXACT_RESULT 0xc000008f
100 | #define STATUS_FLOAT_INVALID_OPERATION 0xc0000090
101 | #define STATUS_FLOAT_OVERFLOW 0xc0000091
102 | #define STATUS_FLOAT_STACK_CHECK 0xc0000092
103 | #define STATUS_FLOAT_UNDERFLOW 0xc0000093
104 | #define STATUS_INTEGER_DIVIDE_BY_ZERO 0xc0000094
105 | #define STATUS_INTEGER_OVERFLOW 0xc0000095
106 | #define STATUS_PRIVILEGED_INSTRUCTION 0xc0000096
107 | #define STATUS_STACK_OVERFLOW 0xc00000fd
108 |
109 | // Calling convension
110 | #ifndef AVS_HAIKU
111 | #define __stdcall
112 | #define __cdecl
113 | #endif
114 |
115 | // PowerPC OS X is really niche these days, but this painless equivocation
116 | // of the function/macro names used in posix_get_available_memory()
117 | // is all it takes to let it work. The G5 was 64-bit, and if 10.5 Leopard
118 | // can run in native 64-bit, it probably uses the names in that block as-is.
119 | #ifdef AVS_MACOS
120 | #ifdef PPC32
121 | #define vm_statistics64_data_t vm_statistics_data_t
122 | #define HOST_VM_INFO64_COUNT HOST_VM_INFO_COUNT
123 | #define HOST_VM_INFO64 HOST_VM_INFO
124 | #define host_statistics64 host_statistics
125 | #endif // PPC32
126 | #endif // AVS_MACOS
127 |
128 | #endif // AVSCORE_POSIX_H
129 | #endif // AVS_POSIX
130 |
--------------------------------------------------------------------------------
/Average/avs/types.h:
--------------------------------------------------------------------------------
1 | // Avisynth C Interface Version 0.20
2 | // Copyright 2003 Kevin Atkinson
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 | // As a special exception, I give you permission to link to the
20 | // Avisynth C interface with independent modules that communicate with
21 | // the Avisynth C interface solely through the interfaces defined in
22 | // avisynth_c.h, regardless of the license terms of these independent
23 | // modules, and to copy and distribute the resulting combined work
24 | // under terms of your choice, provided that every copy of the
25 | // combined work is accompanied by a complete copy of the source code
26 | // of the Avisynth C interface and Avisynth itself (with the version
27 | // used to produce the combined work), being distributed under the
28 | // terms of the GNU General Public License plus this exception. An
29 | // independent module is a module which is not derived from or based
30 | // on Avisynth C Interface, such as 3rd-party filters, import and
31 | // export plugins, or graphical user interfaces.
32 |
33 | #ifndef AVS_TYPES_H
34 | #define AVS_TYPES_H
35 |
36 | // Define all types necessary for interfacing with avisynth.dll
37 | #include
38 | #include
39 | #ifdef __cplusplus
40 | #include
41 | #include
42 | #else
43 | #include
44 | #include
45 | #endif
46 |
47 | // Raster types used by VirtualDub & Avisynth
48 | typedef uint32_t Pixel32;
49 | typedef uint8_t BYTE;
50 |
51 | // Audio Sample information
52 | typedef float SFLOAT;
53 |
54 | #endif //AVS_TYPES_H
55 |
--------------------------------------------------------------------------------
/Average/avs/win.h:
--------------------------------------------------------------------------------
1 | // This program is free software; you can redistribute it and/or modify
2 | // it under the terms of the GNU General Public License as published by
3 | // the Free Software Foundation; either version 2 of the License, or
4 | // (at your option) any later version.
5 | //
6 | // This program is distributed in the hope that it will be useful,
7 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
8 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 | // GNU General Public License for more details.
10 | //
11 | // You should have received a copy of the GNU General Public License
12 | // along with this program; if not, write to the Free Software
13 | // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit
14 | // http://www.gnu.org/copyleft/gpl.html .
15 | //
16 | // Linking Avisynth statically or dynamically with other modules is making a
17 | // combined work based on Avisynth. Thus, the terms and conditions of the GNU
18 | // General Public License cover the whole combination.
19 | //
20 | // As a special exception, the copyright holders of Avisynth give you
21 | // permission to link Avisynth with independent modules that communicate with
22 | // Avisynth solely through the interfaces defined in avisynth.h, regardless of the license
23 | // terms of these independent modules, and to copy and distribute the
24 | // resulting combined work under terms of your choice, provided that
25 | // every copy of the combined work is accompanied by a complete copy of
26 | // the source code of Avisynth (the version of Avisynth used to produce the
27 | // combined work), being distributed under the terms of the GNU General
28 | // Public License plus this exception. An independent module is a module
29 | // which is not derived from or based on Avisynth, such as 3rd-party filters,
30 | // import and export plugins, or graphical user interfaces.
31 |
32 | #ifndef AVSCORE_WIN_H
33 | #define AVSCORE_WIN_H
34 |
35 | // Whenever you need windows headers, start by including this file, then the rest.
36 |
37 | // WWUUT? We require XP now?
38 | #if !defined(NTDDI_VERSION) && !defined(_WIN32_WINNT)
39 | #define NTDDI_VERSION 0x05020000
40 | #define _WIN32_WINNT 0x0502
41 | #endif
42 |
43 | #define WIN32_LEAN_AND_MEAN
44 | #define STRICT
45 | #if !defined(NOMINMAX)
46 | #define NOMINMAX
47 | #endif
48 |
49 | #include
50 |
51 | // Provision for UTF-8 max 4 bytes per code point
52 | #define AVS_MAX_PATH MAX_PATH*4
53 |
54 | #endif // AVSCORE_WIN_H
55 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # We need CMake 3.8 at least, because we require
2 | # CMAKE_CXX_STANDARD to be set to C++17.
3 | # Visual Studio 2019 is supported from CMake 3.14.1
4 | # Possible generators:
5 | # "MinGW Makefiles": MSYS2/Mingw32 GCC 8.3 build
6 | # "Visual Studio 15 2017" optional platform generator Win32 and x64
7 |
8 | # "Visual Studio 16 2019" optional platform generator Win32 and x64
9 | # "Visual Studio 16 2019" + LLVM 8.0 (clang) optional platform generator Win32 and x64
10 | CMAKE_MINIMUM_REQUIRED( VERSION 3.8.2 )
11 |
12 | project("Average" LANGUAGES CXX)
13 | include(GNUInstallDirs)
14 |
15 | # Avoid uselessly linking to unused libraries
16 | set(CMAKE_STANDARD_LIBRARIES "" CACHE STRING "" FORCE)
17 | set(CMAKE_C_STANDARD_LIBRARIES "" CACHE STRING "" FORCE)
18 | set(CMAKE_CXX_STANDARD_LIBRARIES "" CACHE STRING "" FORCE)
19 |
20 | # We require C++17 or higher.
21 | set(CMAKE_CXX_STANDARD 17)
22 | set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
23 | set(CMAKE_CXX_EXTENSIONS FALSE)
24 |
25 | # Detect Intel processors and turn Intel SIMD on or off automatically.
26 | message("-- Detected target processor as: ${CMAKE_SYSTEM_PROCESSOR}")
27 | string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" ARCHID)
28 | if( ("${ARCHID}" STREQUAL "x86") OR
29 | ("${ARCHID}" STREQUAL "x64") OR
30 | ("${ARCHID}" STREQUAL "i686") OR
31 | ("${ARCHID}" STREQUAL "amd64") OR
32 | ("${ARCHID}" STREQUAL "x86_64") )
33 | set(INTEL_SIMD "ON")
34 | else()
35 | set(INTEL_SIMD "OFF")
36 | endif()
37 |
38 | option(ENABLE_INTEL_SIMD "Enable SIMD intrinsics for Intel processors" "${INTEL_SIMD}")
39 |
40 | if(CMAKE_CONFIGURATION_TYPES)
41 | set(CMAKE_CONFIGURATION_TYPES Debug Release RelWithDebInfo)
42 | set(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" CACHE STRING "Reset the configurations to what we need" FORCE)
43 | endif()
44 |
45 | IF( MSVC ) # Check for Visual Studio
46 | # We do not allow creating Visual Studio solutions, existing .sln file contains
47 | # all x86/x64 versions of MSVC and LLVM builds.
48 | MESSAGE(FATAL_ERROR "Please use the existing sln file both for MS VC and also for LLVM toolset in VS")
49 | # anyway we keep all things below
50 | # ** not tested **
51 |
52 |
53 |
54 |
55 | #1910-1919 = VS 15.0 (v141 toolset) Visual Studio 2017
56 | #1920 = VS 16.0 (v142 toolset) Visual Studio 2019
57 |
58 | IF( MSVC_VERSION VERSION_LESS 1910 )
59 | MESSAGE(FATAL_ERROR "Visual C++ 2017 or newer required.")
60 | ENDIF()
61 |
62 | IF(MSVC_IDE)
63 | message("Reported CMAKE_GENERATOR_TOOLSET is: ${CMAKE_GENERATOR_TOOLSET}")
64 |
65 | # For LLVM Clang installed separately, specify llvm or LLVM
66 | # Since Visual Studio 2019 v16.4, LLVM 9.0 is integrated, for this use Toolset: ClangCL
67 | IF(CMAKE_GENERATOR_TOOLSET STREQUAL "LLVM" OR CMAKE_GENERATOR_TOOLSET STREQUAL "llvm" OR CMAKE_GENERATOR_TOOLSET STREQUAL "ClangCL")
68 | if(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") # hope: always
69 | message("LLVM toolset was specified via -T. Compiler ID is: ${CMAKE_CXX_COMPILER_ID}; CMAKE_CXX_COMPILER_VERSION is: ${CMAKE_CXX_COMPILER_VERSION}")
70 | # Clang; 9.0.0
71 | # These are probably not supported when clang is downloaded as a ready-made binary: CLANG_VERSION_MAJOR CLANG_VERSION_MINOR CLANG_VERSION_STRING
72 | # string (REGEX REPLACE ".*clang version ([0-9]+\\.[0-9]+).*" "\\1" CLANG_VERSION_STRING ${clang_full_version_string})
73 | if( CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0.1 )
74 | MESSAGE(FATAL_ERROR "Clang 7.0.1 or newer required") # as of 2019.december actually we are using 9.0
75 | endif()
76 | endif()
77 | set(CLANG_IN_VS "1")
78 | ELSEIF(CMAKE_GENERATOR_TOOLSET STREQUAL "v141_clang_c2")
79 | #1900 is reported
80 | message("v141_clang_c2 toolset was specified via -T. Reported MSVC_VERSION is: ${MSVC_VERSION}")
81 | message("May not work, try LLVM")
82 | set(CLANG_IN_VS "1")
83 | ENDIF()
84 |
85 | option(WINXP_SUPPORT "Make binaries compatible with Windows XP and Vista" OFF)
86 | if(WINXP_SUPPORT)
87 | # We want our project to also run on Windows XP
88 | # Not for LLVM: Clang stopped XP support in 2016
89 | # 1900 (VS2015) is not supported but we leave here
90 | IF(MSVC_VERSION VERSION_LESS 1910 )
91 | IF(NOT CLANG_IN_VS STREQUAL "1")
92 | set(CMAKE_GENERATOR_TOOLSET "v140_xp" CACHE STRING "The compiler toolset to use for Visual Studio." FORCE) # VS2015
93 | # https://connect.microsoft.com/VisualStudio/feedback/details/1789709/visual-c-2015-runtime-broken-on-windows-server-2003-c-11-magic-statics
94 | message("CMAKE_GENERATOR_TOOLSET is forced to: ${CMAKE_GENERATOR_TOOLSET}")
95 | add_definitions("/Zc:threadSafeInit-")
96 | ENDIF()
97 | ELSE()
98 | IF(NOT CLANG_IN_VS STREQUAL "1")
99 | set(CMAKE_GENERATOR_TOOLSET "v141_xp" CACHE STRING "The compiler toolset to use for Visual Studio." FORCE) # VS2017, also choosable for VS2019
100 | # https://connect.microsoft.com/VisualStudio/feedback/details/1789709/visual-c-2015-runtime-broken-on-windows-server-2003-c-11-magic-statics
101 | message("CMAKE_GENERATOR_TOOLSET is forced to: ${CMAKE_GENERATOR_TOOLSET}")
102 | add_definitions("/Zc:threadSafeInit-")
103 | ENDIF()
104 | ENDIF()
105 | endif()
106 | ENDIF()
107 |
108 | IF(CLANG_IN_VS STREQUAL "1")
109 | #these are unknown
110 | #set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fexceptions")
111 | #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexceptions")
112 | STRING( REPLACE "/EHsc" "/EHa" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
113 | STRING( REPLACE "/EHsc" "/EHa" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
114 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-inconsistent-missing-override")
115 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-inconsistent-missing-override")
116 | ELSE()
117 | # Enable C++ with SEH exceptions
118 | # Avoid an obnoxious 'overrriding /EHsc with /EHa' warning when
119 | # using something other than MSBuild
120 | STRING( REPLACE "/EHsc" "/EHa" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
121 | STRING( REPLACE "/EHsc" "/EHa" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
122 | ENDIF()
123 | # Prevent VC++ from complaining about not using MS-specific functions
124 | add_definitions("/D _CRT_SECURE_NO_WARNINGS /D _SECURE_SCL=0")
125 |
126 | # Enable CRT heap debugging - only effective in debug builds
127 | add_definitions("/D _CRTDBG_MAP_ALLOC")
128 |
129 | # Set additional optimization flags
130 | set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /Oy /Ot /GS- /Oi")
131 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Oy /Ot /GS- /Oi")
132 |
133 | # CPU_ARCH can be overridden with the corresponding values when using MSVC:
134 | # IA32 (disabled),
135 | # SSE (Pentium III and higher, 1999),
136 | # SSE2 (Pentium 4 and higher, 2000/2001),
137 | # AVX (Sandy Bridge and higher, 2011),
138 | # AVX2 (Haswell and higher, 2013)
139 | set(MSVC_CPU_ARCH "SSE2" CACHE STRING "Set MSVC architecture optimization level (default: SSE2)")
140 |
141 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /arch:${MSVC_CPU_ARCH}")
142 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:${MSVC_CPU_ARCH}")
143 |
144 | if(CMAKE_SIZEOF_VOID_P EQUAL 8)
145 | # MSVC doesn't allow 64-bit builds to have their /arch set to SSE2 (no-op) or below
146 | if("${MSVC_CPU_ARCH}" MATCHES "(IA32|SSE|SSE2)")
147 | set(DELETE_THIS "/arch:${MSVC_CPU_ARCH}")
148 | message("MSVC doesn't allow x86-64 builds to define /arch:${MSVC_CPU_ARCH}. Setting will be ignored.")
149 | STRING( REPLACE "${DELETE_THIS}" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
150 | STRING( REPLACE "${DELETE_THIS}" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
151 | endif()
152 | endif()
153 |
154 | IF(CLANG_IN_VS STREQUAL "1")
155 | # suppress other frequent but harmless/unavoidable warnings
156 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-function")
157 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function")
158 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-reorder")
159 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-reorder")
160 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-value")
161 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-value")
162 | # allow per-function attributes like __attribute__((__target__("sse4.1")))
163 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-gcc-compat")
164 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-gcc-compat")
165 | ENDIF()
166 |
167 | # Set C++17 flag
168 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /std:c++17")
169 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++17")
170 |
171 | # Enable standards-conformance mode for MSVC compilers that support this
172 | # flag (Visual C++ 2017 and later).
173 | if (NOT (MSVC_VERSION LESS 1910))
174 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /permissive-")
175 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /permissive-")
176 | endif()
177 |
178 | if(ENABLE_INTEL_SIMD)
179 | add_definitions("/D INTEL_INTRINSICS")
180 | endif()
181 |
182 | ELSE()
183 |
184 | if(ENABLE_INTEL_SIMD)
185 | SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse2 -DINTEL_INTRINSICS" )
186 | endif()
187 |
188 | if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
189 | SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-format-security" )
190 | endif()
191 |
192 | IF(WIN32)
193 | SET( CMAKE_SHARED_LINKER_FLAGS "-Wl,--enable-stdcall-fixup" )
194 | ELSE()
195 | if(APPLE)
196 | # macOS uses Clang's linker, doesn't like --no-undefined
197 | SET( CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-undefined,error" )
198 | else()
199 | if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
200 | # make sure there are no undefined symbols
201 | SET( CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined" )
202 | endif()
203 | endif()
204 | ENDIF()
205 | ENDIF()
206 |
207 | IF(ENABLE_INTEL_SIMD)
208 | message("Intel SIMD enabled")
209 | ELSE()
210 | message("Intel SIMD disabled")
211 | ENDIF()
212 |
213 | add_subdirectory("Average")
214 |
215 | # uninstall target
216 | configure_file(
217 | "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
218 | "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
219 | IMMEDIATE @ONLY)
220 |
221 | add_custom_target(uninstall
222 | COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
223 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinterf/Average/ec21ee1bdc4164cd3c98ba9b848179e77d083dd7/LICENSE
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Average ##
2 |
3 | A simple plugin that calculates weighted average of multiple frames.
4 |
5 | ### Usage
6 | ```
7 | Average(clip1, weight1, clip2, weight2, clip3, weight3, ...)
8 | ```
9 | The usage is identical to the old Average plugin or RedAverage.
10 | Output pixel value is calculated as
11 | ```
12 | out[x] = clip1[x] * weight1 + clip2[x] * weight2 + clip3[x] * weight3...
13 | ```
14 | The filter performs faster when all weight in the call are less or equal to one. This filter should be faster than the old Average and more stable (alas slower) than RedAverage.
15 |
16 | ### Build instructions
17 | VS2019:
18 | use IDE
19 |
20 | Windows GCC (mingw installed by msys2):
21 | from the 'build' folder under project root:
22 |
23 | del ..\CMakeCache.txt
24 | cmake .. -G "MinGW Makefiles" -DENABLE_INTEL_SIMD:bool=on
25 | @rem test: cmake .. -G "MinGW Makefiles" -DENABLE_INTEL_SIMD:bool=off
26 | cmake --build . --config Release
27 |
28 | Linux
29 | from the 'build' folder under project root:
30 | ENABLE_INTEL_SIMD is automatically off for non x86 arhitectures
31 |
32 | * Clone repo and build
33 |
34 | git clone https://github.com/pinterf/Average
35 | cd Average
36 | cmake -B build -S .
37 | cmake --build build
38 |
39 | Useful hints:
40 | build after clean:
41 |
42 | cmake --build build --clean-first
43 |
44 | Force no asm support
45 |
46 | cmake -B build -S . -DENABLE_INTEL_SIMD:bool=off
47 |
48 | delete cmake cache
49 |
50 | rm build/CMakeCache.txt
51 |
52 | * Find binaries at
53 |
54 | build/Average/libaverage.so
55 |
56 | * Install binaries
57 |
58 | cd build
59 | sudo make install
60 |
61 | ### History
62 | ```
63 | v0.95 (20211008)
64 | - add AVX2 routines
65 | - accept parameter as a nested array stuffed into the first parameter (AVS 3.7.1)
66 | - pass over frame properties if any (Avisynth interface v8+ check)
67 | - Source: update to VS2019, clang-cl option, gcc and linux friendly
68 | - add CMake build environment, linux build instructions
69 | - Make it compilable for non-Intel processors (C only)
70 |
71 | v0.94 (20170127)
72 | Fix: fix the fix: rounding of intermediate results was ok for two clips
73 | New: AVX for 10-16bit (+20-30%) and float (+50-60%) compared to v0.93
74 | AVX for 8 bit non-integer path (+20% gain), e.g. when one of the weights is over 1.0
75 | Note 1: AVX needs 32 byte frame alignment (Avisynth+ default)
76 | Note 2: AVX CPU flag is reported by recent Avisynth+ version
77 | Note 3: AVX is reported only on approriate OS (from Windows 7 SP1 on)
78 |
79 | v0.93 (20170126 - pinterf)
80 | Fix: rounding of intermediate results in fast integer average of 8 bit clips
81 | Mod: faster results for two or three clips
82 | New: Support for Avisynth+ color spaces: 10-16 bit and float YUV(A)/Planar RGB(A), RGB48 and RGB64
83 | 10+ bits are calculated in float precision internally.
84 | New: auto register as NICE_FILTER for Avisynth+
85 | New: add version resource
86 | Info: built with VS2015 Update 3, may require Visual Studio 2015 Redistributable update 3
87 |
88 | v0.92 (20131227 - tp7)
89 | This release fixes a very important memory leak which made the plugin unusable for somewhat complex scripts.
90 |
91 | v0.91 (20131224 - tp7)
92 | Double performance when absolute values of all weights are smaller or equal to one.
93 |
94 | v0.90 (20131221 - tp7)
95 | Initial release.
96 | ```
97 |
98 |
--------------------------------------------------------------------------------
/cmake_uninstall.cmake.in:
--------------------------------------------------------------------------------
1 | if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
2 | message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
3 | endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
4 |
5 | file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
6 | string(REGEX REPLACE "\n" ";" files "${files}")
7 | foreach(file ${files})
8 | message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
9 | if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
10 | exec_program(
11 | "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
12 | OUTPUT_VARIABLE rm_out
13 | RETURN_VALUE rm_retval
14 | )
15 | if(NOT "${rm_retval}" STREQUAL 0)
16 | message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
17 | endif(NOT "${rm_retval}" STREQUAL 0)
18 | else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
19 | message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
20 | endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
21 | endforeach(file)
22 |
--------------------------------------------------------------------------------