├── .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 | --------------------------------------------------------------------------------