├── .github └── workflows │ ├── check-smp.yml │ └── github-ci.yml ├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── assrender.sln ├── assrender.vcxproj ├── assrender.vcxproj.filters ├── assrender_with_latest_sdk.bat ├── cmake_uninstall.cmake.in ├── docs ├── BUILD.md ├── CHANGELOG.md └── README.md ├── lib ├── x86-32 │ └── readme.txt └── x86-64 │ └── readme.txt └── src ├── ASSRender.rc ├── CMakeLists.txt ├── assrender.c ├── assrender.def ├── assrender.h ├── include ├── avisynth_c.h └── avs │ ├── capi.h │ ├── config.h │ └── types.h ├── render.c ├── render.h ├── sub.c ├── sub.h ├── timecodes.c └── timecodes.h /.github/workflows/check-smp.yml: -------------------------------------------------------------------------------- 1 | name: Update data 2 | on: 3 | push: 4 | branches: 5 | - main 6 | schedule: 7 | - cron: '0 5 * * *' 8 | workflow_dispatch: # 9 | 10 | env: 11 | submodule_owner: ShiftMediaProject 12 | submodule_folder: SMP 13 | 14 | jobs: 15 | check_smp: 16 | runs-on: ubuntu-latest 17 | strategy: 18 | matrix: 19 | submodule: 20 | - fontconfig 21 | - freetype2 22 | - fribidi 23 | - harfbuzz 24 | - libass 25 | - libiconv 26 | - liblzma 27 | - libxml2 28 | - zlib 29 | steps: 30 | - name: Git checkout 31 | uses: actions/checkout@v3 32 | with: 33 | ref: master 34 | - name: Set submodule current 35 | run: | 36 | git submodule update --init --recursive "${{ env.submodule_folder }}/${{ matrix.submodule }}" 37 | cd ${{ env.submodule_folder }}/${{ matrix.submodule }} 38 | echo SUBMODULE_NAME=${{ matrix.submodule }} >> $GITHUB_ENV 39 | echo SUBMODULE_REV=$(git describe --tags --first-parent --abbrev=7 --long --dirty) >> $GITHUB_ENV 40 | echo SUBMODULE_SHA=$(git rev-parse HEAD) >> $GITHUB_ENV 41 | - name: Get submodule current remote 42 | id: current 43 | uses: cardinalby/git-get-release-action@1.2.2 44 | env: 45 | GITHUB_TOKEN: ${{ github.token }} 46 | with: 47 | repo: ${{ env.submodule_owner }}/${{ matrix.submodule }} 48 | commitSha: ${{ env.SUBMODULE_SHA }} 49 | doNotFailIfNotFound: true 50 | - name: Get submodule latest remote 51 | id: latest 52 | uses: cardinalby/git-get-release-action@1.2.2 53 | env: 54 | GITHUB_TOKEN: ${{ github.token }} 55 | with: 56 | repo: ${{ env.submodule_owner }}/${{ matrix.submodule }} 57 | latest: true 58 | prerelease: false 59 | doNotFailIfNotFound: true 60 | - name: Set submodule current remote 61 | if: steps.current.outputs.tag_name != '' 62 | run: echo SUBMODULE_REV=${{ steps.current.outputs.tag_name }} >> $GITHUB_ENV 63 | - name: Check if need update 64 | if: | 65 | steps.latest.outputs.tag_name != '' && 66 | steps.current.outputs.tag_name == '' || 67 | steps.latest.outputs.tag_name != '' && 68 | steps.current.outputs.tag_name != steps.latest.outputs.tag_name 69 | run: | 70 | cd ${{ env.submodule_folder }}/${{ matrix.submodule }} 71 | git checkout ${{ steps.latest.outputs.tag_name }} 72 | echo NEED_UPDATE=1 >> $GITHUB_ENV 73 | - name: Run update 74 | if: ${{ env.NEED_UPDATE }} == '1' 75 | uses: peter-evans/create-pull-request@v4 76 | with: 77 | commit-message: Update ${{ matrix.submodule }} to ${{ steps.latest.outputs.tag_name }} 78 | branch: submodule-${{ matrix.submodule }}-${{ steps.latest.outputs.tag_name }} 79 | base: master 80 | delete-branch: true 81 | title: Update ${{ matrix.submodule }} to ${{ steps.latest.outputs.tag_name }} 82 | body: | 83 | Update ${{ matrix.submodule }} to ${{ steps.latest.outputs.tag_name }} 84 | Current: ${{ env.SUBMODULE_REV }} 85 | -------------------------------------------------------------------------------- /.github/workflows/github-ci.yml: -------------------------------------------------------------------------------- 1 | name: GitHub CI 2 | 3 | on: 4 | push: 5 | pull_request: 6 | workflow_dispatch: # 7 | 8 | jobs: 9 | build-linux: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Git checkout 13 | uses: actions/checkout@v3 14 | - name: Install dependencies 15 | run: | 16 | sudo apt-get update 17 | sudo apt-get install cmake git ninja-build checkinstall 18 | sudo apt-get install -y --no-install-recommends build-essential g++ gcc libass-dev pkg-config 19 | git clone https://github.com/AviSynth/AviSynthPlus avsplus 20 | cd avsplus 21 | cmake -G "Ninja" -B avisynth-build -S . 22 | cd avisynth-build 23 | ninja 24 | sudo checkinstall --pkgname=avisynth --pkgversion="$(grep -r Version avs_core/avisynth.pc | cut -f2 -d " ")-$(date --rfc-3339=date | sed 's/-//g')-git" --backup=no --deldoc=yes --delspec=yes --deldesc=yes --strip=yes --stripso=yes --addso=yes --fstrans=no --default ninja install 25 | - name: Build binary 26 | run: | 27 | cmake -B build -S . 28 | cmake --build build --clean-first 29 | - name: Copy binary 30 | run: cmake -E copy "build/src/libassrender.so" "dist/libassrender.so" 31 | - name: Upload artifact 32 | uses: actions/upload-artifact@v2 33 | with: 34 | name: assrender_bin_linux 35 | path: dist 36 | 37 | build-win: 38 | runs-on: windows-2019 39 | steps: 40 | - name: Git checkout 41 | uses: actions/checkout@v3 42 | - name: Install dependencies 43 | run: | 44 | git submodule update --init --recursive 45 | git clone https://github.com/ShiftMediaProject/VSYASM.git 46 | .\VSYASM\install_script.bat 47 | git clone https://github.com/ShiftMediaProject/VSNASM.git 48 | .\VSNASM\install_script.bat 49 | md avsplus 50 | # - name: Install MSYS2 with dependencies 51 | # uses: msys2/setup-msys2@v2 52 | # with: 53 | # update: true 54 | # install: base-devel git mingw-w64-x86_64-gcc mingw-w64-x86_64-cmake mingw-w64-x86_64-libass 55 | # msystem: MINGW64 56 | # path-type: inherit 57 | - name: Parse AviSynth+ release metadata 58 | uses: actions/github-script@v6 59 | with: 60 | script: | 61 | const req = await github.request('https://api.github.com/repos/avisynth/avisynthplus/releases'); 62 | const data = req.data; 63 | let link = ''; 64 | for(let rel of data){ 65 | if(rel.prerelease||rel.draft){ 66 | continue; 67 | } 68 | for(let asset of rel.assets){ 69 | if(asset.name.match(/-filesonly.7z$/i)){ 70 | link = asset.browser_download_url; 71 | } 72 | } 73 | if(link != ''){ 74 | break; 75 | } 76 | } 77 | core.exportVariable('PACKAGE_URL', link); 78 | - name: Download AviSynth+ latest release 79 | run: curl -L "${{ env.PACKAGE_URL }}" -o "./avsplus/avisynthplus-latest-filesonly.7z" 80 | - name: Move libs files 81 | run: | 82 | 7z e "avsplus\*-filesonly.7z" -o"lib\x86-32" "*\x86\c_api\AviSynth.lib" 83 | 7z e "avsplus\*-filesonly.7z" -o"lib\x86-64" "*\x64\c_api\AviSynth.lib" 84 | - name: Add MSBuild to PATH 85 | uses: microsoft/setup-msbuild@v1 86 | - name: Build x86 binary 87 | run: MSBuild.exe /t:Rebuild /p:PlatformToolset=v142 /m /p:Configuration=Release /p:Platform=x86 88 | - name: Build x64 binary 89 | run: MSBuild.exe /t:Rebuild /p:PlatformToolset=v142 /m /p:Configuration=Release /p:Platform=x64 90 | # - name: Build MINGW64 binary 91 | # shell: msys2 {0} 92 | # run: | 93 | # cmake -G "MinGW Makefiles" -B build -S . 94 | # cmake --build build --config Release --clean-first 95 | - name: Copy x86 binary 96 | run: cmake -E copy "bin\Release_Win32\assrender.dll" "dist\Release_x86\assrender.dll" 97 | - name: Copy x64 binary 98 | run: cmake -E copy "bin\Release_x64\assrender.dll" "dist\Release_x64\assrender.dll" 99 | # - name: Copy MINGW64 binary 100 | # run: cmake -E copy "build\src\assrender.dll" "dist\Release_MINGW64\assrender.dll" 101 | - name: Upload artifact 102 | uses: actions/upload-artifact@v2 103 | with: 104 | name: assrender_bin_win 105 | path: dist 106 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | lib/*/avisynth.lib 2 | 3 | CMakeCache.txt 4 | CMakeFiles/* 5 | cmake.db 6 | 7 | *.aps 8 | *.db 9 | *.opendb 10 | *.opensdf 11 | *.sdf 12 | *.suo 13 | *.user 14 | #cmake generated files 15 | cmake_install.cmake 16 | cmake_uninstall.cmake 17 | generate.stamp 18 | generate.stamp.depend 19 | makefile 20 | 21 | #make 22 | install_manifest.txt 23 | 24 | avsplus/ 25 | SMP/ 26 | VSNASM/ 27 | VSYASM/ 28 | 29 | #*/build/.vs 30 | */build/Win32 31 | */build/x64 32 | Test 33 | 34 | # Build results 35 | [Dd]ebug/ 36 | [Dd]ebugPublic/ 37 | [Rr]elease/ 38 | [Rr]eleases/ 39 | [Rr]elWithDebInfo/ 40 | x64/ 41 | x86/ 42 | bld/ 43 | [Bb]uild/ 44 | [Bb]in/ 45 | [Oo]bj/ 46 | [Ll]og/ 47 | /msvc 48 | # Visual C++ cache files 49 | ipch/ 50 | *.aps 51 | *.ncb 52 | *.opendb 53 | *.opensdf 54 | *.sdf 55 | *.cachefile 56 | *.VC.db 57 | *.VC.VC.opendb 58 | *.VC.db-shm 59 | *.VC.db-wal 60 | 61 | # Visual Studio profiler 62 | *.psess 63 | *.vsp 64 | *.vspx 65 | *.sap 66 | 67 | # Visual Studio 2015 cache/options directory 68 | .vs/ 69 | # Uncomment if you have tasks that create the project's static files in wwwroot 70 | #wwwroot/ 71 | 72 | # MSTest test Results 73 | [Tt]est[Rr]esult*/ 74 | [Bb]uild[Ll]og.* 75 | 76 | # NUNIT 77 | *.VisualState.xml 78 | TestResult.xml 79 | 80 | # Build Results of an ATL Project 81 | [Dd]ebugPS/ 82 | [Rr]eleasePS/ 83 | dlldata.c 84 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "SMP/libass"] 2 | path = SMP/libass 3 | url = https://github.com/ShiftMediaProject/libass.git 4 | [submodule "SMP/libiconv"] 5 | path = SMP/libiconv 6 | url = https://github.com/ShiftMediaProject/libiconv.git 7 | [submodule "SMP/harfbuzz"] 8 | path = SMP/harfbuzz 9 | url = https://github.com/ShiftMediaProject/harfbuzz.git 10 | [submodule "SMP/fontconfig"] 11 | path = SMP/fontconfig 12 | url = https://github.com/ShiftMediaProject/fontconfig.git 13 | [submodule "SMP/freetype2"] 14 | path = SMP/freetype2 15 | url = https://github.com/ShiftMediaProject/freetype2.git 16 | [submodule "SMP/libxml2"] 17 | path = SMP/libxml2 18 | url = https://github.com/ShiftMediaProject/libxml2.git 19 | [submodule "fribidi"] 20 | path = fribidi 21 | url = https://github.com/ShiftMediaProject/fribidi.git 22 | [submodule "SMP/fribidi"] 23 | path = SMP/fribidi 24 | url = https://github.com/ShiftMediaProject/fribidi.git 25 | [submodule "SMP/liblzma"] 26 | path = SMP/liblzma 27 | url = https://github.com/ShiftMediaProject/liblzma.git 28 | [submodule "SMP/zlib"] 29 | path = SMP/zlib 30 | url = https://github.com/ShiftMediaProject/zlib.git 31 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 3.12) 2 | PROJECT(assrender) 3 | 4 | include(GNUInstallDirs) 5 | 6 | ADD_SUBDIRECTORY(src) 7 | 8 | IF(MINGW) 9 | SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-libgcc -Wl,--add-stdcall-alias") 10 | SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -Wpedantic") 11 | SET(CMAKE_SHARED_LINKER_FLAGS_RELEASE "-s") 12 | SET(CMAKE_C_FLAGS_RELEASE "-O3") 13 | ENDIF() 14 | 15 | # uninstall target 16 | configure_file( 17 | "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in" 18 | "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" 19 | IMMEDIATE @ONLY) 20 | 21 | add_custom_target(uninstall 22 | COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) 23 | -------------------------------------------------------------------------------- /assrender.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "assrender", "assrender.vcxproj", "{A8A845C1-48C9-4D03-8D1D-6A6C023EE319}" 7 | ProjectSection(ProjectDependencies) = postProject 8 | {19677DFD-C020-434D-9CB1-D0F105E72770} = {19677DFD-C020-434D-9CB1-D0F105E72770} 9 | EndProjectSection 10 | EndProject 11 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libfontconfig", "SMP\fontconfig\SMP\libfontconfig.vcxproj", "{DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}" 12 | ProjectSection(ProjectDependencies) = postProject 13 | {E62DC439-DE3B-4F2F-84DF-B34E51FA1969} = {E62DC439-DE3B-4F2F-84DF-B34E51FA1969} 14 | {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B} = {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B} 15 | {CFE70273-7A79-4815-AF95-1E02E2675E37} = {CFE70273-7A79-4815-AF95-1E02E2675E37} 16 | EndProjectSection 17 | EndProject 18 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libfreetype2", "SMP\freetype2\SMP\libfreetype2.vcxproj", "{E62DC439-DE3B-4F2F-84DF-B34E51FA1969}" 19 | EndProject 20 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libfribidi", "SMP\fribidi\SMP\libfribidi.vcxproj", "{08091723-A142-478B-A092-20741BA8FAE2}" 21 | EndProject 22 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libharfbuzz", "SMP\harfbuzz\SMP\libharfbuzz.vcxproj", "{9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}" 23 | ProjectSection(ProjectDependencies) = postProject 24 | {E62DC439-DE3B-4F2F-84DF-B34E51FA1969} = {E62DC439-DE3B-4F2F-84DF-B34E51FA1969} 25 | EndProjectSection 26 | EndProject 27 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libass", "SMP\libass\SMP\libass.vcxproj", "{19677DFD-C020-434D-9CB1-D0F105E72770}" 28 | ProjectSection(ProjectDependencies) = postProject 29 | {08091723-A142-478B-A092-20741BA8FAE2} = {08091723-A142-478B-A092-20741BA8FAE2} 30 | {E62DC439-DE3B-4F2F-84DF-B34E51FA1969} = {E62DC439-DE3B-4F2F-84DF-B34E51FA1969} 31 | {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B} = {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B} 32 | {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF} = {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF} 33 | {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC} = {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC} 34 | EndProjectSection 35 | EndProject 36 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libiconv", "SMP\libiconv\SMP\libiconv.vcxproj", "{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}" 37 | EndProject 38 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "liblzma", "SMP\liblzma\SMP\liblzma.vcxproj", "{85763F39-23DF-4C04-B7DF-7FBE3E7CF336}" 39 | EndProject 40 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxml2", "SMP\libxml2\SMP\libxml2.vcxproj", "{CFE70273-7A79-4815-AF95-1E02E2675E37}" 41 | ProjectSection(ProjectDependencies) = postProject 42 | {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32} = {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32} 43 | {85763F39-23DF-4C04-B7DF-7FBE3E7CF336} = {85763F39-23DF-4C04-B7DF-7FBE3E7CF336} 44 | EndProjectSection 45 | EndProject 46 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libzlib", "SMP\zlib\SMP\libzlib.vcxproj", "{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}" 47 | EndProject 48 | Global 49 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 50 | Debug|x64 = Debug|x64 51 | Debug|x86 = Debug|x86 52 | DebugDLL|x64 = DebugDLL|x64 53 | DebugDLL|x86 = DebugDLL|x86 54 | DebugDLLStaticDeps|x64 = DebugDLLStaticDeps|x64 55 | DebugDLLStaticDeps|x86 = DebugDLLStaticDeps|x86 56 | Release|x64 = Release|x64 57 | Release|x86 = Release|x86 58 | ReleaseDLL|x64 = ReleaseDLL|x64 59 | ReleaseDLL|x86 = ReleaseDLL|x86 60 | ReleaseDLLStaticDeps|x64 = ReleaseDLLStaticDeps|x64 61 | ReleaseDLLStaticDeps|x86 = ReleaseDLLStaticDeps|x86 62 | ReleaseLTO|x64 = ReleaseLTO|x64 63 | ReleaseLTO|x86 = ReleaseLTO|x86 64 | EndGlobalSection 65 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 66 | {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.Debug|x64.ActiveCfg = Debug|x64 67 | {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.Debug|x64.Build.0 = Debug|x64 68 | {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.Debug|x86.ActiveCfg = Debug|Win32 69 | {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.Debug|x86.Build.0 = Debug|Win32 70 | {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.DebugDLL|x64.ActiveCfg = Debug|x64 71 | {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.DebugDLL|x64.Build.0 = Debug|x64 72 | {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.DebugDLL|x86.ActiveCfg = Debug|Win32 73 | {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.DebugDLL|x86.Build.0 = Debug|Win32 74 | {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.DebugDLLStaticDeps|x64.ActiveCfg = Debug|x64 75 | {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.DebugDLLStaticDeps|x64.Build.0 = Debug|x64 76 | {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.DebugDLLStaticDeps|x86.ActiveCfg = Debug|Win32 77 | {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.DebugDLLStaticDeps|x86.Build.0 = Debug|Win32 78 | {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.Release|x64.ActiveCfg = Release|x64 79 | {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.Release|x64.Build.0 = Release|x64 80 | {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.Release|x86.ActiveCfg = Release|Win32 81 | {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.Release|x86.Build.0 = Release|Win32 82 | {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.ReleaseDLL|x64.ActiveCfg = Release|x64 83 | {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.ReleaseDLL|x64.Build.0 = Release|x64 84 | {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.ReleaseDLL|x86.ActiveCfg = Release|Win32 85 | {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.ReleaseDLL|x86.Build.0 = Release|Win32 86 | {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.ReleaseDLLStaticDeps|x64.ActiveCfg = Release|x64 87 | {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.ReleaseDLLStaticDeps|x64.Build.0 = Release|x64 88 | {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.ReleaseDLLStaticDeps|x86.ActiveCfg = Release|Win32 89 | {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.ReleaseDLLStaticDeps|x86.Build.0 = Release|Win32 90 | {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.ReleaseLTO|x64.ActiveCfg = Release|x64 91 | {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.ReleaseLTO|x64.Build.0 = Release|x64 92 | {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.ReleaseLTO|x86.ActiveCfg = Release|Win32 93 | {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.ReleaseLTO|x86.Build.0 = Release|Win32 94 | {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.Debug|x64.ActiveCfg = Debug|x64 95 | {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.Debug|x64.Build.0 = Debug|x64 96 | {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.Debug|x86.ActiveCfg = Debug|Win32 97 | {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.Debug|x86.Build.0 = Debug|Win32 98 | {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 99 | {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.DebugDLL|x64.Build.0 = DebugDLL|x64 100 | {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32 101 | {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.DebugDLL|x86.Build.0 = DebugDLL|Win32 102 | {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLLWinRT|x64 103 | {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.DebugDLLStaticDeps|x64.Build.0 = DebugDLLWinRT|x64 104 | {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLLWinRT|Win32 105 | {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.DebugDLLStaticDeps|x86.Build.0 = DebugDLLWinRT|Win32 106 | {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.Release|x64.ActiveCfg = Release|x64 107 | {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.Release|x64.Build.0 = Release|x64 108 | {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.Release|x86.ActiveCfg = Release|Win32 109 | {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.Release|x86.Build.0 = Release|Win32 110 | {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 111 | {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 112 | {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32 113 | {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32 114 | {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLLStaticDeps|x64 115 | {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLLStaticDeps|x64 116 | {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLLStaticDeps|Win32 117 | {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLLStaticDeps|Win32 118 | {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.ReleaseLTO|x64.ActiveCfg = ReleaseWinRT|x64 119 | {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.ReleaseLTO|x64.Build.0 = ReleaseWinRT|x64 120 | {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.ReleaseLTO|x86.ActiveCfg = ReleaseWinRT|Win32 121 | {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.ReleaseLTO|x86.Build.0 = ReleaseWinRT|Win32 122 | {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.Debug|x64.ActiveCfg = Debug|x64 123 | {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.Debug|x64.Build.0 = Debug|x64 124 | {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.Debug|x86.ActiveCfg = Debug|Win32 125 | {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.Debug|x86.Build.0 = Debug|Win32 126 | {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 127 | {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.DebugDLL|x64.Build.0 = DebugDLL|x64 128 | {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32 129 | {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.DebugDLL|x86.Build.0 = DebugDLL|Win32 130 | {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLL|x64 131 | {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.DebugDLLStaticDeps|x64.Build.0 = DebugDLL|x64 132 | {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLL|Win32 133 | {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.DebugDLLStaticDeps|x86.Build.0 = DebugDLL|Win32 134 | {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.Release|x64.ActiveCfg = Release|x64 135 | {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.Release|x64.Build.0 = Release|x64 136 | {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.Release|x86.ActiveCfg = Release|Win32 137 | {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.Release|x86.Build.0 = Release|Win32 138 | {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 139 | {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 140 | {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32 141 | {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32 142 | {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLL|x64 143 | {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLL|x64 144 | {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLL|Win32 145 | {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLL|Win32 146 | {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.ReleaseLTO|x64.ActiveCfg = ReleaseWinRT|x64 147 | {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.ReleaseLTO|x64.Build.0 = ReleaseWinRT|x64 148 | {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.ReleaseLTO|x86.ActiveCfg = ReleaseWinRT|Win32 149 | {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.ReleaseLTO|x86.Build.0 = ReleaseWinRT|Win32 150 | {08091723-A142-478B-A092-20741BA8FAE2}.Debug|x64.ActiveCfg = Debug|x64 151 | {08091723-A142-478B-A092-20741BA8FAE2}.Debug|x64.Build.0 = Debug|x64 152 | {08091723-A142-478B-A092-20741BA8FAE2}.Debug|x86.ActiveCfg = Debug|Win32 153 | {08091723-A142-478B-A092-20741BA8FAE2}.Debug|x86.Build.0 = Debug|Win32 154 | {08091723-A142-478B-A092-20741BA8FAE2}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 155 | {08091723-A142-478B-A092-20741BA8FAE2}.DebugDLL|x64.Build.0 = DebugDLL|x64 156 | {08091723-A142-478B-A092-20741BA8FAE2}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32 157 | {08091723-A142-478B-A092-20741BA8FAE2}.DebugDLL|x86.Build.0 = DebugDLL|Win32 158 | {08091723-A142-478B-A092-20741BA8FAE2}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLL|x64 159 | {08091723-A142-478B-A092-20741BA8FAE2}.DebugDLLStaticDeps|x64.Build.0 = DebugDLL|x64 160 | {08091723-A142-478B-A092-20741BA8FAE2}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLL|Win32 161 | {08091723-A142-478B-A092-20741BA8FAE2}.DebugDLLStaticDeps|x86.Build.0 = DebugDLL|Win32 162 | {08091723-A142-478B-A092-20741BA8FAE2}.Release|x64.ActiveCfg = Release|x64 163 | {08091723-A142-478B-A092-20741BA8FAE2}.Release|x64.Build.0 = Release|x64 164 | {08091723-A142-478B-A092-20741BA8FAE2}.Release|x86.ActiveCfg = Release|Win32 165 | {08091723-A142-478B-A092-20741BA8FAE2}.Release|x86.Build.0 = Release|Win32 166 | {08091723-A142-478B-A092-20741BA8FAE2}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 167 | {08091723-A142-478B-A092-20741BA8FAE2}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 168 | {08091723-A142-478B-A092-20741BA8FAE2}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32 169 | {08091723-A142-478B-A092-20741BA8FAE2}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32 170 | {08091723-A142-478B-A092-20741BA8FAE2}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLL|x64 171 | {08091723-A142-478B-A092-20741BA8FAE2}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLL|x64 172 | {08091723-A142-478B-A092-20741BA8FAE2}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLL|Win32 173 | {08091723-A142-478B-A092-20741BA8FAE2}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLL|Win32 174 | {08091723-A142-478B-A092-20741BA8FAE2}.ReleaseLTO|x64.ActiveCfg = ReleaseWinRT|x64 175 | {08091723-A142-478B-A092-20741BA8FAE2}.ReleaseLTO|x64.Build.0 = ReleaseWinRT|x64 176 | {08091723-A142-478B-A092-20741BA8FAE2}.ReleaseLTO|x86.ActiveCfg = ReleaseWinRT|Win32 177 | {08091723-A142-478B-A092-20741BA8FAE2}.ReleaseLTO|x86.Build.0 = ReleaseWinRT|Win32 178 | {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.Debug|x64.ActiveCfg = Debug|x64 179 | {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.Debug|x64.Build.0 = Debug|x64 180 | {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.Debug|x86.ActiveCfg = Debug|Win32 181 | {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.Debug|x86.Build.0 = Debug|Win32 182 | {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 183 | {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.DebugDLL|x64.Build.0 = DebugDLL|x64 184 | {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32 185 | {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.DebugDLL|x86.Build.0 = DebugDLL|Win32 186 | {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLLWinRT|x64 187 | {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.DebugDLLStaticDeps|x64.Build.0 = DebugDLLWinRT|x64 188 | {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLLWinRT|Win32 189 | {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.DebugDLLStaticDeps|x86.Build.0 = DebugDLLWinRT|Win32 190 | {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.Release|x64.ActiveCfg = Release|x64 191 | {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.Release|x64.Build.0 = Release|x64 192 | {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.Release|x86.ActiveCfg = Release|Win32 193 | {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.Release|x86.Build.0 = Release|Win32 194 | {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 195 | {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 196 | {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32 197 | {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32 198 | {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLLStaticDeps|x64 199 | {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLLStaticDeps|x64 200 | {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLLStaticDeps|Win32 201 | {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLLStaticDeps|Win32 202 | {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.ReleaseLTO|x64.ActiveCfg = ReleaseWinRT|x64 203 | {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.ReleaseLTO|x64.Build.0 = ReleaseWinRT|x64 204 | {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.ReleaseLTO|x86.ActiveCfg = ReleaseWinRT|Win32 205 | {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.ReleaseLTO|x86.Build.0 = ReleaseWinRT|Win32 206 | {19677DFD-C020-434D-9CB1-D0F105E72770}.Debug|x64.ActiveCfg = Debug|x64 207 | {19677DFD-C020-434D-9CB1-D0F105E72770}.Debug|x64.Build.0 = Debug|x64 208 | {19677DFD-C020-434D-9CB1-D0F105E72770}.Debug|x86.ActiveCfg = Debug|Win32 209 | {19677DFD-C020-434D-9CB1-D0F105E72770}.Debug|x86.Build.0 = Debug|Win32 210 | {19677DFD-C020-434D-9CB1-D0F105E72770}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 211 | {19677DFD-C020-434D-9CB1-D0F105E72770}.DebugDLL|x64.Build.0 = DebugDLL|x64 212 | {19677DFD-C020-434D-9CB1-D0F105E72770}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32 213 | {19677DFD-C020-434D-9CB1-D0F105E72770}.DebugDLL|x86.Build.0 = DebugDLL|Win32 214 | {19677DFD-C020-434D-9CB1-D0F105E72770}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLLWinRT|x64 215 | {19677DFD-C020-434D-9CB1-D0F105E72770}.DebugDLLStaticDeps|x64.Build.0 = DebugDLLWinRT|x64 216 | {19677DFD-C020-434D-9CB1-D0F105E72770}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLLWinRT|Win32 217 | {19677DFD-C020-434D-9CB1-D0F105E72770}.DebugDLLStaticDeps|x86.Build.0 = DebugDLLWinRT|Win32 218 | {19677DFD-C020-434D-9CB1-D0F105E72770}.Release|x64.ActiveCfg = Release|x64 219 | {19677DFD-C020-434D-9CB1-D0F105E72770}.Release|x64.Build.0 = Release|x64 220 | {19677DFD-C020-434D-9CB1-D0F105E72770}.Release|x86.ActiveCfg = Release|Win32 221 | {19677DFD-C020-434D-9CB1-D0F105E72770}.Release|x86.Build.0 = Release|Win32 222 | {19677DFD-C020-434D-9CB1-D0F105E72770}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 223 | {19677DFD-C020-434D-9CB1-D0F105E72770}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 224 | {19677DFD-C020-434D-9CB1-D0F105E72770}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32 225 | {19677DFD-C020-434D-9CB1-D0F105E72770}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32 226 | {19677DFD-C020-434D-9CB1-D0F105E72770}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLLStaticDeps|x64 227 | {19677DFD-C020-434D-9CB1-D0F105E72770}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLLStaticDeps|x64 228 | {19677DFD-C020-434D-9CB1-D0F105E72770}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLLStaticDeps|Win32 229 | {19677DFD-C020-434D-9CB1-D0F105E72770}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLLStaticDeps|Win32 230 | {19677DFD-C020-434D-9CB1-D0F105E72770}.ReleaseLTO|x64.ActiveCfg = ReleaseWinRT|x64 231 | {19677DFD-C020-434D-9CB1-D0F105E72770}.ReleaseLTO|x64.Build.0 = ReleaseWinRT|x64 232 | {19677DFD-C020-434D-9CB1-D0F105E72770}.ReleaseLTO|x86.ActiveCfg = ReleaseWinRT|Win32 233 | {19677DFD-C020-434D-9CB1-D0F105E72770}.ReleaseLTO|x86.Build.0 = ReleaseWinRT|Win32 234 | {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Debug|x64.ActiveCfg = Debug|x64 235 | {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Debug|x64.Build.0 = Debug|x64 236 | {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Debug|x86.ActiveCfg = Debug|Win32 237 | {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Debug|x86.Build.0 = Debug|Win32 238 | {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 239 | {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLL|x64.Build.0 = DebugDLL|x64 240 | {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32 241 | {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLL|x86.Build.0 = DebugDLL|Win32 242 | {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLL|x64 243 | {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLLStaticDeps|x64.Build.0 = DebugDLL|x64 244 | {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLL|Win32 245 | {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLLStaticDeps|x86.Build.0 = DebugDLL|Win32 246 | {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Release|x64.ActiveCfg = Release|x64 247 | {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Release|x64.Build.0 = Release|x64 248 | {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Release|x86.ActiveCfg = Release|Win32 249 | {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Release|x86.Build.0 = Release|Win32 250 | {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 251 | {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 252 | {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32 253 | {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32 254 | {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLL|x64 255 | {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLL|x64 256 | {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLL|Win32 257 | {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLL|Win32 258 | {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseLTO|x64.ActiveCfg = ReleaseWinRT|x64 259 | {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseLTO|x64.Build.0 = ReleaseWinRT|x64 260 | {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseLTO|x86.ActiveCfg = ReleaseWinRT|Win32 261 | {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseLTO|x86.Build.0 = ReleaseWinRT|Win32 262 | {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.Debug|x64.ActiveCfg = Debug|x64 263 | {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.Debug|x64.Build.0 = Debug|x64 264 | {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.Debug|x86.ActiveCfg = Debug|Win32 265 | {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.Debug|x86.Build.0 = Debug|Win32 266 | {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 267 | {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.DebugDLL|x64.Build.0 = DebugDLL|x64 268 | {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32 269 | {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.DebugDLL|x86.Build.0 = DebugDLL|Win32 270 | {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLL|x64 271 | {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.DebugDLLStaticDeps|x64.Build.0 = DebugDLL|x64 272 | {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLL|Win32 273 | {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.DebugDLLStaticDeps|x86.Build.0 = DebugDLL|Win32 274 | {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.Release|x64.ActiveCfg = Release|x64 275 | {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.Release|x64.Build.0 = Release|x64 276 | {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.Release|x86.ActiveCfg = Release|Win32 277 | {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.Release|x86.Build.0 = Release|Win32 278 | {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 279 | {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 280 | {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32 281 | {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32 282 | {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLL|x64 283 | {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLL|x64 284 | {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLL|Win32 285 | {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLL|Win32 286 | {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.ReleaseLTO|x64.ActiveCfg = ReleaseWinRT|x64 287 | {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.ReleaseLTO|x64.Build.0 = ReleaseWinRT|x64 288 | {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.ReleaseLTO|x86.ActiveCfg = ReleaseWinRT|Win32 289 | {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.ReleaseLTO|x86.Build.0 = ReleaseWinRT|Win32 290 | {CFE70273-7A79-4815-AF95-1E02E2675E37}.Debug|x64.ActiveCfg = Debug|x64 291 | {CFE70273-7A79-4815-AF95-1E02E2675E37}.Debug|x64.Build.0 = Debug|x64 292 | {CFE70273-7A79-4815-AF95-1E02E2675E37}.Debug|x86.ActiveCfg = Debug|Win32 293 | {CFE70273-7A79-4815-AF95-1E02E2675E37}.Debug|x86.Build.0 = Debug|Win32 294 | {CFE70273-7A79-4815-AF95-1E02E2675E37}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 295 | {CFE70273-7A79-4815-AF95-1E02E2675E37}.DebugDLL|x64.Build.0 = DebugDLL|x64 296 | {CFE70273-7A79-4815-AF95-1E02E2675E37}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32 297 | {CFE70273-7A79-4815-AF95-1E02E2675E37}.DebugDLL|x86.Build.0 = DebugDLL|Win32 298 | {CFE70273-7A79-4815-AF95-1E02E2675E37}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLLWinRT|x64 299 | {CFE70273-7A79-4815-AF95-1E02E2675E37}.DebugDLLStaticDeps|x64.Build.0 = DebugDLLWinRT|x64 300 | {CFE70273-7A79-4815-AF95-1E02E2675E37}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLLWinRT|Win32 301 | {CFE70273-7A79-4815-AF95-1E02E2675E37}.DebugDLLStaticDeps|x86.Build.0 = DebugDLLWinRT|Win32 302 | {CFE70273-7A79-4815-AF95-1E02E2675E37}.Release|x64.ActiveCfg = Release|x64 303 | {CFE70273-7A79-4815-AF95-1E02E2675E37}.Release|x64.Build.0 = Release|x64 304 | {CFE70273-7A79-4815-AF95-1E02E2675E37}.Release|x86.ActiveCfg = Release|Win32 305 | {CFE70273-7A79-4815-AF95-1E02E2675E37}.Release|x86.Build.0 = Release|Win32 306 | {CFE70273-7A79-4815-AF95-1E02E2675E37}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 307 | {CFE70273-7A79-4815-AF95-1E02E2675E37}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 308 | {CFE70273-7A79-4815-AF95-1E02E2675E37}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32 309 | {CFE70273-7A79-4815-AF95-1E02E2675E37}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32 310 | {CFE70273-7A79-4815-AF95-1E02E2675E37}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLLStaticDeps|x64 311 | {CFE70273-7A79-4815-AF95-1E02E2675E37}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLLStaticDeps|x64 312 | {CFE70273-7A79-4815-AF95-1E02E2675E37}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLLStaticDeps|Win32 313 | {CFE70273-7A79-4815-AF95-1E02E2675E37}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLLStaticDeps|Win32 314 | {CFE70273-7A79-4815-AF95-1E02E2675E37}.ReleaseLTO|x64.ActiveCfg = ReleaseWinRT|x64 315 | {CFE70273-7A79-4815-AF95-1E02E2675E37}.ReleaseLTO|x64.Build.0 = ReleaseWinRT|x64 316 | {CFE70273-7A79-4815-AF95-1E02E2675E37}.ReleaseLTO|x86.ActiveCfg = ReleaseWinRT|Win32 317 | {CFE70273-7A79-4815-AF95-1E02E2675E37}.ReleaseLTO|x86.Build.0 = ReleaseWinRT|Win32 318 | {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Debug|x64.ActiveCfg = Debug|x64 319 | {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Debug|x64.Build.0 = Debug|x64 320 | {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Debug|x86.ActiveCfg = Debug|Win32 321 | {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Debug|x86.Build.0 = Debug|Win32 322 | {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 323 | {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLL|x64.Build.0 = DebugDLL|x64 324 | {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32 325 | {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLL|x86.Build.0 = DebugDLL|Win32 326 | {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLL|x64 327 | {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLLStaticDeps|x64.Build.0 = DebugDLL|x64 328 | {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLL|Win32 329 | {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLLStaticDeps|x86.Build.0 = DebugDLL|Win32 330 | {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Release|x64.ActiveCfg = Release|x64 331 | {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Release|x64.Build.0 = Release|x64 332 | {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Release|x86.ActiveCfg = Release|Win32 333 | {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Release|x86.Build.0 = Release|Win32 334 | {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 335 | {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 336 | {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32 337 | {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32 338 | {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLL|x64 339 | {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLL|x64 340 | {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLL|Win32 341 | {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLL|Win32 342 | {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseLTO|x64.ActiveCfg = ReleaseWinRT|x64 343 | {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseLTO|x64.Build.0 = ReleaseWinRT|x64 344 | {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseLTO|x86.ActiveCfg = ReleaseWinRT|Win32 345 | {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseLTO|x86.Build.0 = ReleaseWinRT|Win32 346 | EndGlobalSection 347 | GlobalSection(SolutionProperties) = preSolution 348 | HideSolutionNode = FALSE 349 | EndGlobalSection 350 | GlobalSection(ExtensibilityGlobals) = postSolution 351 | SolutionGuid = {77479689-0075-4EB6-8C55-A03013A8AFFF} 352 | EndGlobalSection 353 | EndGlobal 354 | -------------------------------------------------------------------------------- /assrender.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {A8A845C1-48C9-4D03-8D1D-6A6C023EE319} 23 | Win32Proj 24 | assrender 25 | 10.0 26 | 27 | 28 | 29 | DynamicLibrary 30 | true 31 | v142 32 | Unicode 33 | 34 | 35 | DynamicLibrary 36 | false 37 | v142 38 | true 39 | Unicode 40 | 41 | 42 | DynamicLibrary 43 | true 44 | v142 45 | Unicode 46 | 47 | 48 | DynamicLibrary 49 | false 50 | v142 51 | true 52 | Unicode 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | true 74 | $(SolutionDir)bin\$(Configuration)_$(Platform)\ 75 | $(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\ 76 | $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(SolutionDir)lib\x86-32 77 | 78 | 79 | true 80 | $(SolutionDir)bin\$(Configuration)_$(Platform)\ 81 | $(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\ 82 | $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(SolutionDir)lib\x86-64 83 | 84 | 85 | false 86 | $(SolutionDir)bin\$(Configuration)_$(Platform)\ 87 | $(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\ 88 | $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(SolutionDir)lib\x86-32 89 | 90 | 91 | false 92 | $(SolutionDir)bin\$(Configuration)_$(Platform)\ 93 | $(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\ 94 | $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(SolutionDir)lib\x86-64 95 | 96 | 97 | 98 | 99 | 100 | Level3 101 | Disabled 102 | WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;ASSRENDER_EXPORTS;%(PreprocessorDefinitions) 103 | $(SolutionDir)msvc\include\;$(SolutionDir)src\include\%(AdditionalIncludeDirectories) 104 | 105 | 106 | Windows 107 | true 108 | $(SolutionDir)msvc\lib\$(PlatformTarget)\ 109 | libassd.lib;AviSynth.lib;%(AdditionalDependencies) 110 | $(ProjectDir)src\assrender.def 111 | 112 | 113 | 114 | 115 | 116 | 117 | Level3 118 | Disabled 119 | _DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;ASSRENDER_EXPORTS;%(PreprocessorDefinitions) 120 | $(SolutionDir)msvc\include\;$(SolutionDir)src\include\%(AdditionalIncludeDirectories) 121 | 122 | 123 | Windows 124 | true 125 | $(SolutionDir)msvc\lib\$(PlatformTarget)\ 126 | libassd.lib;AviSynth.lib;%(AdditionalDependencies) 127 | 128 | 129 | 130 | 131 | Level3 132 | 133 | 134 | MaxSpeed 135 | true 136 | true 137 | WIN32;NDEBUG;_WINDOWS;_USRDL;_CRT_SECURE_NO_WARNINGSL;ASSRENDER_EXPORTS;%(PreprocessorDefinitions) 138 | $(SolutionDir)msvc\include\;$(SolutionDir)src\include\%(AdditionalIncludeDirectories) 139 | 140 | 141 | Windows 142 | true 143 | true 144 | true 145 | $(SolutionDir)msvc\lib\$(PlatformTarget)\ 146 | libass.lib;AviSynth.lib;%(AdditionalDependencies) 147 | $(ProjectDir)src\assrender.def 148 | 149 | 150 | 151 | 152 | Level3 153 | 154 | 155 | MaxSpeed 156 | true 157 | true 158 | NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;ASSRENDER_EXPORTS;%(PreprocessorDefinitions) 159 | $(SolutionDir)msvc\include\;$(SolutionDir)src\include\%(AdditionalIncludeDirectories) 160 | 161 | 162 | Windows 163 | true 164 | true 165 | true 166 | $(SolutionDir)msvc\lib\$(PlatformTarget)\ 167 | libass.lib;AviSynth.lib;%(AdditionalDependencies) 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | -------------------------------------------------------------------------------- /assrender.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 | {00a049c9-4f7f-4366-8b58-2449e50a609d} 18 | 19 | 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | Header Files 32 | 33 | 34 | 35 | 36 | Source Files 37 | 38 | 39 | Source Files 40 | 41 | 42 | Source Files 43 | 44 | 45 | Source Files 46 | 47 | 48 | 49 | 50 | Resource Files 51 | 52 | 53 | 54 | 55 | Include 56 | 57 | 58 | -------------------------------------------------------------------------------- /assrender_with_latest_sdk.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | SET PROJECT=assrender 4 | 5 | @REM Detect the newest available Windows SDK 6 | CALL :GetWindowsSdkVer 7 | 8 | @REM Open the project 9 | %PROJECT%.sln 10 | 11 | EXIT /B 0 12 | 13 | :GetWindowsSdkVer 14 | SET WindowsTargetPlatformVersion= 15 | 16 | IF "%WindowsTargetPlatformVersion%"=="" CALL :GetWin10SdkVer 17 | IF "%WindowsTargetPlatformVersion%"=="" CALL :GetWin81SdkVer 18 | EXIT /B 0 19 | 20 | :GetWin10SdkVer 21 | CALL :GetWin10SdkVerHelper HKLM\SOFTWARE\Wow6432Node > nul 2>&1 22 | IF errorlevel 1 CALL :GetWin10SdkVerHelper HKCU\SOFTWARE\Wow6432Node > nul 2>&1 23 | IF errorlevel 1 CALL :GetWin10SdkVerHelper HKLM\SOFTWARE > nul 2>&1 24 | IF errorlevel 1 CALL :GetWin10SdkVerHelper HKCU\SOFTWARE > nul 2>&1 25 | IF errorlevel 1 EXIT /B 1 26 | EXIT /B 0 27 | 28 | :GetWin10SdkVerHelper 29 | @REM Get Windows 10 SDK installed folder 30 | FOR /F "tokens=1,2*" %%i IN ('reg query "%1\Microsoft\Microsoft SDKs\Windows\v10.0" /v "InstallationFolder"') DO ( 31 | IF "%%i"=="InstallationFolder" ( 32 | SET WindowsSdkDir=%%~k 33 | ) 34 | ) 35 | 36 | @REM get windows 10 sdk version number 37 | SETLOCAL enableDelayedExpansion 38 | IF NOT "%WindowsSdkDir%"=="" FOR /f %%i IN ('dir "%WindowsSdkDir%include\" /b /ad-h /on') DO ( 39 | @REM Skip if Windows.h is not found in %%i\um. This would indicate that only the UCRT MSIs were 40 | @REM installed for this Windows SDK version. 41 | IF EXIST "%WindowsSdkDir%include\%%i\um\Windows.h" ( 42 | SET result=%%i 43 | IF "!result:~0,3!"=="10." ( 44 | SET SDK=!result! 45 | IF "!result!"=="%VSCMD_ARG_WINSDK%" SET findSDK=1 46 | ) 47 | ) 48 | ) 49 | 50 | IF "%findSDK%"=="1" SET SDK=%VSCMD_ARG_WINSDK% 51 | ENDLOCAL & SET WindowsTargetPlatformVersion=%SDK% 52 | IF "%WindowsTargetPlatformVersion%"=="" ( 53 | EXIT /B 1 54 | ) 55 | EXIT /B 0 56 | 57 | :GetWin81SdkVer 58 | SET WindowsTargetPlatformVersion=8.1 59 | EXIT /B 0 60 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /docs/BUILD.md: -------------------------------------------------------------------------------- 1 | ## Build instructions 2 | 3 | ### Windows Visual Studio 2019 4 | 5 | * Prequisite: vsnasm integration 6 | - get VSNASM from https://github.com/ShiftMediaProject/VSNASM 7 | - run install_script.bat 8 | 9 | * Clone repo 10 | 11 | Clone https://github.com/pinterf/assrender from VS IDE or 12 | 13 | git clone https://github.com/pinterf/assrender 14 | git submodule update --init --recursive --remote 15 | 16 | * Prequisite: avisynth.lib versions (x86 and x64) 17 | - When you have installed Avisynth through an installer and have installed FilterSDK 18 | get it from c:\Program Files (x86)\AviSynth+\FilterSDK\lib\x86 and x64 19 | - Or get it from the 'filesonly' builds at Avisynth+ releases 20 | https://github.com/AviSynth/AviSynthPlus/releases 21 | 22 | Copy lib files to assrender\lib\x86-64\ and assrender\lib\x86-32\ 23 | 32 and 64 bit versions respectively 24 | 25 | * Build: 26 | Open solution file from IDE 27 | 28 | ### Windows GCC (mingw installed by msys2) 29 | 30 | * Clone repo 31 | 32 | git clone https://github.com/pinterf/assrender 33 | 34 | This environment is not using the git submodules, we need libass as a package. 35 | There is no need for submodule update. 36 | 37 | * Prequisite: avisynth.lib versions (x86 and x64) 38 | - When you have installed Avisynth through an installer and have installed FilterSDK 39 | get it from c:\Program Files (x86)\AviSynth+\FilterSDK\lib\x86 and x64 40 | - Or get it from the 'filesonly' builds at [Avisynth+ releases](https://github.com/AviSynth/AviSynthPlus/releases) 41 | 42 | Copy lib files to assrender\lib\x86-64\ and assrender\lib\x86-32\ 43 | 32 and 64 bit versions respectively 44 | 45 | * Prequisite: libass package 46 | 47 | - List libass versions 48 | 49 | $ pacman -Ss libass 50 | 51 | Output: 52 | 53 | mingw32/mingw-w64-i686-libass 0.16.0-1 54 | A portable library for SSA/ASS subtitles rendering (mingw-w64) 55 | mingw64/mingw-w64-x86_64-libass 0.16.0-1 56 | A portable library for SSA/ASS subtitles rendering (mingw-w64) 57 | 58 | - Get package 59 | 60 | Example for x64 version: 61 | 62 | $ pacman -S mingw64/mingw-w64-x86_64-libass 63 | 64 | Output: 65 | 66 | resolving dependencies... 67 | looking for conflicting packages... 68 | warning: dependency cycle detected: 69 | warning: mingw-w64-x86_64-harfbuzz will be installed before its mingw-w64-x86_64-freetype dependency 70 | 71 | Packages (10) mingw-w64-x86_64-fontconfig-2.13.93-1 72 | mingw-w64-x86_64-freetype-2.10.4-1 73 | mingw-w64-x86_64-fribidi-1.0.10-2 74 | mingw-w64-x86_64-glib2-2.66.4-1 75 | mingw-w64-x86_64-graphite2-1.3.14-2 76 | mingw-w64-x86_64-harfbuzz-2.7.4-1 77 | mingw-w64-x86_64-libpng-1.6.37-3 mingw-w64-x86_64-pcre-8.44-2 78 | mingw-w64-x86_64-wineditline-2.205-3 79 | mingw-w64-x86_64-libass-0.15.0-1 80 | 81 | Total Download Size: 6.92 MiB 82 | Total Installed Size: 42.31 MiB 83 | 84 | :: Proceed with installation? [Y/n] 85 | 86 | Choose Y and wait 87 | 88 | * Build 89 | under project root: 90 | 91 | rm -r build 92 | cmake -G "MinGW Makefiles" -B build -S . 93 | cmake --build build --config Release --clean-first 94 | 95 | ### Linux 96 | * Clone repo 97 | 98 | git clone https://github.com/pinterf/assrender 99 | cd assrender 100 | cmake -B build -S . 101 | cmake --build build --clean-first 102 | 103 | Remark: submodules are not needed, libass is used as a package. 104 | 105 | * Find binaries at 106 | 107 | build/assrender/libassrender.so 108 | 109 | * Install binaries 110 | 111 | cd build 112 | sudo make install 113 | -------------------------------------------------------------------------------- /docs/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## Change log 2 | 3 | ### 0.35 (20210304) 4 | * Windows MSVC: Update to libass v0.15 5 | (git submodule update --init --recursive --remote) 6 | For changes since v0.14 see https://github.com/libass/libass/blob/master/Changelog 7 | * don't guess base on video resolution (realfinder) 8 | if .ass file has no Matrix info then it should be treated as it "Rec601" to maintain compatibility 9 | * Parameter 'colorspace' default value is no longer "guess" 10 | * Add more color options: PC.709, PC.601, TV.fcc, PC.fcc, TV.240m, PC.240m, none. 11 | "none" and "guess" implies "guess-by-resolution". 12 | * Fix: possible crash on initializing phase (buffer overread, linux crashed, Windows was just lucky) 13 | 14 | ### 0.34 (20210301) 15 | * Fix the fix: revert matrix change made in 0.33 16 | * Fix: Check matrix from .ASS file "YCbCr Matrix:" section besides "Video Colorspace:" 17 | Recognized values are "tv.601" and "tv.709" 18 | 19 | ### 0.33 (20210228) 20 | * Fix: wrong Bt.709 matrix (it wasn't :) ) 21 | 22 | ### 0.32 (20210227) 23 | * Fix: treat I420 variant as YV12 instead of unsupported color space 24 | 25 | ### 0.31 (20210218) 26 | * Fix colors for planar RGB 27 | * code: hidden ifdef FOR_AVISYNTH_26_ONLY for Avisynth 2.6-only build 28 | 29 | ### 0.30 (20210217) 30 | * From now assrender does not works with classic Aviysnth: high-bitdepth helper function calls 31 | * 10-16 bit support (including RGB48 and RGB64) 32 | * YV411, Planar RGB support 33 | 34 | ### 0.29 (20210216 - pinterf) 35 | * project moved to https://github.com/pinterf/assrender from https://github.com/vadosnaprimer/assrender 36 | * Move to Visual Studio 2019 - v142 platform toolset 37 | * Add .def module definition file for Avisynth 2.6 std compatibility (function name mangling) 38 | * Update Avisynth C headers 39 | * Check Linux and gcc-MinGW CMake build 40 | * Add build instructions and change log to README 41 | 42 | ### no version (20190114 - vadosnaprimer) 43 | * https://github.com/vadosnaprimer/assrender/ 44 | * add batch that lets not to change deps sdk and vs version copied from SMP libass 45 | * update SMP submodules 46 | 47 | ### no version (20161018 - Blitzker) 48 | * https://github.com/Blitzker/assrender 49 | * Visual Studio 2015 support 50 | 51 | ### 0.28 (20120226 - pingplug) 52 | * small changes and update version to 0.28 53 | 54 | ### 0.27 (20150202 - pingplug) 55 | * https://github.com/pingplug/assrender 56 | * add a simple .rc file :-) 57 | * cache the last img to rend faster if img not changed 58 | * add YUY2 and YV16 support 59 | 60 | ### 0.25 (20120420 - lachs0r) 61 | * moved to github 62 | * code restructured 63 | * added support for the BT.709 color space and the 'Video Colorspace' property that has been introduced with recent versions of Aegisub. 64 | * binary: 65 | - updated everything, switched to MinGW-w64 (same toolchain as mplayer2 now) 66 | 67 | ### 0.24.1 (20110922 - lachs0r) 68 | * binary changes only 69 | * binary: 70 | - updated libass to current git HEAD 71 | - switched Harfbuzz to libass’ compatibility branch 72 | - compiled Harfbuzz without Uniscribe backend 73 | * fixes lots of crashes and misbehavior 74 | 75 | ### 0.24 (20110729) 76 | * fixing the performance regression 77 | 78 | ### 0.23 (20110728) 79 | * disabled font hinting by default 80 | * binary: 81 | - updated libass to current git HEAD and included Harfbuzz: 82 | - added support for bidirectional text, Arabic shaping etc. 83 | - added proper support for @fonts (vertical writing) 84 | - slight performance regression (glyph cache not hooked up with Harfbuzz yet) 85 | - updated FreeType to current git HEAD: 86 | - fixed outline stroker for some broken fonts 87 | 88 | ### 0.22 (20110618 - lachs0r) 89 | * fixed that annoying hang on vector clips 90 | 91 | ### 0.21 (20110608 - lachs0r) 92 | * fixed YV12 subsampling so it no longer looks horrible, which should be rather good news for most users. 93 | * temporarily removed YV16 support 94 | * renamed parameter verbosity → debuglevel 95 | * code cleanups 96 | * binary: 97 | - reverted to GCC 4.5.2 (4.6 miscompiles MinGW) 98 | 99 | ### 0.20 (20110601) 100 | * fixed RGB32 support (it’s actually usable with BlankClip(pixel_type="RGB32") now). 101 | * fixed the masksub stuff 102 | * properly output debug messages to stderr instead of stdout 103 | * reformatted source and corrected/removed some comments 104 | * modified CMakeLists.txt to strip the binary by default 105 | * binary: 106 | - now built with GCC 4.6 instead of 4.5.2 107 | - included enca again 108 | - patched fontconfig: 109 | - prettier debug output 110 | - use the correct location for its cache 111 | 112 | ### 0.19 (2011-02-01 - lachs0r) 113 | This is a bugfix/cleanup release. 114 | * fixed possible buffer overflows in timecodesv1 and SRT parsing 115 | * fixed random crashes on unloading 116 | * probably fixed compilation with MSVC (patch by TheFluff) 117 | * very slightly improved performance with GCC 118 | * various code cleanups 119 | 120 | ### 0.16 (2011-01-25 - lachs0r) 121 | * improved YV12 support (should be somewhat usable now) 122 | * added support for RGB24, YV24, YV16 and Y8 (YUY2 coming soon) 123 | * added SRT subtitle format support, additional parameter: srt_font (font to use for srt subs) 124 | * exposed some libass parameters: 125 | - line_spacing (line spacing) 126 | - dar, sar (aspect ratio) 127 | - top, bottom, left, right (margins) 128 | - fontdir (additional font directory) 129 | * masksub equivalent if used on a blankclip 130 | (still buggy - read source for details) 131 | * no more global variables 132 | 133 | ### 0.16 (2011-01-17 - lachs0r) 134 | * added rudimentary YV12 support (chroma subsampling still needs work) 135 | * binary: Previously, I linked against a very old avisynth_c.lib 136 | now you shouldn’t get any error messages about "avisynth_c.dll" 137 | * tidied up the RGB32 blitter a bit 138 | 139 | ### 0.16 (2011-01-16) 140 | * implemented VFRaC support via timecodes files (v1 and v2 supported) 141 | 142 | ### 0.15 (2011-01-16 - lachs0r) 143 | * reimplemented as AviSynth C plugin - this fixed several crashes and 144 | got rid of the major pain in the ass that is MSVC 145 | * binary: built with patched Fontconfig (no longer needs fonts.conf) 146 | 147 | ### 0.11 TheFluff 148 | * Source code (under MIT license, binaries are under GPL for obvious reasons): assrender_0.11-src.7z 149 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # AssRender 2 | 3 | AssRender is an AviSynth plugin that renders ASS/SSA and SRT (without the HTML-like markup) subtitles. It uses libass to render the subtitles, which makes it the fastest and most correct ASS renderer for AviSynth. 4 | 5 | This also means that it is much more picky about script syntax than VSFilter and friends, so keep that in mind before blaming the filter. Yes, people have reported a lot of errors that were actually the script author’s fault. 6 | 7 | ## Usage 8 | 9 | assrender(clip, string file, [string vfr, int hinting, float scale, float line_spacing, float dar, float sar, int top, int bottom, int left, int right, string charset, int debuglevel, string fontdir, string srt_font, string colorspace]) 10 | 11 | `string file` 12 | 13 | Your subtitle file. May be ASS, SSA or SRT. 14 | 15 | `string vfr` 16 | 17 | Specify timecodes v1 or v2 file when working with VFRaC. 18 | 19 | `int hinting` 20 | 21 | Font hinting mode. Choose between none (0, default), light (1), normal (2) and Freetype native (3) autohinting. 22 | 23 | `float scale` 24 | 25 | Font scale. Defaults to 1.0. 26 | 27 | `float line_spacing` 28 | 29 | Line spacing in pixels. Defaults to 1.0 and won’t be scaled with frame size. 30 | 31 | `float dar`, `float sar` 32 | 33 | Aspect ratio. Of course you need to set both parameters. 34 | 35 | `int top`, `int bottom`, `int left`, `int right` 36 | 37 | Margins. They will be added to the frame size and may be negative. 38 | 39 | `string charset` 40 | 41 | Character set to use, in GNU iconv or enca format. Defaults to UTF-8. 42 | Example enca format: `enca:pl:cp1250` 43 | (guess the encoding for Polish, fall back on `cp1250`) 44 | 45 | `int debuglevel` 46 | 47 | How much crap assrender is supposed to spam to stderr. 48 | 49 | `string fontdir` 50 | 51 | Additional font directory. 52 | Useful if you are lazy but want to keep your system fonts clean. 53 | Default value: C:/Windows/Fonts or /usr/share/fonts (Windows and linux respectively) 54 | 55 | `string srt_font` 56 | 57 | Font to use for SRT subtitles. 58 | Defaults to whatever Fontconfig chooses for “sans-serif”. 59 | 60 | `string colorspace` 61 | 62 | The color space of your (YUV) video. Possible values: 63 | - Rec2020, BT.2020 64 | - Rec709, BT.709 65 | - Rec601, BT.601 66 | - PC.709 67 | - PC.601 68 | - TV.fcc, PC.fcc 69 | - TV.240m, PC.240m 70 | - none, guess 71 | 72 | Default is to use the ASS script's "YCbCr Matrix" or "Video Colorspace" property. 73 | 74 | Recognized .ASS properties: "TV.601" "TV.709", "PC.601" "PC.709" "TV.240m" "PC.240m" "TV.fcc" "PC.fcc" and "none". 75 | 76 | "none" and "guess" decides upon on video resolution: width > 1280 or height > 576 → BT.709, else → BT.601. 77 | When no hint found in ASS script and 'colorspace' parameter is empty then the default is BT.601. 78 | 79 | ## Build instructions 80 | See: [BUILD.md](BUILD.md) 81 | 82 | ## Change log 83 | See: [CHANGELOG.md](CHANGELOG.md) 84 | 85 | ## Licenses 86 | For all modules: see msvc/licenses 87 | 88 | ## Links 89 | * Doom9 forum: https://forum.doom9.org/showthread.php?t=148926 90 | * Avisynth wiki: http://avisynth.nl/index.php/AssRender 91 | * libass original: https://github.com/libass/libass 92 | * libass submodule used for msvc https://github.com/ShiftMediaProject/libass 93 | * Aegisub: https://github.com/Aegisub/Aegisub 94 | -------------------------------------------------------------------------------- /lib/x86-32/readme.txt: -------------------------------------------------------------------------------- 1 | placeholder for 32 bit avisynth.lib from Avisynth C API SDK files -------------------------------------------------------------------------------- /lib/x86-64/readme.txt: -------------------------------------------------------------------------------- 1 | placeholder for 64 bit avisynth.lib from Avisynth C API SDK files -------------------------------------------------------------------------------- /src/ASSRender.rc: -------------------------------------------------------------------------------- 1 | #include 2 | #pragma code_page(65001) 3 | VS_VERSION_INFO VERSIONINFO 4 | FILEVERSION 0, 35, 0, 0 5 | PRODUCTVERSION 0, 35, 0, 0 6 | FILEFLAGSMASK VS_FFI_FILEFLAGSMASK 7 | FILEFLAGS 0 8 | FILEOS VOS_NT_WINDOWS32 9 | #ifdef OPENOBEX_EXPORTS 10 | FILETYPE VFT_DLL 11 | #else 12 | FILETYPE VFT_STATIC_LIB 13 | #endif 14 | FILESUBTYPE VFT2_UNKNOWN 15 | BEGIN 16 | BLOCK "StringFileInfo" 17 | BEGIN 18 | BLOCK "040904B0" 19 | BEGIN 20 | VALUE "CompanyName", "" 21 | VALUE "FileDescription", "a plugin for AviSynth to rend ASS/SSA subtitles using libass" 22 | VALUE "FileVersion", "0.35.0.0" 23 | VALUE "InternalName", "ASSRENDER.DLL" 24 | VALUE "LegalCopyright", "" 25 | VALUE "OriginalFilename", "LIBASSRENDER.DLL" 26 | VALUE "ProductName", "ASSRender plugin for AVISynth" 27 | VALUE "ProductVersion", "0.35.0.0" 28 | END 29 | END 30 | BLOCK "VarFileInfo" 31 | BEGIN 32 | VALUE "Translation", 0x0409, 0x04B0 /* U.S. English (Unicode) */ 33 | END 34 | END 35 | 36 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(PluginName "assrender") 2 | 3 | if (NOT WIN32) 4 | string(TOLOWER "${PluginName}" PluginName) 5 | endif() 6 | 7 | set(ProjectName "${PluginName}") 8 | project(${ProjectName} LANGUAGES C) 9 | 10 | SET(ASSRender_SRC 11 | assrender.c 12 | assrender.h 13 | render.c 14 | render.h 15 | sub.c 16 | sub.h 17 | timecodes.c 18 | timecodes.h 19 | ) 20 | 21 | IF( WIN32 ) 22 | LIST(APPEND ASSRender_SRC "ASSRender.rc") 23 | if(NOT MINGW AND CMAKE_SIZEOF_VOID_P EQUAL 4) 24 | # 32 bit VS only: decoration remove for old Avisynth 2.6 25 | LIST(APPEND ASSRender_SRC "assrender.def") 26 | ENDIF() 27 | ENDIF() 28 | 29 | add_library(${PluginName} SHARED ${ASSRender_SRC}) 30 | 31 | set_target_properties(${PluginName} PROPERTIES "OUTPUT_NAME" "${PluginName}") 32 | if (MINGW) 33 | set_target_properties(${PluginName} PROPERTIES PREFIX "") 34 | set_target_properties(${PluginName} PROPERTIES IMPORT_PREFIX "") 35 | endif() 36 | 37 | IF (NOT WIN32 OR MINGW) 38 | FIND_PACKAGE(PkgConfig REQUIRED) 39 | IF (NOT MINGW) 40 | PKG_CHECK_MODULES(AVISYNTH REQUIRED avisynth>=3.5.0) 41 | ENDIF() 42 | PKG_CHECK_MODULES(LIBASS REQUIRED libass>=0.12.0) 43 | target_include_directories(${PluginName} PRIVATE ${AVISYNTH_INCLUDE_DIR} ${LIBASS_INCLUDE_DIR}) 44 | ENDIF() 45 | 46 | #dedicated include dir for avisynth.h 47 | target_include_directories(${ProjectName} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) 48 | 49 | if (WIN32) 50 | # avisynth.lib for C API 51 | if(CMAKE_SIZEOF_VOID_P EQUAL 8) 52 | set(AVS_LIBDIR ${CMAKE_CURRENT_SOURCE_DIR}/../lib/x86-64) 53 | else() 54 | set(AVS_LIBDIR ${CMAKE_CURRENT_SOURCE_DIR}/../lib/x86-32) 55 | endif() 56 | if (MINGW) 57 | TARGET_LINK_LIBRARIES(${ProjectName} ${LIBASS_LDFLAGS} ${AVS_LIBDIR}/avisynth.lib) 58 | else() 59 | # msvc: IDE based, with subprojects 60 | TARGET_LINK_LIBRARIES(${ProjectName} ${AVS_LIBDIR}/avisynth.lib) 61 | endif() 62 | else() 63 | TARGET_LINK_LIBRARIES(${ProjectName} ${AVISYNTH_LDFLAGS} ${LIBASS_LDFLAGS} ) 64 | endif() 65 | 66 | include(GNUInstallDirs) 67 | 68 | INSTALL(TARGETS ${ProjectName} 69 | LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}/avisynth") 70 | -------------------------------------------------------------------------------- /src/assrender.c: -------------------------------------------------------------------------------- 1 | #include "assrender.h" 2 | #include "render.h" 3 | #include "sub.h" 4 | #include "timecodes.h" 5 | 6 | void AVSC_CC assrender_destroy(void* ud, AVS_ScriptEnvironment* env) 7 | { 8 | ass_renderer_done(((udata*)ud)->ass_renderer); 9 | ass_library_done(((udata*)ud)->ass_library); 10 | ass_free_track(((udata*)ud)->ass); 11 | 12 | free(((udata*)ud)->sub_img[0]); 13 | free(((udata*)ud)->sub_img[1]); 14 | free(((udata*)ud)->sub_img[2]); 15 | free(((udata*)ud)->sub_img[3]); 16 | 17 | if (((udata*)ud)->isvfr) 18 | free(((udata*)ud)->timestamp); 19 | 20 | free(ud); 21 | } 22 | 23 | AVS_Value AVSC_CC assrender_create(AVS_ScriptEnvironment* env, AVS_Value args, 24 | void* ud) 25 | { 26 | AVS_Value v; 27 | AVS_FilterInfo* fi; 28 | AVS_Clip* c = avs_new_c_filter(env, &fi, avs_array_elt(args, 0), 1); 29 | char e[250]; 30 | 31 | const char* f = avs_as_string(avs_array_elt(args, 1)); 32 | const char* vfr = avs_as_string(avs_array_elt(args, 2)); 33 | int h = avs_is_int(avs_array_elt(args, 3)) ? 34 | avs_as_int(avs_array_elt(args, 3)) : 0; 35 | double scale = avs_is_float(avs_array_elt(args, 4)) ? 36 | avs_as_float(avs_array_elt(args, 4)) : 1.0; 37 | double line_spacing = avs_is_float(avs_array_elt(args, 5)) ? 38 | avs_as_float(avs_array_elt(args, 5)) : 0; 39 | double dar = avs_is_float(avs_array_elt(args, 6)) ? 40 | avs_as_float(avs_array_elt(args, 6)) : 0; 41 | double sar = avs_is_float(avs_array_elt(args, 7)) ? 42 | avs_as_float(avs_array_elt(args, 7)) : 0; 43 | int top = avs_is_int(avs_array_elt(args, 8)) ? 44 | avs_as_int(avs_array_elt(args, 8)) : 0; 45 | int bottom = avs_is_int(avs_array_elt(args, 9)) ? 46 | avs_as_int(avs_array_elt(args, 9)) : 0; 47 | int left = avs_is_int(avs_array_elt(args, 10)) ? 48 | avs_as_int(avs_array_elt(args, 10)) : 0; 49 | int right = avs_is_int(avs_array_elt(args, 11)) ? 50 | avs_as_int(avs_array_elt(args, 11)) : 0; 51 | const char* cs = avs_as_string(avs_array_elt(args, 12)) ? 52 | avs_as_string(avs_array_elt(args, 12)) : "UTF-8"; 53 | int debuglevel = avs_is_int(avs_array_elt(args, 13)) ? 54 | avs_as_int(avs_array_elt(args, 13)) : 0; 55 | const char* fontdir = avs_as_string(avs_array_elt(args, 14)) ? 56 | #ifdef AVS_WINDOWS 57 | avs_as_string(avs_array_elt(args, 14)) : "C:/Windows/Fonts"; 58 | #else 59 | avs_as_string(avs_array_elt(args, 14)) : "/usr/share/fonts"; 60 | #endif 61 | const char* srt_font = avs_as_string(avs_array_elt(args, 15)) ? 62 | avs_as_string(avs_array_elt(args, 15)) : "sans-serif"; 63 | const char* colorspace = avs_as_string(avs_array_elt(args, 16)) ? 64 | avs_as_string(avs_array_elt(args, 16)) : ""; 65 | 66 | char* tmpcsp = calloc(1, BUFSIZ); 67 | strncpy(tmpcsp, colorspace, BUFSIZ - 1); 68 | 69 | ASS_Hinting hinting; 70 | udata* data; 71 | ASS_Track* ass; 72 | 73 | /* 74 | no unsupported colorspace left, bitness is checked at other place 75 | if (0 == 1) { 76 | v = avs_new_value_error( 77 | "AssRender: unsupported colorspace"); 78 | avs_release_clip(c); 79 | return v; 80 | } 81 | */ 82 | 83 | if (!f) { 84 | v = avs_new_value_error("AssRender: no input file specified"); 85 | avs_release_clip(c); 86 | return v; 87 | } 88 | 89 | switch (h) { 90 | case 0: 91 | hinting = ASS_HINTING_NONE; 92 | break; 93 | case 1: 94 | hinting = ASS_HINTING_LIGHT; 95 | break; 96 | case 2: 97 | hinting = ASS_HINTING_NORMAL; 98 | break; 99 | case 3: 100 | hinting = ASS_HINTING_NATIVE; 101 | break; 102 | default: 103 | v = avs_new_value_error("AssRender: invalid hinting mode"); 104 | avs_release_clip(c); 105 | return v; 106 | } 107 | 108 | data = malloc(sizeof(udata)); 109 | 110 | if (!init_ass(fi->vi.width, fi->vi.height, scale, line_spacing, 111 | hinting, dar, sar, top, bottom, left, right, 112 | debuglevel, fontdir, data)) { 113 | v = avs_new_value_error("AssRender: failed to initialize"); 114 | avs_release_clip(c); 115 | return v; 116 | } 117 | 118 | if (!strcasecmp(strrchr(f, '.'), ".srt")) 119 | ass = parse_srt(f, data, srt_font); 120 | else { 121 | ass = ass_read_file(data->ass_library, (char*)f, (char*)cs); 122 | ass_read_matrix(f, tmpcsp); 123 | } 124 | 125 | if (!ass) { 126 | sprintf(e, "AssRender: unable to parse '%s'", f); 127 | v = avs_new_value_error(e); 128 | avs_release_clip(c); 129 | return v; 130 | } 131 | 132 | data->ass = ass; 133 | 134 | if (vfr) { 135 | int ver; 136 | FILE* fh = fopen(vfr, "r"); 137 | 138 | if (!fh) { 139 | sprintf(e, "AssRender: could not read timecodes file '%s'", vfr); 140 | v = avs_new_value_error(e); 141 | avs_release_clip(c); 142 | return v; 143 | } 144 | 145 | data->isvfr = 1; 146 | 147 | if (fscanf(fh, "# timecode format v%d", &ver) != 1) { 148 | sprintf(e, "AssRender: invalid timecodes file '%s'", vfr); 149 | v = avs_new_value_error(e); 150 | avs_release_clip(c); 151 | return v; 152 | } 153 | 154 | switch (ver) { 155 | case 1: 156 | 157 | if (!parse_timecodesv1(fh, fi->vi.num_frames, data)) { 158 | v = avs_new_value_error( 159 | "AssRender: error parsing timecodes file"); 160 | avs_release_clip(c); 161 | return v; 162 | } 163 | 164 | break; 165 | case 2: 166 | 167 | if (!parse_timecodesv2(fh, fi->vi.num_frames, data)) { 168 | v = avs_new_value_error( 169 | "AssRender: timecodes file had less frames than " 170 | "expected"); 171 | avs_release_clip(c); 172 | return v; 173 | } 174 | 175 | break; 176 | } 177 | 178 | fclose(fh); 179 | } else { 180 | data->isvfr = 0; 181 | } 182 | 183 | matrix_type color_mt; 184 | 185 | if (avs_is_rgb(&fi->vi)) { 186 | color_mt = MATRIX_NONE; // no RGB->YUV conversion 187 | } else { 188 | // .ASS "YCbCr Matrix" valid values are 189 | // "none" "tv.601" "pc.601" "tv.709" "pc.709" "tv.240m" "pc.240m" "tv.fcc" "pc.fcc" 190 | if (!strcasecmp(tmpcsp, "bt.709") || !strcasecmp(tmpcsp, "rec709") || !strcasecmp(tmpcsp, "tv.709")) { 191 | color_mt = MATRIX_BT709; 192 | } 193 | else if (!strcasecmp(tmpcsp, "pc.709")) { 194 | color_mt = MATRIX_PC709; 195 | } 196 | else if (!strcasecmp(tmpcsp, "bt.601") || !strcasecmp(tmpcsp, "rec601") || !strcasecmp(tmpcsp, "tv.601")) { 197 | color_mt = MATRIX_BT601; 198 | } 199 | else if (!strcasecmp(tmpcsp, "pc.601")) { 200 | color_mt = MATRIX_PC601; 201 | } 202 | else if (!strcasecmp(tmpcsp, "tv.fcc")) { 203 | color_mt = MATRIX_TVFCC; 204 | } 205 | else if (!strcasecmp(tmpcsp, "pc.fcc")) { 206 | color_mt = MATRIX_PCFCC; 207 | } 208 | else if (!strcasecmp(tmpcsp, "tv.240m")) { 209 | color_mt = MATRIX_TV240M; 210 | } 211 | else if (!strcasecmp(tmpcsp, "pc.240m")) { 212 | color_mt = MATRIX_PC240M; 213 | } 214 | else if (!strcasecmp(tmpcsp, "bt.2020") || !strcasecmp(tmpcsp, "rec2020")) { 215 | color_mt = MATRIX_BT2020; 216 | } 217 | else if (!strcasecmp(tmpcsp, "none") || !strcasecmp(tmpcsp, "guess")) { 218 | /* not yet 219 | * Theoretically only for 10 and 12 bits: 220 | if (fi->vi.width > 1920 || fi->vi.height > 1080) 221 | color_mt = MATRIX_BT2020; 222 | else 223 | */ 224 | if (fi->vi.width > 1280 || fi->vi.height > 576) 225 | color_mt = MATRIX_PC709; 226 | else 227 | color_mt = MATRIX_PC601; 228 | } 229 | else { 230 | color_mt = MATRIX_BT601; 231 | } 232 | } 233 | 234 | FillMatrix(&data->mx, color_mt); 235 | 236 | #ifdef FOR_AVISYNTH_26_ONLY 237 | const int bits_per_pixel = 8; 238 | const int pixelsize = 1; 239 | const int greyscale = avs_is_y8(&fi->vi); 240 | #else 241 | const int bits_per_pixel = avs_bits_per_component(&fi->vi); 242 | const int pixelsize = avs_component_size(&fi->vi); 243 | const int greyscale = avs_is_y(&fi->vi); 244 | #endif 245 | 246 | if (bits_per_pixel == 8) 247 | data->f_make_sub_img = make_sub_img; 248 | else if(bits_per_pixel <= 16) 249 | data->f_make_sub_img = make_sub_img16; 250 | else { 251 | v = avs_new_value_error("AssRender: unsupported bit depth: 32"); 252 | avs_release_clip(c); 253 | return v; 254 | } 255 | 256 | 257 | switch (fi->vi.pixel_type) 258 | { 259 | case AVS_CS_YV12: 260 | case AVS_CS_I420: 261 | data->apply = apply_yv12; 262 | break; 263 | case AVS_CS_YUV420P10: 264 | case AVS_CS_YUV420P12: 265 | case AVS_CS_YUV420P14: 266 | case AVS_CS_YUV420P16: 267 | data->apply = apply_yuv420; 268 | break; 269 | case AVS_CS_YV16: 270 | data->apply = apply_yv16; 271 | break; 272 | case AVS_CS_YUV422P10: 273 | case AVS_CS_YUV422P12: 274 | case AVS_CS_YUV422P14: 275 | case AVS_CS_YUV422P16: 276 | data->apply = apply_yuv422; 277 | break; 278 | case AVS_CS_YV24: 279 | case AVS_CS_RGBP: 280 | case AVS_CS_RGBAP: 281 | data->apply = apply_yv24; 282 | break; 283 | case AVS_CS_YUV444P10: 284 | case AVS_CS_YUV444P12: 285 | case AVS_CS_YUV444P14: 286 | case AVS_CS_YUV444P16: 287 | case AVS_CS_RGBP10: 288 | case AVS_CS_RGBP12: 289 | case AVS_CS_RGBP14: 290 | case AVS_CS_RGBP16: 291 | case AVS_CS_RGBAP10: 292 | case AVS_CS_RGBAP12: 293 | case AVS_CS_RGBAP14: 294 | case AVS_CS_RGBAP16: 295 | data->apply = apply_yuv444; 296 | break; 297 | case AVS_CS_Y8: 298 | data->apply = apply_y8; 299 | break; 300 | case AVS_CS_Y10: 301 | case AVS_CS_Y12: 302 | case AVS_CS_Y14: 303 | case AVS_CS_Y16: 304 | data->apply = apply_y; 305 | break; 306 | case AVS_CS_YUY2: 307 | data->apply = apply_yuy2; 308 | break; 309 | case AVS_CS_BGR24: 310 | data->apply = apply_rgb; 311 | break; 312 | case AVS_CS_BGR32: 313 | data->apply = apply_rgba; 314 | break; 315 | case AVS_CS_BGR48: 316 | data->apply = apply_rgb48; 317 | break; 318 | case AVS_CS_BGR64: 319 | data->apply = apply_rgb64; 320 | break; 321 | case AVS_CS_YV411: 322 | data->apply = apply_yv411; 323 | break; 324 | default: 325 | v = avs_new_value_error("AssRender: unsupported pixel type"); 326 | avs_release_clip(c); 327 | return v; 328 | } 329 | 330 | free(tmpcsp); 331 | 332 | const int buffersize = fi->vi.width * fi->vi.height * pixelsize; 333 | 334 | data->sub_img[0] = malloc(buffersize); 335 | data->sub_img[1] = malloc(buffersize); 336 | data->sub_img[2] = malloc(buffersize); 337 | data->sub_img[3] = malloc(buffersize); 338 | 339 | data->bits_per_pixel = bits_per_pixel; 340 | data->pixelsize = pixelsize; 341 | data->rgb_fullscale = avs_is_rgb(&fi->vi); 342 | data->greyscale = greyscale; 343 | 344 | fi->user_data = data; 345 | 346 | fi->get_frame = assrender_get_frame; 347 | 348 | v = avs_new_value_clip(c); 349 | avs_release_clip(c); 350 | 351 | avs_at_exit(env, assrender_destroy, data); 352 | 353 | return v; 354 | } 355 | 356 | const char* AVSC_CC avisynth_c_plugin_init(AVS_ScriptEnvironment* env) 357 | { 358 | avs_add_function(env, "assrender", 359 | "c[file]s[vfr]s[hinting]i[scale]f[line_spacing]f[dar]f" 360 | "[sar]f[top]i[bottom]i[left]i[right]i[charset]s" 361 | "[debuglevel]i[fontdir]s[srt_font]s[colorspace]s", 362 | assrender_create, 0); 363 | return "AssRender: draws text subtitles better and faster than ever before"; 364 | } 365 | -------------------------------------------------------------------------------- /src/assrender.def: -------------------------------------------------------------------------------- 1 | LIBRARY assrender 2 | EXPORTS 3 | avisynth_c_plugin_init@4 = _avisynth_c_plugin_init@4 4 | -------------------------------------------------------------------------------- /src/assrender.h: -------------------------------------------------------------------------------- 1 | #ifndef _ASSRENDER_H_ 2 | #define _ASSRENDER_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "avs/config.h" 10 | #ifdef AVS_WINDOWS 11 | #include "avisynth_c.h" 12 | #else 13 | #include 14 | #endif 15 | 16 | #if defined(_MSC_VER) 17 | #define __NO_ISOCEXT 18 | #define __NO_INLINE__ 19 | 20 | #define strcasecmp _stricmp 21 | #define atoll _atoi64 22 | #endif 23 | 24 | typedef struct { 25 | // premultiplied coefficients for integer scaled arithmetics 26 | int y_r, y_g, y_b; 27 | int u_r, u_g, u_b; 28 | int v_r, v_g, v_b; 29 | int offset_y; 30 | bool valid; 31 | } ConversionMatrix; 32 | 33 | typedef enum { 34 | MATRIX_NONE = 0, 35 | MATRIX_BT601, 36 | MATRIX_PC601, 37 | MATRIX_BT709, 38 | MATRIX_PC709, 39 | MATRIX_PC2020, 40 | MATRIX_BT2020, 41 | MATRIX_TVFCC, 42 | MATRIX_PCFCC, 43 | MATRIX_TV240M, 44 | MATRIX_PC240M 45 | } matrix_type; 46 | 47 | typedef void (* fPixel)(uint8_t** sub_img, uint8_t** data, uint32_t* pitch, uint32_t width, uint32_t height); 48 | typedef void (* fMakeSubImg)(ASS_Image* img, uint8_t** sub_img, uint32_t width, int bits_per_pixel, int rgb, ConversionMatrix* m); 49 | 50 | void col2yuv(uint32_t* c, uint8_t* y, uint8_t* u, uint8_t* v, ConversionMatrix* m); 51 | void col2rgb(uint32_t* c, uint8_t* r, uint8_t* g, uint8_t* b); 52 | 53 | typedef struct { 54 | uint8_t* sub_img[4]; 55 | uint32_t isvfr; 56 | ASS_Track* ass; 57 | ASS_Library* ass_library; 58 | ASS_Renderer* ass_renderer; 59 | int64_t* timestamp; 60 | ConversionMatrix mx; 61 | fPixel apply; 62 | fMakeSubImg f_make_sub_img; 63 | int bits_per_pixel; 64 | int pixelsize; 65 | int rgb_fullscale; 66 | int greyscale; 67 | } udata; 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /src/include/avisynth_c.h: -------------------------------------------------------------------------------- 1 | // Avisynth C Interface Version 0.20 2 | // Copyright 2003 Kevin Atkinson 3 | 4 | // Copyright 2020 AviSynth+ project 5 | 6 | // This program is free software; you can redistribute it and/or modify 7 | // it under the terms of the GNU General Public License as published by 8 | // the Free Software Foundation; either version 2 of the License, or 9 | // (at your option) any later version. 10 | // 11 | // This program is distributed in the hope that it will be useful, 12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | // GNU General Public License for more details. 15 | // 16 | // You should have received a copy of the GNU General Public License 17 | // along with this program; if not, write to the Free Software 18 | // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 19 | // MA 02110-1301 USA, or visit 20 | // http://www.gnu.org/copyleft/gpl.html . 21 | // 22 | // As a special exception, I give you permission to link to the 23 | // Avisynth C interface with independent modules that communicate with 24 | // the Avisynth C interface solely through the interfaces defined in 25 | // avisynth_c.h, regardless of the license terms of these independent 26 | // modules, and to copy and distribute the resulting combined work 27 | // under terms of your choice, provided that every copy of the 28 | // combined work is accompanied by a complete copy of the source code 29 | // of the Avisynth C interface and Avisynth itself (with the version 30 | // used to produce the combined work), being distributed under the 31 | // terms of the GNU General Public License plus this exception. An 32 | // independent module is a module which is not derived from or based 33 | // on Avisynth C Interface, such as 3rd-party filters, import and 34 | // export plugins, or graphical user interfaces. 35 | 36 | // NOTE: this is a partial update of the Avisynth C interface to recognize 37 | // new color spaces and interface elements added in Avisynth 2.60 and AviSynth+. 38 | // This interface is not 100% Avisynth+ CPP interface equivalent. 39 | 40 | // 170103: added new CPU constants (FMA4, AVX512xx) 41 | // 171102: define SIZETMOD. do not use yet, experimental. Offsets are size_t instead of int. Affects x64. 42 | // 171106: avs_get_row_size calls into avs_get_row_size_p, instead of direct field access 43 | // 171106: avs_get_height calls into avs_get_row_size_p, instead of direct field access 44 | // 180524: AVSC_EXPORT to dllexport in capi.h for avisynth_c_plugin_init 45 | // 180524: avs_is_same_colorspace VideoInfo parameters to const 46 | // 181230: Readability: functions regrouped to mix less AVSC_API and AVSC_INLINE, put together Avisynth+ specific stuff 47 | // 181230: use #ifndef AVSC_NO_DECLSPEC for AVSC_INLINE functions which are calling API functions 48 | // 181230: comments on avs_load_library (helper for loading API entries dynamically into a struct using AVSC_NO_DECLSPEC define) 49 | // 181230: define alias AVS_FRAME_ALIGN as FRAME_ALIGN 50 | // 181230: remove unused form of avs_get_rowsize and avs_get_height (kept earlier for reference) 51 | // 190104: avs_load_library: smart fallback mechanism for Avisynth+ specific functions: 52 | // if they are not loadable, they will work in a classic Avisynth compatible mode 53 | // Example#1: e.g. avs_is_444 will call the existing avs_is_yv24 instead 54 | // Example#2: avs_bits_per_component will return 8 for all colorspaces (Classic Avisynth supports only 8 bits/pixel) 55 | // Thus the Avisynth+ specific API functions are safely callable even when connected to classic Avisynth DLL 56 | // 202002xx non-Windows friendly additions 57 | // 20200305 avs_vsprintf parameter type change: (void *) to va_list 58 | // 20200330: (remove test SIZETMOD define for clarity) 59 | // 20200513: user must use explicite #define AVS26_FALLBACK_SIMULATION for having fallback helpers in dynamic loaded library section 60 | // 20200513: Follow AviSynth+ V8 interface additions 61 | // AVS_VideoFrame struct extended with placeholder for frame property pointer 62 | // avs_subframe_planar_a 63 | // avs_copy_frame_props 64 | // avs_get_frame_props_ro, avs_get_frame_props_rw 65 | // avs_prop_num_keys, avs_prop_get_key, avs_prop_num_elements, avs_prop_get_type, avs_prop_get_data_size 66 | // avs_prop_get_int, avs_prop_get_float, avs_prop_get_data, avs_prop_get_clip, avs_prop_get_frame, avs_prop_get_int_array, avs_prop_get_float_array 67 | // avs_prop_set_int, avs_prop_set_float, avs_prop_set_data, avs_prop_set_clip, avs_prop_set_frame, avs_prop_set_int_array, avs_prop_set_float_array 68 | // avs_prop_delete_key, avs_clear_map 69 | // avs_new_video_frame_p, avs_new_video_frame_p_a 70 | // avs_get_env_property (internal system properties), AVS_AEP_xxx (AvsEnvProperty) enums 71 | // avs_get_var_try, avs_get_var_bool, avs_get_var_int, avs_get_var_double, avs_get_var_string, avs_get_var_long 72 | // avs_pool_allocate, avs_pool_free 73 | 74 | 75 | #ifndef __AVISYNTH_C__ 76 | #define __AVISYNTH_C__ 77 | 78 | #include "avs/config.h" 79 | #include "avs/capi.h" 80 | #include "avs/types.h" 81 | 82 | #define AVS_FRAME_ALIGN FRAME_ALIGN 83 | ///////////////////////////////////////////////////////////////////// 84 | // 85 | // Constants 86 | // 87 | 88 | #ifndef __AVISYNTH_8_H__ 89 | enum { 90 | AVISYNTH_INTERFACE_CLASSIC_VERSION = 6, 91 | AVISYNTH_INTERFACE_VERSION = 8 92 | }; 93 | #endif 94 | 95 | enum {AVS_SAMPLE_INT8 = 1<<0, 96 | AVS_SAMPLE_INT16 = 1<<1, 97 | AVS_SAMPLE_INT24 = 1<<2, 98 | AVS_SAMPLE_INT32 = 1<<3, 99 | AVS_SAMPLE_FLOAT = 1<<4}; 100 | 101 | enum {AVS_PLANAR_Y=1<<0, 102 | AVS_PLANAR_U=1<<1, 103 | AVS_PLANAR_V=1<<2, 104 | AVS_PLANAR_ALIGNED=1<<3, 105 | AVS_PLANAR_Y_ALIGNED=AVS_PLANAR_Y|AVS_PLANAR_ALIGNED, 106 | AVS_PLANAR_U_ALIGNED=AVS_PLANAR_U|AVS_PLANAR_ALIGNED, 107 | AVS_PLANAR_V_ALIGNED=AVS_PLANAR_V|AVS_PLANAR_ALIGNED, 108 | AVS_PLANAR_A=1<<4, 109 | AVS_PLANAR_R=1<<5, 110 | AVS_PLANAR_G=1<<6, 111 | AVS_PLANAR_B=1<<7, 112 | AVS_PLANAR_A_ALIGNED=AVS_PLANAR_A|AVS_PLANAR_ALIGNED, 113 | AVS_PLANAR_R_ALIGNED=AVS_PLANAR_R|AVS_PLANAR_ALIGNED, 114 | AVS_PLANAR_G_ALIGNED=AVS_PLANAR_G|AVS_PLANAR_ALIGNED, 115 | AVS_PLANAR_B_ALIGNED=AVS_PLANAR_B|AVS_PLANAR_ALIGNED}; 116 | 117 | // Colorspace properties. 118 | enum { 119 | AVS_CS_YUVA = 1 << 27, 120 | AVS_CS_BGR = 1 << 28, 121 | AVS_CS_YUV = 1 << 29, 122 | AVS_CS_INTERLEAVED = 1 << 30, 123 | AVS_CS_PLANAR = 1 << 31, 124 | 125 | AVS_CS_SHIFT_SUB_WIDTH = 0, 126 | AVS_CS_SHIFT_SUB_HEIGHT = 8, 127 | AVS_CS_SHIFT_SAMPLE_BITS = 16, 128 | 129 | AVS_CS_SUB_WIDTH_MASK = 7 << AVS_CS_SHIFT_SUB_WIDTH, 130 | AVS_CS_SUB_WIDTH_1 = 3 << AVS_CS_SHIFT_SUB_WIDTH, // YV24 131 | AVS_CS_SUB_WIDTH_2 = 0 << AVS_CS_SHIFT_SUB_WIDTH, // YV12, I420, YV16 132 | AVS_CS_SUB_WIDTH_4 = 1 << AVS_CS_SHIFT_SUB_WIDTH, // YUV9, YV411 133 | 134 | AVS_CS_VPLANEFIRST = 1 << 3, // YV12, YV16, YV24, YV411, YUV9 135 | AVS_CS_UPLANEFIRST = 1 << 4, // I420 136 | 137 | AVS_CS_SUB_HEIGHT_MASK = 7 << AVS_CS_SHIFT_SUB_HEIGHT, 138 | AVS_CS_SUB_HEIGHT_1 = 3 << AVS_CS_SHIFT_SUB_HEIGHT, // YV16, YV24, YV411 139 | AVS_CS_SUB_HEIGHT_2 = 0 << AVS_CS_SHIFT_SUB_HEIGHT, // YV12, I420 140 | AVS_CS_SUB_HEIGHT_4 = 1 << AVS_CS_SHIFT_SUB_HEIGHT, // YUV9 141 | 142 | AVS_CS_SAMPLE_BITS_MASK = 7 << AVS_CS_SHIFT_SAMPLE_BITS, 143 | AVS_CS_SAMPLE_BITS_8 = 0 << AVS_CS_SHIFT_SAMPLE_BITS, 144 | AVS_CS_SAMPLE_BITS_10 = 5 << AVS_CS_SHIFT_SAMPLE_BITS, 145 | AVS_CS_SAMPLE_BITS_12 = 6 << AVS_CS_SHIFT_SAMPLE_BITS, 146 | AVS_CS_SAMPLE_BITS_14 = 7 << AVS_CS_SHIFT_SAMPLE_BITS, 147 | AVS_CS_SAMPLE_BITS_16 = 1 << AVS_CS_SHIFT_SAMPLE_BITS, 148 | AVS_CS_SAMPLE_BITS_32 = 2 << AVS_CS_SHIFT_SAMPLE_BITS, 149 | 150 | AVS_CS_PLANAR_MASK = AVS_CS_PLANAR | AVS_CS_INTERLEAVED | AVS_CS_YUV | AVS_CS_BGR | AVS_CS_YUVA | AVS_CS_SAMPLE_BITS_MASK | AVS_CS_SUB_HEIGHT_MASK | AVS_CS_SUB_WIDTH_MASK, 151 | AVS_CS_PLANAR_FILTER = ~(AVS_CS_VPLANEFIRST | AVS_CS_UPLANEFIRST), 152 | 153 | AVS_CS_RGB_TYPE = 1 << 0, 154 | AVS_CS_RGBA_TYPE = 1 << 1, 155 | 156 | AVS_CS_GENERIC_YUV420 = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_VPLANEFIRST | AVS_CS_SUB_HEIGHT_2 | AVS_CS_SUB_WIDTH_2, // 4:2:0 planar 157 | AVS_CS_GENERIC_YUV422 = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_VPLANEFIRST | AVS_CS_SUB_HEIGHT_1 | AVS_CS_SUB_WIDTH_2, // 4:2:2 planar 158 | AVS_CS_GENERIC_YUV444 = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_VPLANEFIRST | AVS_CS_SUB_HEIGHT_1 | AVS_CS_SUB_WIDTH_1, // 4:4:4 planar 159 | AVS_CS_GENERIC_Y = AVS_CS_PLANAR | AVS_CS_INTERLEAVED | AVS_CS_YUV, // Y only (4:0:0) 160 | AVS_CS_GENERIC_RGBP = AVS_CS_PLANAR | AVS_CS_BGR | AVS_CS_RGB_TYPE, // planar RGB 161 | AVS_CS_GENERIC_RGBAP = AVS_CS_PLANAR | AVS_CS_BGR | AVS_CS_RGBA_TYPE, // planar RGBA 162 | AVS_CS_GENERIC_YUVA420 = AVS_CS_PLANAR | AVS_CS_YUVA | AVS_CS_VPLANEFIRST | AVS_CS_SUB_HEIGHT_2 | AVS_CS_SUB_WIDTH_2, // 4:2:0:A planar 163 | AVS_CS_GENERIC_YUVA422 = AVS_CS_PLANAR | AVS_CS_YUVA | AVS_CS_VPLANEFIRST | AVS_CS_SUB_HEIGHT_1 | AVS_CS_SUB_WIDTH_2, // 4:2:2:A planar 164 | AVS_CS_GENERIC_YUVA444 = AVS_CS_PLANAR | AVS_CS_YUVA | AVS_CS_VPLANEFIRST | AVS_CS_SUB_HEIGHT_1 | AVS_CS_SUB_WIDTH_1 }; // 4:4:4:A planar 165 | 166 | 167 | // Specific color formats 168 | enum { 169 | AVS_CS_UNKNOWN = 0, 170 | AVS_CS_BGR24 = AVS_CS_RGB_TYPE | AVS_CS_BGR | AVS_CS_INTERLEAVED, 171 | AVS_CS_BGR32 = AVS_CS_RGBA_TYPE | AVS_CS_BGR | AVS_CS_INTERLEAVED, 172 | AVS_CS_YUY2 = 1<<2 | AVS_CS_YUV | AVS_CS_INTERLEAVED, 173 | // AVS_CS_YV12 = 1<<3 Reserved 174 | // AVS_CS_I420 = 1<<4 Reserved 175 | AVS_CS_RAW32 = 1<<5 | AVS_CS_INTERLEAVED, 176 | 177 | AVS_CS_YV24 = AVS_CS_GENERIC_YUV444 | AVS_CS_SAMPLE_BITS_8, // YUV 4:4:4 planar 178 | AVS_CS_YV16 = AVS_CS_GENERIC_YUV422 | AVS_CS_SAMPLE_BITS_8, // YUV 4:2:2 planar 179 | AVS_CS_YV12 = AVS_CS_GENERIC_YUV420 | AVS_CS_SAMPLE_BITS_8, // YUV 4:2:0 planar 180 | AVS_CS_I420 = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_SAMPLE_BITS_8 | AVS_CS_UPLANEFIRST | AVS_CS_SUB_HEIGHT_2 | AVS_CS_SUB_WIDTH_2, // YUV 4:2:0 planar 181 | AVS_CS_IYUV = AVS_CS_I420, 182 | AVS_CS_YV411 = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_SAMPLE_BITS_8 | AVS_CS_VPLANEFIRST | AVS_CS_SUB_HEIGHT_1 | AVS_CS_SUB_WIDTH_4, // YUV 4:1:1 planar 183 | AVS_CS_YUV9 = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_SAMPLE_BITS_8 | AVS_CS_VPLANEFIRST | AVS_CS_SUB_HEIGHT_4 | AVS_CS_SUB_WIDTH_4, // YUV 4:1:0 planar 184 | AVS_CS_Y8 = AVS_CS_GENERIC_Y | AVS_CS_SAMPLE_BITS_8, // Y 4:0:0 planar 185 | 186 | //------------------------- 187 | // AVS16: new planar constants go live! Experimental PF 160613 188 | // 10-12-14-16 bit + planar RGB + BGR48/64 160725 189 | AVS_CS_YUV444P10 = AVS_CS_GENERIC_YUV444 | AVS_CS_SAMPLE_BITS_10, // YUV 4:4:4 10bit samples 190 | AVS_CS_YUV422P10 = AVS_CS_GENERIC_YUV422 | AVS_CS_SAMPLE_BITS_10, // YUV 4:2:2 10bit samples 191 | AVS_CS_YUV420P10 = AVS_CS_GENERIC_YUV420 | AVS_CS_SAMPLE_BITS_10, // YUV 4:2:0 10bit samples 192 | AVS_CS_Y10 = AVS_CS_GENERIC_Y | AVS_CS_SAMPLE_BITS_10, // Y 4:0:0 10bit samples 193 | 194 | AVS_CS_YUV444P12 = AVS_CS_GENERIC_YUV444 | AVS_CS_SAMPLE_BITS_12, // YUV 4:4:4 12bit samples 195 | AVS_CS_YUV422P12 = AVS_CS_GENERIC_YUV422 | AVS_CS_SAMPLE_BITS_12, // YUV 4:2:2 12bit samples 196 | AVS_CS_YUV420P12 = AVS_CS_GENERIC_YUV420 | AVS_CS_SAMPLE_BITS_12, // YUV 4:2:0 12bit samples 197 | AVS_CS_Y12 = AVS_CS_GENERIC_Y | AVS_CS_SAMPLE_BITS_12, // Y 4:0:0 12bit samples 198 | 199 | AVS_CS_YUV444P14 = AVS_CS_GENERIC_YUV444 | AVS_CS_SAMPLE_BITS_14, // YUV 4:4:4 14bit samples 200 | AVS_CS_YUV422P14 = AVS_CS_GENERIC_YUV422 | AVS_CS_SAMPLE_BITS_14, // YUV 4:2:2 14bit samples 201 | AVS_CS_YUV420P14 = AVS_CS_GENERIC_YUV420 | AVS_CS_SAMPLE_BITS_14, // YUV 4:2:0 14bit samples 202 | AVS_CS_Y14 = AVS_CS_GENERIC_Y | AVS_CS_SAMPLE_BITS_14, // Y 4:0:0 14bit samples 203 | 204 | AVS_CS_YUV444P16 = AVS_CS_GENERIC_YUV444 | AVS_CS_SAMPLE_BITS_16, // YUV 4:4:4 16bit samples 205 | AVS_CS_YUV422P16 = AVS_CS_GENERIC_YUV422 | AVS_CS_SAMPLE_BITS_16, // YUV 4:2:2 16bit samples 206 | AVS_CS_YUV420P16 = AVS_CS_GENERIC_YUV420 | AVS_CS_SAMPLE_BITS_16, // YUV 4:2:0 16bit samples 207 | AVS_CS_Y16 = AVS_CS_GENERIC_Y | AVS_CS_SAMPLE_BITS_16, // Y 4:0:0 16bit samples 208 | 209 | // 32 bit samples (float) 210 | AVS_CS_YUV444PS = AVS_CS_GENERIC_YUV444 | AVS_CS_SAMPLE_BITS_32, // YUV 4:4:4 32bit samples 211 | AVS_CS_YUV422PS = AVS_CS_GENERIC_YUV422 | AVS_CS_SAMPLE_BITS_32, // YUV 4:2:2 32bit samples 212 | AVS_CS_YUV420PS = AVS_CS_GENERIC_YUV420 | AVS_CS_SAMPLE_BITS_32, // YUV 4:2:0 32bit samples 213 | AVS_CS_Y32 = AVS_CS_GENERIC_Y | AVS_CS_SAMPLE_BITS_32, // Y 4:0:0 32bit samples 214 | 215 | // RGB packed 216 | AVS_CS_BGR48 = AVS_CS_RGB_TYPE | AVS_CS_BGR | AVS_CS_INTERLEAVED | AVS_CS_SAMPLE_BITS_16, // BGR 3x16 bit 217 | AVS_CS_BGR64 = AVS_CS_RGBA_TYPE | AVS_CS_BGR | AVS_CS_INTERLEAVED | AVS_CS_SAMPLE_BITS_16, // BGR 4x16 bit 218 | // no packed 32 bit (float) support for these legacy types 219 | 220 | // RGB planar 221 | AVS_CS_RGBP = AVS_CS_GENERIC_RGBP | AVS_CS_SAMPLE_BITS_8, // Planar RGB 8 bit samples 222 | AVS_CS_RGBP10 = AVS_CS_GENERIC_RGBP | AVS_CS_SAMPLE_BITS_10, // Planar RGB 10bit samples 223 | AVS_CS_RGBP12 = AVS_CS_GENERIC_RGBP | AVS_CS_SAMPLE_BITS_12, // Planar RGB 12bit samples 224 | AVS_CS_RGBP14 = AVS_CS_GENERIC_RGBP | AVS_CS_SAMPLE_BITS_14, // Planar RGB 14bit samples 225 | AVS_CS_RGBP16 = AVS_CS_GENERIC_RGBP | AVS_CS_SAMPLE_BITS_16, // Planar RGB 16bit samples 226 | AVS_CS_RGBPS = AVS_CS_GENERIC_RGBP | AVS_CS_SAMPLE_BITS_32, // Planar RGB 32bit samples 227 | 228 | // RGBA planar 229 | AVS_CS_RGBAP = AVS_CS_GENERIC_RGBAP | AVS_CS_SAMPLE_BITS_8, // Planar RGBA 8 bit samples 230 | AVS_CS_RGBAP10 = AVS_CS_GENERIC_RGBAP | AVS_CS_SAMPLE_BITS_10, // Planar RGBA 10bit samples 231 | AVS_CS_RGBAP12 = AVS_CS_GENERIC_RGBAP | AVS_CS_SAMPLE_BITS_12, // Planar RGBA 12bit samples 232 | AVS_CS_RGBAP14 = AVS_CS_GENERIC_RGBAP | AVS_CS_SAMPLE_BITS_14, // Planar RGBA 14bit samples 233 | AVS_CS_RGBAP16 = AVS_CS_GENERIC_RGBAP | AVS_CS_SAMPLE_BITS_16, // Planar RGBA 16bit samples 234 | AVS_CS_RGBAPS = AVS_CS_GENERIC_RGBAP | AVS_CS_SAMPLE_BITS_32, // Planar RGBA 32bit samples 235 | 236 | // Planar YUVA 237 | AVS_CS_YUVA444 = AVS_CS_GENERIC_YUVA444 | AVS_CS_SAMPLE_BITS_8, // YUVA 4:4:4 8bit samples 238 | AVS_CS_YUVA422 = AVS_CS_GENERIC_YUVA422 | AVS_CS_SAMPLE_BITS_8, // YUVA 4:2:2 8bit samples 239 | AVS_CS_YUVA420 = AVS_CS_GENERIC_YUVA420 | AVS_CS_SAMPLE_BITS_8, // YUVA 4:2:0 8bit samples 240 | 241 | AVS_CS_YUVA444P10 = AVS_CS_GENERIC_YUVA444 | AVS_CS_SAMPLE_BITS_10, // YUVA 4:4:4 10bit samples 242 | AVS_CS_YUVA422P10 = AVS_CS_GENERIC_YUVA422 | AVS_CS_SAMPLE_BITS_10, // YUVA 4:2:2 10bit samples 243 | AVS_CS_YUVA420P10 = AVS_CS_GENERIC_YUVA420 | AVS_CS_SAMPLE_BITS_10, // YUVA 4:2:0 10bit samples 244 | 245 | AVS_CS_YUVA444P12 = AVS_CS_GENERIC_YUVA444 | AVS_CS_SAMPLE_BITS_12, // YUVA 4:4:4 12bit samples 246 | AVS_CS_YUVA422P12 = AVS_CS_GENERIC_YUVA422 | AVS_CS_SAMPLE_BITS_12, // YUVA 4:2:2 12bit samples 247 | AVS_CS_YUVA420P12 = AVS_CS_GENERIC_YUVA420 | AVS_CS_SAMPLE_BITS_12, // YUVA 4:2:0 12bit samples 248 | 249 | AVS_CS_YUVA444P14 = AVS_CS_GENERIC_YUVA444 | AVS_CS_SAMPLE_BITS_14, // YUVA 4:4:4 14bit samples 250 | AVS_CS_YUVA422P14 = AVS_CS_GENERIC_YUVA422 | AVS_CS_SAMPLE_BITS_14, // YUVA 4:2:2 14bit samples 251 | AVS_CS_YUVA420P14 = AVS_CS_GENERIC_YUVA420 | AVS_CS_SAMPLE_BITS_14, // YUVA 4:2:0 14bit samples 252 | 253 | AVS_CS_YUVA444P16 = AVS_CS_GENERIC_YUVA444 | AVS_CS_SAMPLE_BITS_16, // YUVA 4:4:4 16bit samples 254 | AVS_CS_YUVA422P16 = AVS_CS_GENERIC_YUVA422 | AVS_CS_SAMPLE_BITS_16, // YUVA 4:2:2 16bit samples 255 | AVS_CS_YUVA420P16 = AVS_CS_GENERIC_YUVA420 | AVS_CS_SAMPLE_BITS_16, // YUVA 4:2:0 16bit samples 256 | 257 | AVS_CS_YUVA444PS = AVS_CS_GENERIC_YUVA444 | AVS_CS_SAMPLE_BITS_32, // YUVA 4:4:4 32bit samples 258 | AVS_CS_YUVA422PS = AVS_CS_GENERIC_YUVA422 | AVS_CS_SAMPLE_BITS_32, // YUVA 4:2:2 32bit samples 259 | AVS_CS_YUVA420PS = AVS_CS_GENERIC_YUVA420 | AVS_CS_SAMPLE_BITS_32, // YUVA 4:2:0 32bit samples 260 | 261 | }; 262 | 263 | enum { 264 | AVS_IT_BFF = 1<<0, 265 | AVS_IT_TFF = 1<<1, 266 | AVS_IT_FIELDBASED = 1<<2}; 267 | 268 | enum { 269 | AVS_FILTER_TYPE=1, 270 | AVS_FILTER_INPUT_COLORSPACE=2, 271 | AVS_FILTER_OUTPUT_TYPE=9, 272 | AVS_FILTER_NAME=4, 273 | AVS_FILTER_AUTHOR=5, 274 | AVS_FILTER_VERSION=6, 275 | AVS_FILTER_ARGS=7, 276 | AVS_FILTER_ARGS_INFO=8, 277 | AVS_FILTER_ARGS_DESCRIPTION=10, 278 | AVS_FILTER_DESCRIPTION=11}; 279 | 280 | enum { //SUBTYPES 281 | AVS_FILTER_TYPE_AUDIO=1, 282 | AVS_FILTER_TYPE_VIDEO=2, 283 | AVS_FILTER_OUTPUT_TYPE_SAME=3, 284 | AVS_FILTER_OUTPUT_TYPE_DIFFERENT=4}; 285 | 286 | enum { 287 | // New 2.6 explicitly defined cache hints. 288 | AVS_CACHE_NOTHING = 10, // Do not cache video. 289 | AVS_CACHE_WINDOW = 11, // Hard protect up to X frames within a range of X from the current frame N. 290 | AVS_CACHE_GENERIC = 12, // LRU cache up to X frames. 291 | AVS_CACHE_FORCE_GENERIC = 13, // LRU cache up to X frames, override any previous CACHE_WINDOW. 292 | 293 | AVS_CACHE_GET_POLICY = 30, // Get the current policy. 294 | AVS_CACHE_GET_WINDOW = 31, // Get the current window h_span. 295 | AVS_CACHE_GET_RANGE = 32, // Get the current generic frame range. 296 | 297 | AVS_CACHE_AUDIO = 50, // Explicitly do cache audio, X byte cache. 298 | AVS_CACHE_AUDIO_NOTHING = 51, // Explicitly do not cache audio. 299 | AVS_CACHE_AUDIO_NONE = 52, // Audio cache off (auto mode), X byte initial cache. 300 | AVS_CACHE_AUDIO_AUTO = 53, // Audio cache on (auto mode), X byte initial cache. 301 | 302 | AVS_CACHE_GET_AUDIO_POLICY = 70, // Get the current audio policy. 303 | AVS_CACHE_GET_AUDIO_SIZE = 71, // Get the current audio cache size. 304 | 305 | AVS_CACHE_PREFETCH_FRAME = 100, // Queue request to prefetch frame N. 306 | AVS_CACHE_PREFETCH_GO = 101, // Action video prefetches. 307 | 308 | AVS_CACHE_PREFETCH_AUDIO_BEGIN = 120, // Begin queue request transaction to prefetch audio (take critical section). 309 | AVS_CACHE_PREFETCH_AUDIO_STARTLO = 121, // Set low 32 bits of start. 310 | AVS_CACHE_PREFETCH_AUDIO_STARTHI = 122, // Set high 32 bits of start. 311 | AVS_CACHE_PREFETCH_AUDIO_COUNT = 123, // Set low 32 bits of length. 312 | AVS_CACHE_PREFETCH_AUDIO_COMMIT = 124, // Enqueue request transaction to prefetch audio (release critical section). 313 | AVS_CACHE_PREFETCH_AUDIO_GO = 125, // Action audio prefetches. 314 | 315 | AVS_CACHE_GETCHILD_CACHE_MODE = 200, // Cache ask Child for desired video cache mode. 316 | AVS_CACHE_GETCHILD_CACHE_SIZE = 201, // Cache ask Child for desired video cache size. 317 | AVS_CACHE_GETCHILD_AUDIO_MODE = 202, // Cache ask Child for desired audio cache mode. 318 | AVS_CACHE_GETCHILD_AUDIO_SIZE = 203, // Cache ask Child for desired audio cache size. 319 | 320 | AVS_CACHE_GETCHILD_COST = 220, // Cache ask Child for estimated processing cost. 321 | AVS_CACHE_COST_ZERO = 221, // Child response of zero cost (ptr arithmetic only). 322 | AVS_CACHE_COST_UNIT = 222, // Child response of unit cost (less than or equal 1 full frame blit). 323 | AVS_CACHE_COST_LOW = 223, // Child response of light cost. (Fast) 324 | AVS_CACHE_COST_MED = 224, // Child response of medium cost. (Real time) 325 | AVS_CACHE_COST_HI = 225, // Child response of heavy cost. (Slow) 326 | 327 | AVS_CACHE_GETCHILD_THREAD_MODE = 240, // Cache ask Child for thread safety. 328 | AVS_CACHE_THREAD_UNSAFE = 241, // Only 1 thread allowed for all instances. 2.5 filters default! 329 | AVS_CACHE_THREAD_CLASS = 242, // Only 1 thread allowed for each instance. 2.6 filters default! 330 | AVS_CACHE_THREAD_SAFE = 243, // Allow all threads in any instance. 331 | AVS_CACHE_THREAD_OWN = 244, // Safe but limit to 1 thread, internally threaded. 332 | 333 | AVS_CACHE_GETCHILD_ACCESS_COST = 260, // Cache ask Child for preferred access pattern. 334 | AVS_CACHE_ACCESS_RAND = 261, // Filter is access order agnostic. 335 | AVS_CACHE_ACCESS_SEQ0 = 262, // Filter prefers sequential access (low cost) 336 | AVS_CACHE_ACCESS_SEQ1 = 263, // Filter needs sequential access (high cost) 337 | 338 | AVS_CACHE_AVSPLUS_CONSTANTS = 500, // Smaller values are reserved for classic Avisynth 339 | 340 | AVS_CACHE_DONT_CACHE_ME = 501, // Filters that don't need caching (eg. trim, cache etc.) should return 1 to this request 341 | AVS_CACHE_SET_MIN_CAPACITY = 502, 342 | AVS_CACHE_SET_MAX_CAPACITY = 503, 343 | AVS_CACHE_GET_MIN_CAPACITY = 504, 344 | AVS_CACHE_GET_MAX_CAPACITY = 505, 345 | AVS_CACHE_GET_SIZE = 506, 346 | AVS_CACHE_GET_REQUESTED_CAP = 507, 347 | AVS_CACHE_GET_CAPACITY = 508, 348 | AVS_CACHE_GET_MTMODE = 509, 349 | 350 | AVS_CACHE_IS_CACHE_REQ = 510, 351 | AVS_CACHE_IS_CACHE_ANS = 511, 352 | AVS_CACHE_IS_MTGUARD_REQ = 512, 353 | AVS_CACHE_IS_MTGUARD_ANS = 513, 354 | 355 | AVS_CACHE_AVSPLUS_CUDA_CONSTANTS = 600, 356 | 357 | AVS_CACHE_GET_DEV_TYPE = 601, // Device types a filter can return 358 | AVS_CACHE_GET_CHILD_DEV_TYPE = 602, // Device types a fitler can receive 359 | 360 | AVS_CACHE_USER_CONSTANTS = 1000 // Smaller values are reserved for the core 361 | 362 | }; 363 | 364 | 365 | 366 | // enums for frame property functions 367 | // AVSPropTypes 368 | enum { 369 | AVS_PROPTYPE_UNSET = 'u', 370 | AVS_PROPTYPE_INT = 'i', 371 | AVS_PROPTYPE_FLOAT = 'f', 372 | AVS_PROPTYPE_DATA = 's', 373 | AVS_PROPTYPE_CLIP = 'c', 374 | AVS_PROPTYPE_FRAME = 'v' 375 | }; 376 | 377 | // AVSGetPropErrors for avs_prop_get_... 378 | enum { 379 | AVS_GETPROPERROR_UNSET = 1, 380 | AVS_GETPROPERROR_TYPE = 2, 381 | AVS_GETPROPERROR_INDEX = 4 382 | }; 383 | 384 | // AVSPropAppendMode for avs_prop_set_... 385 | enum { 386 | AVS_PROPAPPENDMODE_REPLACE = 0, 387 | AVS_PROPAPPENDMODE_APPEND = 1, 388 | AVS_PROPAPPENDMODE_TOUCH = 2 389 | }; 390 | 391 | // AvsEnvProperty for avs_get_env_property 392 | enum 393 | { 394 | AVS_AEP_PHYSICAL_CPUS = 1, 395 | AVS_AEP_LOGICAL_CPUS = 2, 396 | AVS_AEP_THREADPOOL_THREADS = 3, 397 | AVS_AEP_FILTERCHAIN_THREADS = 4, 398 | AVS_AEP_THREAD_ID = 5, 399 | AVS_AEP_VERSION = 6, 400 | 401 | // Neo additionals 402 | AVS_AEP_NUM_DEVICES = 901, 403 | AVS_AEP_FRAME_ALIGN = 902, 404 | AVS_AEP_PLANE_ALIGN = 903, 405 | 406 | AVS_AEP_SUPPRESS_THREAD = 921, 407 | AVS_AEP_GETFRAME_RECURSIVE = 922 408 | }; 409 | 410 | // enum AvsAllocType for avs_allocate 411 | enum { 412 | AVS_ALLOCTYPE_NORMAL_ALLOC = 1, 413 | AVS_ALLOCTYPE_POOLED_ALLOC = 2 414 | }; 415 | 416 | #ifdef BUILDING_AVSCORE 417 | AVSValue create_c_video_filter(AVSValue args, void * user_data, IScriptEnvironment * e0); 418 | 419 | struct AVS_ScriptEnvironment { 420 | IScriptEnvironment * env; 421 | const char * error; 422 | AVS_ScriptEnvironment(IScriptEnvironment * e = 0) 423 | : env(e), error(0) {} 424 | }; 425 | #endif 426 | 427 | typedef struct AVS_Clip AVS_Clip; 428 | typedef struct AVS_ScriptEnvironment AVS_ScriptEnvironment; 429 | 430 | ///////////////////////////////////////////////////////////////////// 431 | // 432 | // AVS_VideoInfo 433 | // 434 | 435 | // AVS_VideoInfo is laid out identically to VideoInfo 436 | typedef struct AVS_VideoInfo { 437 | int width, height; // width=0 means no video 438 | unsigned fps_numerator, fps_denominator; 439 | int num_frames; 440 | 441 | int pixel_type; 442 | 443 | int audio_samples_per_second; // 0 means no audio 444 | int sample_type; 445 | int64_t num_audio_samples; 446 | int nchannels; 447 | 448 | // Image type properties 449 | 450 | int image_type; 451 | } AVS_VideoInfo; 452 | 453 | // useful functions of the above 454 | AVSC_INLINE int avs_has_video(const AVS_VideoInfo * p) 455 | { return (p->width!=0); } 456 | 457 | AVSC_INLINE int avs_has_audio(const AVS_VideoInfo * p) 458 | { return (p->audio_samples_per_second!=0); } 459 | 460 | AVSC_INLINE int avs_is_rgb(const AVS_VideoInfo * p) 461 | { return !!(p->pixel_type&AVS_CS_BGR); } 462 | 463 | AVSC_INLINE int avs_is_rgb24(const AVS_VideoInfo * p) 464 | { return ((p->pixel_type&AVS_CS_BGR24)==AVS_CS_BGR24) && ((p->pixel_type & AVS_CS_SAMPLE_BITS_MASK) == AVS_CS_SAMPLE_BITS_8); } 465 | 466 | AVSC_INLINE int avs_is_rgb32(const AVS_VideoInfo * p) 467 | { return ((p->pixel_type&AVS_CS_BGR32)==AVS_CS_BGR32) && ((p->pixel_type & AVS_CS_SAMPLE_BITS_MASK) == AVS_CS_SAMPLE_BITS_8); } 468 | 469 | AVSC_INLINE int avs_is_yuv(const AVS_VideoInfo * p) 470 | { return !!(p->pixel_type&AVS_CS_YUV ); } 471 | 472 | AVSC_INLINE int avs_is_yuy2(const AVS_VideoInfo * p) 473 | { return (p->pixel_type & AVS_CS_YUY2) == AVS_CS_YUY2; } 474 | 475 | AVSC_API(int, avs_is_yv24)(const AVS_VideoInfo * p); // avs+: for generic 444 check, use avs_is_yuv444 476 | 477 | AVSC_API(int, avs_is_yv16)(const AVS_VideoInfo * p); // avs+: for generic 422 check, use avs_is_yuv422 478 | 479 | AVSC_API(int, avs_is_yv12)(const AVS_VideoInfo * p) ; // avs+: for generic 420 check, use avs_is_yuv420 480 | 481 | AVSC_API(int, avs_is_yv411)(const AVS_VideoInfo * p); 482 | 483 | AVSC_API(int, avs_is_y8)(const AVS_VideoInfo * p); // avs+: for generic grayscale, use avs_is_y 484 | 485 | AVSC_API(int, avs_get_plane_width_subsampling)(const AVS_VideoInfo * p, int plane); 486 | 487 | AVSC_API(int, avs_get_plane_height_subsampling)(const AVS_VideoInfo * p, int plane); 488 | 489 | AVSC_API(int, avs_bits_per_pixel)(const AVS_VideoInfo * p); 490 | 491 | AVSC_API(int, avs_bytes_from_pixels)(const AVS_VideoInfo * p, int pixels); 492 | 493 | AVSC_API(int, avs_row_size)(const AVS_VideoInfo * p, int plane); 494 | 495 | AVSC_API(int, avs_bmp_size)(const AVS_VideoInfo * vi); 496 | 497 | AVSC_API(int, avs_is_color_space)(const AVS_VideoInfo * p, int c_space); 498 | 499 | // no API for these, inline helper functions 500 | AVSC_INLINE int avs_is_property(const AVS_VideoInfo * p, int property) 501 | { 502 | return ((p->image_type & property) == property); 503 | } 504 | 505 | AVSC_INLINE int avs_is_planar(const AVS_VideoInfo * p) 506 | { 507 | return !!(p->pixel_type & AVS_CS_PLANAR); 508 | } 509 | 510 | AVSC_INLINE int avs_is_field_based(const AVS_VideoInfo * p) 511 | { 512 | return !!(p->image_type & AVS_IT_FIELDBASED); 513 | } 514 | 515 | AVSC_INLINE int avs_is_parity_known(const AVS_VideoInfo * p) 516 | { 517 | return ((p->image_type & AVS_IT_FIELDBASED) && (p->image_type & (AVS_IT_BFF | AVS_IT_TFF))); 518 | } 519 | 520 | AVSC_INLINE int avs_is_bff(const AVS_VideoInfo * p) 521 | { 522 | return !!(p->image_type & AVS_IT_BFF); 523 | } 524 | 525 | AVSC_INLINE int avs_is_tff(const AVS_VideoInfo * p) 526 | { 527 | return !!(p->image_type & AVS_IT_TFF); 528 | } 529 | 530 | AVSC_INLINE int avs_samples_per_second(const AVS_VideoInfo * p) 531 | { return p->audio_samples_per_second; } 532 | 533 | AVSC_INLINE int avs_bytes_per_channel_sample(const AVS_VideoInfo * p) 534 | { 535 | switch (p->sample_type) { 536 | case AVS_SAMPLE_INT8: return sizeof(signed char); 537 | case AVS_SAMPLE_INT16: return sizeof(signed short); 538 | case AVS_SAMPLE_INT24: return 3; 539 | case AVS_SAMPLE_INT32: return sizeof(signed int); 540 | case AVS_SAMPLE_FLOAT: return sizeof(float); 541 | default: return 0; 542 | } 543 | } 544 | 545 | AVSC_INLINE int avs_bytes_per_audio_sample(const AVS_VideoInfo * p) 546 | { return p->nchannels*avs_bytes_per_channel_sample(p);} 547 | 548 | AVSC_INLINE int64_t avs_audio_samples_from_frames(const AVS_VideoInfo * p, int64_t frames) 549 | { return ((int64_t)(frames) * p->audio_samples_per_second * p->fps_denominator / p->fps_numerator); } 550 | 551 | AVSC_INLINE int avs_frames_from_audio_samples(const AVS_VideoInfo * p, int64_t samples) 552 | { return (int)(samples * (int64_t)p->fps_numerator / (int64_t)p->fps_denominator / (int64_t)p->audio_samples_per_second); } 553 | 554 | AVSC_INLINE int64_t avs_audio_samples_from_bytes(const AVS_VideoInfo * p, int64_t bytes) 555 | { return bytes / avs_bytes_per_audio_sample(p); } 556 | 557 | AVSC_INLINE int64_t avs_bytes_from_audio_samples(const AVS_VideoInfo * p, int64_t samples) 558 | { return samples * avs_bytes_per_audio_sample(p); } 559 | 560 | AVSC_INLINE int avs_audio_channels(const AVS_VideoInfo * p) 561 | { return p->nchannels; } 562 | 563 | AVSC_INLINE int avs_sample_type(const AVS_VideoInfo * p) 564 | { return p->sample_type;} 565 | 566 | // useful mutator 567 | // Note: these are video format properties, neither frame properties, nor system properties 568 | AVSC_INLINE void avs_set_property(AVS_VideoInfo * p, int property) 569 | { p->image_type|=property; } 570 | 571 | AVSC_INLINE void avs_clear_property(AVS_VideoInfo * p, int property) 572 | { p->image_type&=~property; } 573 | 574 | AVSC_INLINE void avs_set_field_based(AVS_VideoInfo * p, int isfieldbased) 575 | { if (isfieldbased) p->image_type|=AVS_IT_FIELDBASED; else p->image_type&=~AVS_IT_FIELDBASED; } 576 | 577 | AVSC_INLINE void avs_set_fps(AVS_VideoInfo * p, unsigned numerator, unsigned denominator) 578 | { 579 | unsigned x=numerator, y=denominator; 580 | while (y) { // find gcd 581 | unsigned t = x%y; x = y; y = t; 582 | } 583 | p->fps_numerator = numerator/x; 584 | p->fps_denominator = denominator/x; 585 | } 586 | 587 | #ifndef AVSC_NO_DECLSPEC 588 | // this inline function is calling an API function 589 | AVSC_INLINE int avs_is_same_colorspace(const AVS_VideoInfo * x, const AVS_VideoInfo * y) 590 | { 591 | return (x->pixel_type == y->pixel_type) 592 | || (avs_is_yv12(x) && avs_is_yv12(y)); 593 | } 594 | #endif 595 | 596 | // AviSynth+ extensions 597 | AVSC_API(int, avs_is_rgb48)(const AVS_VideoInfo * p); 598 | 599 | AVSC_API(int, avs_is_rgb64)(const AVS_VideoInfo * p); 600 | 601 | AVSC_API(int, avs_is_yuv444p16)(const AVS_VideoInfo * p); // deprecated, use avs_is_yuv444 602 | AVSC_API(int, avs_is_yuv422p16)(const AVS_VideoInfo * p); // deprecated, use avs_is_yuv422 603 | AVSC_API(int, avs_is_yuv420p16)(const AVS_VideoInfo * p); // deprecated, use avs_is_yuv420 604 | AVSC_API(int, avs_is_y16)(const AVS_VideoInfo * p); // deprecated, use avs_is_y 605 | AVSC_API(int, avs_is_yuv444ps)(const AVS_VideoInfo * p); // deprecated, use avs_is_yuv444 606 | AVSC_API(int, avs_is_yuv422ps)(const AVS_VideoInfo * p); // deprecated, use avs_is_yuv422 607 | AVSC_API(int, avs_is_yuv420ps)(const AVS_VideoInfo * p); // deprecated, use avs_is_yuv420 608 | AVSC_API(int, avs_is_y32)(const AVS_VideoInfo * p); // deprecated, use avs_is_y 609 | 610 | AVSC_API(int, avs_is_444)(const AVS_VideoInfo * p); 611 | 612 | AVSC_API(int, avs_is_422)(const AVS_VideoInfo * p); 613 | 614 | AVSC_API(int, avs_is_420)(const AVS_VideoInfo * p); 615 | 616 | AVSC_API(int, avs_is_y)(const AVS_VideoInfo * p); 617 | 618 | AVSC_API(int, avs_is_yuva)(const AVS_VideoInfo * p); 619 | 620 | AVSC_API(int, avs_is_planar_rgb)(const AVS_VideoInfo * p); 621 | 622 | AVSC_API(int, avs_is_planar_rgba)(const AVS_VideoInfo * p); 623 | 624 | AVSC_API(int, avs_num_components)(const AVS_VideoInfo * p); 625 | 626 | AVSC_API(int, avs_component_size)(const AVS_VideoInfo * p); 627 | 628 | AVSC_API(int, avs_bits_per_component)(const AVS_VideoInfo * p); 629 | 630 | // end of Avisynth+ specific 631 | 632 | ///////////////////////////////////////////////////////////////////// 633 | // 634 | // AVS_VideoFrame 635 | // 636 | 637 | // VideoFrameBuffer holds information about a memory block which is used 638 | // for video data. For efficiency, instances of this class are not deleted 639 | // when the refcount reaches zero; instead they're stored in a linked list 640 | // to be reused. The instances are deleted when the corresponding AVS 641 | // file is closed. 642 | 643 | // AVS_VideoFrameBuffer is laid out identically to VideoFrameBuffer 644 | // DO NOT USE THIS STRUCTURE DIRECTLY 645 | typedef struct AVS_VideoFrameBuffer { 646 | BYTE * data; 647 | int data_size; 648 | // sequence_number is incremented every time the buffer is changed, so 649 | // that stale views can tell they're no longer valid. 650 | volatile long sequence_number; 651 | 652 | volatile long refcount; 653 | 654 | void* device; // avs+ 655 | } AVS_VideoFrameBuffer; 656 | 657 | // VideoFrame holds a "window" into a VideoFrameBuffer. 658 | 659 | // AVS_VideoFrame is laid out identically to IVideoFrame 660 | // DO NOT USE THIS STRUCTURE DIRECTLY 661 | typedef struct AVS_VideoFrame { 662 | volatile long refcount; 663 | AVS_VideoFrameBuffer * vfb; 664 | int offset; 665 | int pitch, row_size, height; 666 | int offsetU, offsetV; 667 | int pitchUV; // U&V offsets are from top of picture. 668 | int row_sizeUV, heightUV; // for Planar RGB offsetU, offsetV is for the 2nd and 3rd Plane. 669 | // for Planar RGB pitchUV and row_sizeUV = 0, because when no VideoInfo (MakeWriteable) 670 | // the decision on existence of UV is checked by zero pitch 671 | // AVS+ extension, avisynth.h: class does not break plugins if appended here 672 | int offsetA; 673 | int pitchA, row_sizeA; // 4th alpha plane support, pitch and row_size is 0 is none 674 | void* properties; // frame properties 675 | } AVS_VideoFrame; 676 | 677 | // Access functions for AVS_VideoFrame 678 | AVSC_API(int, avs_get_pitch_p)(const AVS_VideoFrame * p, int plane); 679 | 680 | AVSC_API(int, avs_get_row_size_p)(const AVS_VideoFrame * p, int plane); 681 | 682 | AVSC_API(int, avs_get_height_p)(const AVS_VideoFrame * p, int plane); 683 | 684 | AVSC_API(const BYTE *, avs_get_read_ptr_p)(const AVS_VideoFrame * p, int plane); 685 | 686 | AVSC_API(int, avs_is_writable)(const AVS_VideoFrame * p); 687 | 688 | AVSC_API(BYTE *, avs_get_write_ptr_p)(const AVS_VideoFrame * p, int plane); 689 | 690 | AVSC_API(void, avs_release_video_frame)(AVS_VideoFrame *); 691 | // makes a shallow copy of a video frame 692 | AVSC_API(AVS_VideoFrame *, avs_copy_video_frame)(AVS_VideoFrame *); 693 | 694 | // no API for these, inline helper functions 695 | #ifndef AVSC_NO_DECLSPEC 696 | // this inline function is calling an API function 697 | AVSC_INLINE int avs_get_pitch(const AVS_VideoFrame * p) { 698 | return avs_get_pitch_p(p, 0); 699 | } 700 | #endif 701 | 702 | #ifndef AVSC_NO_DECLSPEC 703 | // this inline function is calling an API function 704 | AVSC_INLINE int avs_get_row_size(const AVS_VideoFrame * p) { 705 | return avs_get_row_size_p(p, 0); } 706 | #endif 707 | 708 | 709 | #ifndef AVSC_NO_DECLSPEC 710 | // this inline function is calling an API function 711 | AVSC_INLINE int avs_get_height(const AVS_VideoFrame * p) { 712 | return avs_get_height_p(p, 0); 713 | } 714 | #endif 715 | 716 | #ifndef AVSC_NO_DECLSPEC 717 | // this inline function is calling an API function 718 | AVSC_INLINE const BYTE* avs_get_read_ptr(const AVS_VideoFrame * p) { 719 | return avs_get_read_ptr_p(p, 0);} 720 | #endif 721 | 722 | #ifndef AVSC_NO_DECLSPEC 723 | // this inline function is calling an API function 724 | AVSC_INLINE BYTE* avs_get_write_ptr(const AVS_VideoFrame * p) { 725 | return avs_get_write_ptr_p(p, 0);} 726 | #endif 727 | 728 | #ifndef AVSC_NO_DECLSPEC 729 | // this inline function is calling an API function 730 | AVSC_INLINE void avs_release_frame(AVS_VideoFrame * f) 731 | {avs_release_video_frame(f);} 732 | #endif 733 | 734 | #ifndef AVSC_NO_DECLSPEC 735 | // this inline function is calling an API function 736 | AVSC_INLINE AVS_VideoFrame * avs_copy_frame(AVS_VideoFrame * f) 737 | {return avs_copy_video_frame(f);} 738 | #endif 739 | 740 | // Interface V8: frame properties 741 | // AVS_Map is just a placeholder for AVSMap 742 | typedef struct AVS_Map { 743 | void* data; 744 | } AVS_Map; 745 | 746 | 747 | ///////////////////////////////////////////////////////////////////// 748 | // 749 | // AVS_Value 750 | // 751 | 752 | // Treat AVS_Value as a fat pointer. That is use avs_copy_value 753 | // and avs_release_value appropriately as you would if AVS_Value was 754 | // a pointer. 755 | 756 | // To maintain source code compatibility with future versions of the 757 | // avisynth_c API don't use the AVS_Value directly. Use the helper 758 | // functions below. 759 | 760 | // AVS_Value is laid out identically to AVSValue 761 | typedef struct AVS_Value AVS_Value; 762 | struct AVS_Value { 763 | short type; // 'a'rray, 'c'lip, 'b'ool, 'i'nt, 'f'loat, 's'tring, 'v'oid, or 'l'ong, or fu'n'ction 764 | // for some function e'rror 765 | short array_size; 766 | union { 767 | void * clip; // do not use directly, use avs_take_clip 768 | char boolean; 769 | int integer; 770 | float floating_pt; 771 | const char * string; 772 | const AVS_Value * array; 773 | void * function; // not supported on C interface 774 | #ifdef X86_64 775 | // if ever, only x64 will support. It breaks struct size on 32 bit 776 | int64_t longlong; // 8 bytes 777 | double double_pt; // 8 bytes 778 | #endif 779 | } d; 780 | }; 781 | 782 | // AVS_Value should be initialized with avs_void. 783 | // Should also set to avs_void after the value is released 784 | // with avs_copy_value. Consider it the equivalent of setting 785 | // a pointer to NULL 786 | static const AVS_Value avs_void = {'v'}; 787 | 788 | AVSC_API(void, avs_copy_value)(AVS_Value * dest, AVS_Value src); 789 | AVSC_API(void, avs_release_value)(AVS_Value); 790 | AVSC_API(AVS_Clip *, avs_take_clip)(AVS_Value, AVS_ScriptEnvironment *); 791 | AVSC_API(void, avs_set_to_clip)(AVS_Value *, AVS_Clip *); 792 | 793 | 794 | // no API for these, inline helper functions 795 | AVSC_INLINE int avs_defined(AVS_Value v) { return v.type != 'v'; } 796 | AVSC_INLINE int avs_is_clip(AVS_Value v) { return v.type == 'c'; } 797 | AVSC_INLINE int avs_is_bool(AVS_Value v) { return v.type == 'b'; } 798 | AVSC_INLINE int avs_is_int(AVS_Value v) { return v.type == 'i'; } 799 | AVSC_INLINE int avs_is_float(AVS_Value v) { return v.type == 'f' || v.type == 'i'; } 800 | AVSC_INLINE int avs_is_string(AVS_Value v) { return v.type == 's'; } 801 | AVSC_INLINE int avs_is_array(AVS_Value v) { return v.type == 'a'; } 802 | AVSC_INLINE int avs_is_error(AVS_Value v) { return v.type == 'e'; } 803 | 804 | AVSC_INLINE int avs_as_bool(AVS_Value v) 805 | { return v.d.boolean; } 806 | AVSC_INLINE int avs_as_int(AVS_Value v) 807 | { return v.d.integer; } 808 | AVSC_INLINE const char * avs_as_string(AVS_Value v) 809 | { return avs_is_error(v) || avs_is_string(v) ? v.d.string : 0; } 810 | AVSC_INLINE double avs_as_float(AVS_Value v) 811 | { return avs_is_int(v) ? v.d.integer : v.d.floating_pt; } 812 | AVSC_INLINE const char * avs_as_error(AVS_Value v) 813 | { return avs_is_error(v) ? v.d.string : 0; } 814 | AVSC_INLINE const AVS_Value * avs_as_array(AVS_Value v) 815 | { return v.d.array; } 816 | AVSC_INLINE int avs_array_size(AVS_Value v) 817 | { return avs_is_array(v) ? v.array_size : 1; } 818 | AVSC_INLINE AVS_Value avs_array_elt(AVS_Value v, int index) 819 | { return avs_is_array(v) ? v.d.array[index] : v; } 820 | 821 | // only use these functions on an AVS_Value that does not already have 822 | // an active value. Remember, treat AVS_Value as a fat pointer. 823 | AVSC_INLINE AVS_Value avs_new_value_bool(int v0) 824 | { AVS_Value v; v.type = 'b'; v.d.boolean = v0 == 0 ? 0 : 1; return v; } 825 | AVSC_INLINE AVS_Value avs_new_value_int(int v0) 826 | { AVS_Value v; v.type = 'i'; v.d.integer = v0; return v; } 827 | AVSC_INLINE AVS_Value avs_new_value_string(const char * v0) 828 | { AVS_Value v; v.type = 's'; v.d.string = v0; return v; } 829 | AVSC_INLINE AVS_Value avs_new_value_float(float v0) 830 | { AVS_Value v; v.type = 'f'; v.d.floating_pt = v0; return v;} 831 | AVSC_INLINE AVS_Value avs_new_value_error(const char * v0) 832 | { AVS_Value v; v.type = 'e'; v.d.string = v0; return v; } 833 | #ifndef AVSC_NO_DECLSPEC 834 | // this inline function is calling an API function 835 | AVSC_INLINE AVS_Value avs_new_value_clip(AVS_Clip * v0) 836 | { AVS_Value v; avs_set_to_clip(&v, v0); return v; } 837 | #endif 838 | AVSC_INLINE AVS_Value avs_new_value_array(AVS_Value * v0, int size) 839 | { AVS_Value v; v.type = 'a'; v.d.array = v0; v.array_size = (short)size; return v; } 840 | // end of inline helper functions 841 | 842 | ///////////////////////////////////////////////////////////////////// 843 | // 844 | // AVS_Clip 845 | // 846 | 847 | AVSC_API(void, avs_release_clip)(AVS_Clip *); 848 | AVSC_API(AVS_Clip *, avs_copy_clip)(AVS_Clip *); 849 | 850 | AVSC_API(const char *, avs_clip_get_error)(AVS_Clip *); // return 0 if no error 851 | 852 | AVSC_API(const AVS_VideoInfo *, avs_get_video_info)(AVS_Clip *); 853 | 854 | AVSC_API(int, avs_get_version)(AVS_Clip *); 855 | 856 | AVSC_API(AVS_VideoFrame *, avs_get_frame)(AVS_Clip *, int n); 857 | // The returned video frame must be released with avs_release_video_frame 858 | 859 | AVSC_API(int, avs_get_parity)(AVS_Clip *, int n); 860 | // return field parity if field_based, else parity of first field in frame 861 | 862 | AVSC_API(int, avs_get_audio)(AVS_Clip *, void * buf, 863 | int64_t start, int64_t count); 864 | // start and count are in samples 865 | 866 | AVSC_API(int, avs_set_cache_hints)(AVS_Clip *, 867 | int cachehints, int frame_range); 868 | 869 | // This is the callback type used by avs_add_function 870 | typedef AVS_Value (AVSC_CC * AVS_ApplyFunc) 871 | (AVS_ScriptEnvironment *, AVS_Value args, void * user_data); 872 | 873 | typedef struct AVS_FilterInfo AVS_FilterInfo; 874 | struct AVS_FilterInfo 875 | { 876 | // these members should not be modified outside of the AVS_ApplyFunc callback 877 | AVS_Clip * child; 878 | AVS_VideoInfo vi; 879 | AVS_ScriptEnvironment * env; 880 | AVS_VideoFrame * (AVSC_CC * get_frame)(AVS_FilterInfo *, int n); 881 | int (AVSC_CC * get_parity)(AVS_FilterInfo *, int n); 882 | int (AVSC_CC * get_audio)(AVS_FilterInfo *, void * buf, 883 | int64_t start, int64_t count); 884 | int (AVSC_CC * set_cache_hints)(AVS_FilterInfo *, int cachehints, 885 | int frame_range); 886 | void (AVSC_CC * free_filter)(AVS_FilterInfo *); 887 | 888 | // Should be set when ever there is an error to report. 889 | // It is cleared before any of the above methods are called 890 | const char * error; 891 | // this is to store whatever and may be modified at will 892 | void * user_data; 893 | }; 894 | 895 | // Create a new filter 896 | // fi is set to point to the AVS_FilterInfo so that you can 897 | // modify it once it is initialized. 898 | // store_child should generally be set to true. If it is not 899 | // set than ALL methods (the function pointers) must be defined 900 | // If it is set than you do not need to worry about freeing the child 901 | // clip. 902 | AVSC_API(AVS_Clip *, avs_new_c_filter)(AVS_ScriptEnvironment * e, 903 | AVS_FilterInfo * * fi, 904 | AVS_Value child, int store_child); 905 | 906 | ///////////////////////////////////////////////////////////////////// 907 | // 908 | // AVS_ScriptEnvironment 909 | // 910 | 911 | // For GetCPUFlags. These are backwards-compatible with those in VirtualDub. 912 | enum { 913 | /* slowest CPU to support extension */ 914 | AVS_CPU_FORCE = 0x01, // N/A 915 | AVS_CPU_FPU = 0x02, // 386/486DX 916 | AVS_CPU_MMX = 0x04, // P55C, K6, PII 917 | AVS_CPU_INTEGER_SSE = 0x08, // PIII, Athlon 918 | AVS_CPU_SSE = 0x10, // PIII, Athlon XP/MP 919 | AVS_CPU_SSE2 = 0x20, // PIV, Hammer 920 | AVS_CPU_3DNOW = 0x40, // K6-2 921 | AVS_CPU_3DNOW_EXT = 0x80, // Athlon 922 | AVS_CPU_X86_64 = 0xA0, // Hammer (note: equiv. to 3DNow + SSE2, 923 | // which only Hammer will have anyway) 924 | AVS_CPUF_SSE3 = 0x100, // PIV+, K8 Venice 925 | AVS_CPUF_SSSE3 = 0x200, // Core 2 926 | AVS_CPUF_SSE4 = 0x400, // Penryn, Wolfdale, Yorkfield 927 | AVS_CPUF_SSE4_1 = 0x400, 928 | AVS_CPUF_AVX = 0x800, // Sandy Bridge, Bulldozer 929 | AVS_CPUF_SSE4_2 = 0x1000, // Nehalem 930 | // AVS+ 931 | AVS_CPUF_AVX2 = 0x2000, // Haswell 932 | AVS_CPUF_FMA3 = 0x4000, 933 | AVS_CPUF_F16C = 0x8000, 934 | AVS_CPUF_MOVBE = 0x10000, // Big Endian Move 935 | AVS_CPUF_POPCNT = 0x20000, 936 | AVS_CPUF_AES = 0x40000, 937 | AVS_CPUF_FMA4 = 0x80000, 938 | 939 | AVS_CPUF_AVX512F = 0x100000, // AVX-512 Foundation. 940 | AVS_CPUF_AVX512DQ = 0x200000, // AVX-512 DQ (Double/Quad granular) Instructions 941 | AVS_CPUF_AVX512PF = 0x400000, // AVX-512 Prefetch 942 | AVS_CPUF_AVX512ER = 0x800000, // AVX-512 Exponential and Reciprocal 943 | AVS_CPUF_AVX512CD = 0x1000000, // AVX-512 Conflict Detection 944 | AVS_CPUF_AVX512BW = 0x2000000, // AVX-512 BW (Byte/Word granular) Instructions 945 | AVS_CPUF_AVX512VL = 0x4000000, // AVX-512 VL (128/256 Vector Length) Extensions 946 | AVS_CPUF_AVX512IFMA = 0x8000000, // AVX-512 IFMA integer 52 bit 947 | AVS_CPUF_AVX512VBMI = 0x10000000 // AVX-512 VBMI 948 | }; 949 | 950 | 951 | AVSC_API(const char *, avs_get_error)(AVS_ScriptEnvironment *); // return 0 if no error 952 | 953 | AVSC_API(int, avs_get_cpu_flags)(AVS_ScriptEnvironment *); 954 | AVSC_API(int, avs_check_version)(AVS_ScriptEnvironment *, int version); 955 | 956 | AVSC_API(char *, avs_save_string)(AVS_ScriptEnvironment *, const char* s, int length); 957 | AVSC_API(char *, avs_sprintf)(AVS_ScriptEnvironment *, const char * fmt, ...); 958 | 959 | AVSC_API(char *, avs_vsprintf)(AVS_ScriptEnvironment *, const char * fmt, va_list val); 960 | 961 | AVSC_API(int, avs_add_function)(AVS_ScriptEnvironment *, 962 | const char * name, const char * params, 963 | AVS_ApplyFunc apply, void * user_data); 964 | 965 | AVSC_API(int, avs_function_exists)(AVS_ScriptEnvironment *, const char * name); 966 | 967 | AVSC_API(AVS_Value, avs_invoke)(AVS_ScriptEnvironment *, const char * name, 968 | AVS_Value args, const char** arg_names); 969 | // The returned value must be be released with avs_release_value 970 | 971 | AVSC_API(AVS_Value, avs_get_var)(AVS_ScriptEnvironment *, const char* name); 972 | // The returned value must be be released with avs_release_value 973 | 974 | AVSC_API(int, avs_set_var)(AVS_ScriptEnvironment *, const char* name, AVS_Value val); 975 | 976 | AVSC_API(int, avs_set_global_var)(AVS_ScriptEnvironment *, const char* name, const AVS_Value val); 977 | 978 | //void avs_push_context(AVS_ScriptEnvironment *, int level=0); 979 | //void avs_pop_context(AVS_ScriptEnvironment *); 980 | 981 | // partially deprecated, from V8 use avs_new_video_frame_p_a (frame property copy) 982 | AVSC_API(AVS_VideoFrame *, avs_new_video_frame_a)(AVS_ScriptEnvironment *, 983 | const AVS_VideoInfo * vi, int align); 984 | // align should be at least 16 for classic Avisynth 985 | // Avisynth+: any value, Avs+ ensures a minimum alignment if too small align is provided 986 | 987 | // no API for these, inline helper functions 988 | #ifndef AVSC_NO_DECLSPEC 989 | // partially deprecated, from V8 use avs_new_video_frame_p (frame property copy) 990 | // this inline function is calling an API function 991 | AVSC_INLINE AVS_VideoFrame * avs_new_video_frame(AVS_ScriptEnvironment * env, 992 | const AVS_VideoInfo * vi) 993 | {return avs_new_video_frame_a(env,vi,AVS_FRAME_ALIGN);} 994 | 995 | // an older compatibility alias 996 | // this inline function is calling an API function 997 | AVSC_INLINE AVS_VideoFrame * avs_new_frame(AVS_ScriptEnvironment * env, 998 | const AVS_VideoInfo * vi) 999 | {return avs_new_video_frame_a(env,vi,AVS_FRAME_ALIGN);} 1000 | #endif 1001 | // end of inline helper functions 1002 | 1003 | AVSC_API(int, avs_make_writable)(AVS_ScriptEnvironment *, AVS_VideoFrame * * pvf); 1004 | 1005 | AVSC_API(void, avs_bit_blt)(AVS_ScriptEnvironment *, BYTE* dstp, int dst_pitch, const BYTE* srcp, int src_pitch, int row_size, int height); 1006 | 1007 | typedef void (AVSC_CC *AVS_ShutdownFunc)(void* user_data, AVS_ScriptEnvironment * env); 1008 | AVSC_API(void, avs_at_exit)(AVS_ScriptEnvironment *, AVS_ShutdownFunc function, void * user_data); 1009 | 1010 | AVSC_API(AVS_VideoFrame *, avs_subframe)(AVS_ScriptEnvironment *, AVS_VideoFrame * src, int rel_offset, int new_pitch, int new_row_size, int new_height); 1011 | // The returned video frame must be be released 1012 | AVSC_API(AVS_VideoFrame*, avs_subframe_planar)(AVS_ScriptEnvironment*, AVS_VideoFrame* src, int rel_offset, int new_pitch, int new_row_size, int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV); 1013 | // The returned video frame must be be released 1014 | // see also avs_subframe_planar_a in interface V8 1015 | 1016 | AVSC_API(int, avs_set_memory_max)(AVS_ScriptEnvironment *, int mem); 1017 | 1018 | AVSC_API(int, avs_set_working_dir)(AVS_ScriptEnvironment *, const char * newdir); 1019 | 1020 | // avisynth.dll exports this; it's a way to use it as a library, without 1021 | // writing an AVS script or without going through AVIFile. 1022 | AVSC_API(AVS_ScriptEnvironment *, avs_create_script_environment)(int version); 1023 | 1024 | // this symbol is the entry point for the plugin and must 1025 | // be defined 1026 | AVSC_EXPORT 1027 | const char * AVSC_CC avisynth_c_plugin_init(AVS_ScriptEnvironment* env); 1028 | 1029 | 1030 | AVSC_API(void, avs_delete_script_environment)(AVS_ScriptEnvironment *); 1031 | 1032 | /////////////////////////////////////////////////////////////////////////////// 1033 | // 1034 | // Avisynth+ V8 interface elements 1035 | // 1036 | 1037 | AVSC_API(AVS_VideoFrame*, avs_subframe_planar_a)(AVS_ScriptEnvironment*, AVS_VideoFrame* src, int rel_offset, int new_pitch, int new_row_size, int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV, int rel_offsetA); 1038 | // The returned video frame must be be released 1039 | 1040 | AVSC_API(void, avs_copy_frame_props)(AVS_ScriptEnvironment* p, const AVS_VideoFrame* src, AVS_VideoFrame* dst); 1041 | AVSC_API(const AVS_Map*, avs_get_frame_props_ro)(AVS_ScriptEnvironment* p, const AVS_VideoFrame* frame); 1042 | AVSC_API(AVS_Map*, avs_get_frame_props_rw)(AVS_ScriptEnvironment* p, AVS_VideoFrame* frame); 1043 | AVSC_API(int, avs_prop_num_keys)(AVS_ScriptEnvironment* p, const AVS_Map* map); 1044 | AVSC_API(const char*, avs_prop_get_key)(AVS_ScriptEnvironment* p, const AVS_Map* map, int index); 1045 | AVSC_API(int, avs_prop_num_elements)(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key); 1046 | 1047 | // see AVS_PROPTYPE_... enums 1048 | AVSC_API(char, avs_prop_get_type)(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key); 1049 | 1050 | // see AVS_GETPROPERROR_... enums 1051 | AVSC_API(int64_t, avs_prop_get_int)(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key, int index, int* error); 1052 | AVSC_API(double, avs_prop_get_float)(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key, int index, int* error); 1053 | AVSC_API(const char*, avs_prop_get_data)(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key, int index, int* error); 1054 | AVSC_API(int, avs_prop_get_data_size)(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key, int index, int* error); 1055 | AVSC_API(AVS_Clip*, avs_prop_get_clip)(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key, int index, int* error); 1056 | AVSC_API(const AVS_VideoFrame*, avs_prop_get_frame)(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key, int index, int* error); 1057 | 1058 | AVSC_API(int, avs_prop_delete_key)(AVS_ScriptEnvironment* p, AVS_Map* map, const char* key); 1059 | 1060 | // see AVS_PROPAPPENDMODE_... enums 1061 | AVSC_API(int, avs_prop_set_int)(AVS_ScriptEnvironment* p, AVS_Map* map, const char* key, int64_t i, int append); 1062 | AVSC_API(int, avs_prop_set_float)(AVS_ScriptEnvironment* p, AVS_Map* map, const char* key, double d, int append); 1063 | AVSC_API(int, avs_prop_set_data)(AVS_ScriptEnvironment* p, AVS_Map* map, const char* key, const char* d, int length, int append); 1064 | AVSC_API(int, avs_prop_set_clip)(AVS_ScriptEnvironment* p, AVS_Map* map, const char* key, AVS_Clip* clip, int append); 1065 | AVSC_API(int, avs_prop_set_frame)(AVS_ScriptEnvironment* p, AVS_Map* map, const char* key, const AVS_VideoFrame* frame, int append); 1066 | 1067 | AVSC_API(const int64_t*, avs_prop_get_int_array)(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key, int* error); 1068 | AVSC_API(const double*, avs_prop_get_float_array)(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key, int* error); 1069 | AVSC_API(int, avs_prop_set_int_array)(AVS_ScriptEnvironment* p, AVS_Map* map, const char* key, const int64_t* i, int size); 1070 | AVSC_API(int, avs_prop_set_float_array)(AVS_ScriptEnvironment* p, AVS_Map* map, const char* key, const double* d, int size); 1071 | 1072 | AVSC_API(void, avs_clear_map)(AVS_ScriptEnvironment* p, AVS_Map* map); 1073 | 1074 | // with frame property source 1075 | AVSC_API(AVS_VideoFrame*, avs_new_video_frame_p)(AVS_ScriptEnvironment*, 1076 | const AVS_VideoInfo* vi, AVS_VideoFrame* propSrc); 1077 | 1078 | // with frame property source 1079 | AVSC_API(AVS_VideoFrame*, avs_new_video_frame_p_a)(AVS_ScriptEnvironment*, 1080 | const AVS_VideoInfo* vi, AVS_VideoFrame* propSrc, int align); 1081 | 1082 | // Generic query to ask for various system properties, see AVS_AEP_xxx enums 1083 | AVSC_API(size_t, avs_get_env_property)(AVS_ScriptEnvironment*, int avs_aep_prop); 1084 | 1085 | // buffer pool, see AVS_ALLOCTYPE enums 1086 | AVSC_API(void *, avs_pool_allocate)(AVS_ScriptEnvironment*, size_t nBytes, size_t alignment, int avs_alloc_type); 1087 | AVSC_API(void, avs_pool_free)(AVS_ScriptEnvironment*, void *ptr); 1088 | 1089 | // Interface V8 1090 | // Returns TRUE (1) and the requested variable. If the method fails, returns 0 (FALSE) and does not touch 'val'. 1091 | // The returned AVS_Value *val value must be be released with avs_release_value only on success 1092 | // AVS_Value *val is not caller allocated 1093 | AVSC_API(int, avs_get_var_try)(AVS_ScriptEnvironment*, const char* name, AVS_Value* val); 1094 | 1095 | // Interface V8 1096 | // Return the value of the requested variable. 1097 | // If the variable was not found or had the wrong type, 1098 | // return the supplied default value. 1099 | AVSC_API(int, avs_get_var_bool)(AVS_ScriptEnvironment*, const char* name, int def); 1100 | AVSC_API(int, avs_get_var_int)(AVS_ScriptEnvironment*, const char* name, int def); 1101 | AVSC_API(double, avs_get_var_double)(AVS_ScriptEnvironment*, const char* name, double def); 1102 | AVSC_API(const char*, avs_get_var_string)(AVS_ScriptEnvironment*, const char* name, const char* def); 1103 | AVSC_API(int64_t, avs_get_var_long)(AVS_ScriptEnvironment*, const char* name, int64_t def); 1104 | 1105 | #if defined(AVS_WINDOWS) 1106 | // The following stuff is only relevant for Windows DLL handling; Linux does it completely differently. 1107 | #ifdef AVSC_NO_DECLSPEC 1108 | // This part uses LoadLibrary and related functions to dynamically load Avisynth instead of declspec(dllimport) 1109 | // When AVSC_NO_DECLSPEC is defined, you can use avs_load_library to populate API functions into a struct 1110 | // AVSC_INLINE functions which call onto an API functions should be treated specially (todo) 1111 | 1112 | /* 1113 | The following functions needs to have been declared, probably from windows.h 1114 | 1115 | void* malloc(size_t) 1116 | void free(void*); 1117 | 1118 | HMODULE LoadLibraryA(const char*); 1119 | void* GetProcAddress(HMODULE, const char*); 1120 | FreeLibrary(HMODULE); 1121 | */ 1122 | 1123 | 1124 | typedef struct AVS_Library AVS_Library; 1125 | 1126 | #define AVSC_DECLARE_FUNC(name) name##_func name 1127 | 1128 | // AVSC_DECLARE_FUNC helps keeping naming convention: type is xxxxx_func, function name is xxxxx 1129 | // e.g. "AVSC_DECLARE_FUNC(avs_add_function);" 1130 | // is a shortcut for "avs_add_function_func avs_add_function;" 1131 | 1132 | // Note: AVSC_INLINE functions which call into API, 1133 | // are guarded by #ifndef AVSC_NO_DECLSPEC 1134 | // They should call the appropriate library-> API entry 1135 | 1136 | struct AVS_Library { 1137 | HMODULE handle; 1138 | 1139 | AVSC_DECLARE_FUNC(avs_add_function); 1140 | AVSC_DECLARE_FUNC(avs_at_exit); 1141 | AVSC_DECLARE_FUNC(avs_bit_blt); 1142 | AVSC_DECLARE_FUNC(avs_check_version); 1143 | AVSC_DECLARE_FUNC(avs_clip_get_error); 1144 | AVSC_DECLARE_FUNC(avs_copy_clip); 1145 | AVSC_DECLARE_FUNC(avs_copy_value); 1146 | AVSC_DECLARE_FUNC(avs_copy_video_frame); 1147 | AVSC_DECLARE_FUNC(avs_create_script_environment); 1148 | AVSC_DECLARE_FUNC(avs_delete_script_environment); 1149 | AVSC_DECLARE_FUNC(avs_function_exists); 1150 | AVSC_DECLARE_FUNC(avs_get_audio); 1151 | AVSC_DECLARE_FUNC(avs_get_cpu_flags); 1152 | AVSC_DECLARE_FUNC(avs_get_frame); 1153 | AVSC_DECLARE_FUNC(avs_get_parity); 1154 | AVSC_DECLARE_FUNC(avs_get_var); 1155 | AVSC_DECLARE_FUNC(avs_get_version); 1156 | AVSC_DECLARE_FUNC(avs_get_video_info); 1157 | AVSC_DECLARE_FUNC(avs_invoke); 1158 | AVSC_DECLARE_FUNC(avs_make_writable); 1159 | AVSC_DECLARE_FUNC(avs_new_c_filter); 1160 | AVSC_DECLARE_FUNC(avs_new_video_frame_a); 1161 | AVSC_DECLARE_FUNC(avs_release_clip); 1162 | AVSC_DECLARE_FUNC(avs_release_value); 1163 | AVSC_DECLARE_FUNC(avs_release_video_frame); 1164 | AVSC_DECLARE_FUNC(avs_save_string); 1165 | AVSC_DECLARE_FUNC(avs_set_cache_hints); 1166 | AVSC_DECLARE_FUNC(avs_set_global_var); 1167 | AVSC_DECLARE_FUNC(avs_set_memory_max); 1168 | AVSC_DECLARE_FUNC(avs_set_to_clip); 1169 | AVSC_DECLARE_FUNC(avs_set_var); 1170 | AVSC_DECLARE_FUNC(avs_set_working_dir); 1171 | AVSC_DECLARE_FUNC(avs_sprintf); 1172 | AVSC_DECLARE_FUNC(avs_subframe); 1173 | AVSC_DECLARE_FUNC(avs_subframe_planar); 1174 | AVSC_DECLARE_FUNC(avs_take_clip); 1175 | AVSC_DECLARE_FUNC(avs_vsprintf); 1176 | 1177 | AVSC_DECLARE_FUNC(avs_get_error); 1178 | AVSC_DECLARE_FUNC(avs_is_yv24); 1179 | AVSC_DECLARE_FUNC(avs_is_yv16); 1180 | AVSC_DECLARE_FUNC(avs_is_yv12); 1181 | AVSC_DECLARE_FUNC(avs_is_yv411); 1182 | AVSC_DECLARE_FUNC(avs_is_y8); 1183 | AVSC_DECLARE_FUNC(avs_is_color_space); 1184 | 1185 | AVSC_DECLARE_FUNC(avs_get_plane_width_subsampling); 1186 | AVSC_DECLARE_FUNC(avs_get_plane_height_subsampling); 1187 | AVSC_DECLARE_FUNC(avs_bits_per_pixel); 1188 | AVSC_DECLARE_FUNC(avs_bytes_from_pixels); 1189 | AVSC_DECLARE_FUNC(avs_row_size); 1190 | AVSC_DECLARE_FUNC(avs_bmp_size); 1191 | AVSC_DECLARE_FUNC(avs_get_pitch_p); 1192 | AVSC_DECLARE_FUNC(avs_get_row_size_p); 1193 | AVSC_DECLARE_FUNC(avs_get_height_p); 1194 | AVSC_DECLARE_FUNC(avs_get_read_ptr_p); 1195 | AVSC_DECLARE_FUNC(avs_is_writable); 1196 | AVSC_DECLARE_FUNC(avs_get_write_ptr_p); 1197 | 1198 | // Avisynth+ specific 1199 | // Note: these functions are simulated/use fallback to existing functions 1200 | AVSC_DECLARE_FUNC(avs_is_rgb48); 1201 | AVSC_DECLARE_FUNC(avs_is_rgb64); 1202 | AVSC_DECLARE_FUNC(avs_is_yuv444p16); 1203 | AVSC_DECLARE_FUNC(avs_is_yuv422p16); 1204 | AVSC_DECLARE_FUNC(avs_is_yuv420p16); 1205 | AVSC_DECLARE_FUNC(avs_is_y16); 1206 | AVSC_DECLARE_FUNC(avs_is_yuv444ps); 1207 | AVSC_DECLARE_FUNC(avs_is_yuv422ps); 1208 | AVSC_DECLARE_FUNC(avs_is_yuv420ps); 1209 | AVSC_DECLARE_FUNC(avs_is_y32); 1210 | AVSC_DECLARE_FUNC(avs_is_444); 1211 | AVSC_DECLARE_FUNC(avs_is_422); 1212 | AVSC_DECLARE_FUNC(avs_is_420); 1213 | AVSC_DECLARE_FUNC(avs_is_y); 1214 | AVSC_DECLARE_FUNC(avs_is_yuva); 1215 | AVSC_DECLARE_FUNC(avs_is_planar_rgb); 1216 | AVSC_DECLARE_FUNC(avs_is_planar_rgba); 1217 | AVSC_DECLARE_FUNC(avs_num_components); 1218 | AVSC_DECLARE_FUNC(avs_component_size); 1219 | AVSC_DECLARE_FUNC(avs_bits_per_component); 1220 | 1221 | /////////////////////////////////////////////////////////////////////////////// 1222 | // Avisynth+ new interface elements from interface version 8 1223 | // avs_subframe_planar with alpha support 1224 | AVSC_DECLARE_FUNC(avs_subframe_planar_a); 1225 | 1226 | // frame properties 1227 | AVSC_DECLARE_FUNC(avs_copy_frame_props); 1228 | AVSC_DECLARE_FUNC(avs_get_frame_props_ro); 1229 | AVSC_DECLARE_FUNC(avs_get_frame_props_rw); 1230 | AVSC_DECLARE_FUNC(avs_prop_num_keys); 1231 | AVSC_DECLARE_FUNC(avs_prop_get_key); 1232 | AVSC_DECLARE_FUNC(avs_prop_num_elements); 1233 | AVSC_DECLARE_FUNC(avs_prop_get_type); 1234 | AVSC_DECLARE_FUNC(avs_prop_get_int); 1235 | AVSC_DECLARE_FUNC(avs_prop_get_float); 1236 | AVSC_DECLARE_FUNC(avs_prop_get_data); 1237 | AVSC_DECLARE_FUNC(avs_prop_get_data_size); 1238 | AVSC_DECLARE_FUNC(avs_prop_get_clip); 1239 | AVSC_DECLARE_FUNC(avs_prop_get_frame); 1240 | AVSC_DECLARE_FUNC(avs_prop_delete_key); 1241 | AVSC_DECLARE_FUNC(avs_prop_set_int); 1242 | AVSC_DECLARE_FUNC(avs_prop_set_float); 1243 | AVSC_DECLARE_FUNC(avs_prop_set_data); 1244 | AVSC_DECLARE_FUNC(avs_prop_set_clip); 1245 | AVSC_DECLARE_FUNC(avs_prop_set_frame); 1246 | 1247 | AVSC_DECLARE_FUNC(avs_prop_get_int_array); 1248 | AVSC_DECLARE_FUNC(avs_prop_get_float_array); 1249 | AVSC_DECLARE_FUNC(avs_prop_set_int_array); 1250 | AVSC_DECLARE_FUNC(avs_prop_set_float_array); 1251 | 1252 | AVSC_DECLARE_FUNC(avs_clear_map); 1253 | 1254 | // NewVideoFrame with frame properties 1255 | AVSC_DECLARE_FUNC(avs_new_video_frame_p); 1256 | AVSC_DECLARE_FUNC(avs_new_video_frame_p_a); 1257 | 1258 | AVSC_DECLARE_FUNC(avs_get_env_property); 1259 | 1260 | AVSC_DECLARE_FUNC(avs_get_var_try); 1261 | AVSC_DECLARE_FUNC(avs_get_var_bool); 1262 | AVSC_DECLARE_FUNC(avs_get_var_int); 1263 | AVSC_DECLARE_FUNC(avs_get_var_double); 1264 | AVSC_DECLARE_FUNC(avs_get_var_string); 1265 | AVSC_DECLARE_FUNC(avs_get_var_long); 1266 | 1267 | AVSC_DECLARE_FUNC(avs_pool_allocate); 1268 | AVSC_DECLARE_FUNC(avs_pool_free); 1269 | }; 1270 | 1271 | #undef AVSC_DECLARE_FUNC 1272 | 1273 | #ifdef AVS26_FALLBACK_SIMULATION 1274 | // Helper functions for fallback simulation 1275 | // Avisynth+ extensions do not exist in classic Avisynth so they are simulated 1276 | AVSC_INLINE int avs_is_xx_fallback_return_false(const AVS_VideoInfo * p) 1277 | { 1278 | return 0; 1279 | } 1280 | 1281 | // Avisynth+ extensions do not exist in classic Avisynth so they are simulated 1282 | AVSC_INLINE int avs_num_components_fallback(const AVS_VideoInfo * p) 1283 | { 1284 | switch (p->pixel_type) { 1285 | case AVS_CS_UNKNOWN: 1286 | return 0; 1287 | case AVS_CS_RAW32: 1288 | case AVS_CS_Y8: 1289 | return 1; 1290 | case AVS_CS_BGR32: 1291 | return 4; // not planar but return the count 1292 | default: 1293 | return 3; 1294 | } 1295 | } 1296 | 1297 | // Avisynth+ extensions do not exist in classic Avisynth so they are simulated 1298 | AVSC_INLINE int avs_component_size_fallback(const AVS_VideoInfo * p) 1299 | { 1300 | return 1; 1301 | } 1302 | 1303 | // Avisynth+ extensions do not exist in classic Avisynth so they are simulated 1304 | AVSC_INLINE int avs_bits_per_component_fallback(const AVS_VideoInfo * p) 1305 | { 1306 | return 8; 1307 | } 1308 | // End of helper functions for fallback simulation 1309 | #endif // AVS26_FALLBACK_SIMULATION 1310 | 1311 | // avs_load_library() allocates an array for API procedure entries 1312 | // reads and fills the entries with live procedure addresses. 1313 | // AVSC_INLINE helpers which are calling into API procedures are not treated here (todo) 1314 | 1315 | AVSC_INLINE AVS_Library * avs_load_library() { 1316 | AVS_Library *library = (AVS_Library *)malloc(sizeof(AVS_Library)); 1317 | if (library == NULL) 1318 | return NULL; 1319 | library->handle = LoadLibraryA("avisynth"); 1320 | if (library->handle == NULL) 1321 | goto fail; 1322 | 1323 | #define __AVSC_STRINGIFY(x) #x 1324 | #define AVSC_STRINGIFY(x) __AVSC_STRINGIFY(x) 1325 | #define AVSC_LOAD_FUNC(name) {\ 1326 | library->name = (name##_func) GetProcAddress(library->handle, AVSC_STRINGIFY(name));\ 1327 | if (library->name == NULL)\ 1328 | goto fail;\ 1329 | } 1330 | 1331 | #ifdef AVS26_FALLBACK_SIMULATION 1332 | // When an API function is not loadable, let's try a replacement 1333 | // Missing Avisynth+ functions will be substituted with classic Avisynth compatible methods 1334 | /* 1335 | Avisynth+ When method is missing (classic Avisynth) 1336 | avs_is_rgb48 constant false 1337 | avs_is_rgb64 constant false 1338 | avs_is_444 avs_is_yv24 1339 | avs_is_422 avs_is_yv16 1340 | avs_is_420 avs_is_yv12 1341 | avs_is_y avs_is_y8 1342 | avs_is_yuva constant false 1343 | avs_is_planar_rgb constant false 1344 | avs_is_planar_rgba constant false 1345 | avs_num_components special: avs_num_components_fake Y8:1 RGB32:4 else 3 1346 | avs_component_size constant 1 (1 bytes/component) 1347 | avs_bits_per_component constant 8 (8 bits/component) 1348 | */ 1349 | 1350 | // try to load an alternative function 1351 | #define AVSC_LOAD_FUNC_FALLBACK(name,name2) {\ 1352 | library->name = (name##_func) GetProcAddress(library->handle, AVSC_STRINGIFY(name));\ 1353 | if (library->name == NULL)\ 1354 | library->name = (name##_func) GetProcAddress(library->handle, AVSC_STRINGIFY(name2));\ 1355 | if (library->name == NULL)\ 1356 | goto fail;\ 1357 | } 1358 | 1359 | // try to assign a replacement function 1360 | #define AVSC_LOAD_FUNC_FALLBACK_SIMULATED(name,name2) {\ 1361 | library->name = (name##_func) GetProcAddress(library->handle, AVSC_STRINGIFY(name));\ 1362 | if (library->name == NULL)\ 1363 | library->name = name2;\ 1364 | if (library->name == NULL)\ 1365 | goto fail;\ 1366 | } 1367 | #endif // AVS26_FALLBACK_SIMULATION 1368 | 1369 | AVSC_LOAD_FUNC(avs_add_function); 1370 | AVSC_LOAD_FUNC(avs_at_exit); 1371 | AVSC_LOAD_FUNC(avs_bit_blt); 1372 | AVSC_LOAD_FUNC(avs_check_version); 1373 | AVSC_LOAD_FUNC(avs_clip_get_error); 1374 | AVSC_LOAD_FUNC(avs_copy_clip); 1375 | AVSC_LOAD_FUNC(avs_copy_value); 1376 | AVSC_LOAD_FUNC(avs_copy_video_frame); 1377 | AVSC_LOAD_FUNC(avs_create_script_environment); 1378 | AVSC_LOAD_FUNC(avs_delete_script_environment); 1379 | AVSC_LOAD_FUNC(avs_function_exists); 1380 | AVSC_LOAD_FUNC(avs_get_audio); 1381 | AVSC_LOAD_FUNC(avs_get_cpu_flags); 1382 | AVSC_LOAD_FUNC(avs_get_frame); 1383 | AVSC_LOAD_FUNC(avs_get_parity); 1384 | AVSC_LOAD_FUNC(avs_get_var); 1385 | AVSC_LOAD_FUNC(avs_get_version); 1386 | AVSC_LOAD_FUNC(avs_get_video_info); 1387 | AVSC_LOAD_FUNC(avs_invoke); 1388 | AVSC_LOAD_FUNC(avs_make_writable); 1389 | AVSC_LOAD_FUNC(avs_new_c_filter); 1390 | AVSC_LOAD_FUNC(avs_new_video_frame_a); 1391 | 1392 | 1393 | 1394 | AVSC_LOAD_FUNC(avs_release_clip); 1395 | AVSC_LOAD_FUNC(avs_release_value); 1396 | AVSC_LOAD_FUNC(avs_release_video_frame); 1397 | AVSC_LOAD_FUNC(avs_save_string); 1398 | AVSC_LOAD_FUNC(avs_set_cache_hints); 1399 | AVSC_LOAD_FUNC(avs_set_global_var); 1400 | AVSC_LOAD_FUNC(avs_set_memory_max); 1401 | AVSC_LOAD_FUNC(avs_set_to_clip); 1402 | AVSC_LOAD_FUNC(avs_set_var); 1403 | AVSC_LOAD_FUNC(avs_set_working_dir); 1404 | AVSC_LOAD_FUNC(avs_sprintf); 1405 | AVSC_LOAD_FUNC(avs_subframe); 1406 | AVSC_LOAD_FUNC(avs_subframe_planar); 1407 | AVSC_LOAD_FUNC(avs_take_clip); 1408 | AVSC_LOAD_FUNC(avs_vsprintf); 1409 | 1410 | AVSC_LOAD_FUNC(avs_get_error); 1411 | AVSC_LOAD_FUNC(avs_is_yv24); 1412 | AVSC_LOAD_FUNC(avs_is_yv16); 1413 | AVSC_LOAD_FUNC(avs_is_yv12); 1414 | AVSC_LOAD_FUNC(avs_is_yv411); 1415 | AVSC_LOAD_FUNC(avs_is_y8); 1416 | AVSC_LOAD_FUNC(avs_is_color_space); 1417 | 1418 | AVSC_LOAD_FUNC(avs_get_plane_width_subsampling); 1419 | AVSC_LOAD_FUNC(avs_get_plane_height_subsampling); 1420 | AVSC_LOAD_FUNC(avs_bits_per_pixel); 1421 | AVSC_LOAD_FUNC(avs_bytes_from_pixels); 1422 | AVSC_LOAD_FUNC(avs_row_size); 1423 | AVSC_LOAD_FUNC(avs_bmp_size); 1424 | AVSC_LOAD_FUNC(avs_get_pitch_p); 1425 | AVSC_LOAD_FUNC(avs_get_row_size_p); 1426 | AVSC_LOAD_FUNC(avs_get_height_p); 1427 | AVSC_LOAD_FUNC(avs_get_read_ptr_p); 1428 | AVSC_LOAD_FUNC(avs_is_writable); 1429 | AVSC_LOAD_FUNC(avs_get_write_ptr_p); 1430 | 1431 | // Avisynth+ specific 1432 | #ifdef AVS26_FALLBACK_SIMULATION 1433 | // replace with fallback fn when does not exist 1434 | AVSC_LOAD_FUNC_FALLBACK_SIMULATED(avs_is_rgb48, avs_is_xx_fallback_return_false); 1435 | AVSC_LOAD_FUNC_FALLBACK_SIMULATED(avs_is_rgb64, avs_is_xx_fallback_return_false); 1436 | AVSC_LOAD_FUNC_FALLBACK(avs_is_444, avs_is_yv24); 1437 | AVSC_LOAD_FUNC_FALLBACK(avs_is_422, avs_is_yv16); 1438 | AVSC_LOAD_FUNC_FALLBACK(avs_is_420, avs_is_yv12); 1439 | AVSC_LOAD_FUNC_FALLBACK(avs_is_y, avs_is_y8); 1440 | AVSC_LOAD_FUNC_FALLBACK_SIMULATED(avs_is_yuva, avs_is_xx_fallback_return_false); 1441 | AVSC_LOAD_FUNC_FALLBACK_SIMULATED(avs_is_planar_rgb, avs_is_xx_fallback_return_false); 1442 | AVSC_LOAD_FUNC_FALLBACK_SIMULATED(avs_is_planar_rgba, avs_is_xx_fallback_return_false); 1443 | AVSC_LOAD_FUNC_FALLBACK_SIMULATED(avs_num_components, avs_num_components_fallback); 1444 | AVSC_LOAD_FUNC_FALLBACK_SIMULATED(avs_component_size, avs_component_size_fallback); 1445 | AVSC_LOAD_FUNC_FALLBACK_SIMULATED(avs_bits_per_component, avs_bits_per_component_fallback); 1446 | #else 1447 | // Avisynth+ specific 1448 | AVSC_LOAD_FUNC(avs_is_rgb48); 1449 | AVSC_LOAD_FUNC(avs_is_rgb64); 1450 | AVSC_LOAD_FUNC(avs_is_444); 1451 | AVSC_LOAD_FUNC(avs_is_422); 1452 | AVSC_LOAD_FUNC(avs_is_420); 1453 | AVSC_LOAD_FUNC(avs_is_y); 1454 | AVSC_LOAD_FUNC(avs_is_yuva); 1455 | AVSC_LOAD_FUNC(avs_is_planar_rgb); 1456 | AVSC_LOAD_FUNC(avs_is_planar_rgba); 1457 | AVSC_LOAD_FUNC(avs_num_components); 1458 | AVSC_LOAD_FUNC(avs_component_size); 1459 | AVSC_LOAD_FUNC(avs_bits_per_component); 1460 | #endif 1461 | // Avisynth+ interface V8, no backward compatible simulation 1462 | AVSC_LOAD_FUNC(avs_subframe_planar_a); 1463 | // frame properties 1464 | AVSC_LOAD_FUNC(avs_copy_frame_props); 1465 | AVSC_LOAD_FUNC(avs_get_frame_props_ro); 1466 | AVSC_LOAD_FUNC(avs_get_frame_props_rw); 1467 | AVSC_LOAD_FUNC(avs_prop_num_keys); 1468 | AVSC_LOAD_FUNC(avs_prop_get_key); 1469 | AVSC_LOAD_FUNC(avs_prop_num_elements); 1470 | AVSC_LOAD_FUNC(avs_prop_get_type); 1471 | AVSC_LOAD_FUNC(avs_prop_get_int); 1472 | AVSC_LOAD_FUNC(avs_prop_get_float); 1473 | AVSC_LOAD_FUNC(avs_prop_get_data); 1474 | AVSC_LOAD_FUNC(avs_prop_get_data_size); 1475 | AVSC_LOAD_FUNC(avs_prop_get_clip); 1476 | AVSC_LOAD_FUNC(avs_prop_get_frame); 1477 | AVSC_LOAD_FUNC(avs_prop_delete_key); 1478 | AVSC_LOAD_FUNC(avs_prop_set_int); 1479 | AVSC_LOAD_FUNC(avs_prop_set_float); 1480 | AVSC_LOAD_FUNC(avs_prop_set_data); 1481 | AVSC_LOAD_FUNC(avs_prop_set_clip); 1482 | AVSC_LOAD_FUNC(avs_prop_set_frame); 1483 | 1484 | AVSC_LOAD_FUNC(avs_prop_get_int_array); 1485 | AVSC_LOAD_FUNC(avs_prop_get_float_array); 1486 | AVSC_LOAD_FUNC(avs_prop_set_int_array); 1487 | AVSC_LOAD_FUNC(avs_prop_set_float_array); 1488 | 1489 | AVSC_LOAD_FUNC(avs_clear_map); 1490 | 1491 | // NewVideoFrame with frame properties 1492 | AVSC_LOAD_FUNC(avs_new_video_frame_p); 1493 | AVSC_LOAD_FUNC(avs_new_video_frame_p_a); 1494 | 1495 | AVSC_LOAD_FUNC(avs_get_env_property); 1496 | 1497 | AVSC_LOAD_FUNC(avs_get_var_try); 1498 | AVSC_LOAD_FUNC(avs_get_var_bool); 1499 | AVSC_LOAD_FUNC(avs_get_var_int); 1500 | AVSC_LOAD_FUNC(avs_get_var_double); 1501 | AVSC_LOAD_FUNC(avs_get_var_string); 1502 | AVSC_LOAD_FUNC(avs_get_var_long); 1503 | 1504 | AVSC_LOAD_FUNC(avs_pool_allocate); 1505 | AVSC_LOAD_FUNC(avs_pool_free); 1506 | 1507 | #undef __AVSC_STRINGIFY 1508 | #undef AVSC_STRINGIFY 1509 | #undef AVSC_LOAD_FUNC 1510 | #undef AVSC_LOAD_FUNC_FALLBACK 1511 | #undef AVSC_LOAD_FUNC_FALLBACK_SIMULATED 1512 | 1513 | return library; 1514 | 1515 | fail: 1516 | free(library); 1517 | return NULL; 1518 | } 1519 | 1520 | AVSC_INLINE void avs_free_library(AVS_Library *library) { 1521 | if (library == NULL) 1522 | return; 1523 | FreeLibrary(library->handle); 1524 | free(library); 1525 | } 1526 | #endif 1527 | 1528 | #endif // AVS_WINDOWS 1529 | 1530 | #endif 1531 | -------------------------------------------------------------------------------- /src/include/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 | # define AVSC_EXPORT __declspec(dllexport) 98 | # define AVSC_API(ret, name) EXTERN_C AVSC_EXPORT ret AVSC_CC name 99 | #else 100 | # define AVSC_EXPORT EXTERN_C 101 | # define AVSC_API(ret, name) EXTERN_C ret AVSC_CC name 102 | #endif 103 | #else 104 | # define AVSC_EXPORT EXTERN_C __declspec(dllexport) 105 | # ifndef AVSC_NO_DECLSPEC 106 | # define AVSC_API(ret, name) EXTERN_C __declspec(dllimport) ret AVSC_CC name 107 | # else 108 | # define AVSC_API(ret, name) typedef ret (AVSC_CC *name##_func) 109 | # endif 110 | #endif 111 | 112 | #endif //AVS_CAPI_H 113 | -------------------------------------------------------------------------------- /src/include/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 | #else 61 | # error Unsupported CPU architecture. 62 | #endif 63 | 64 | // VC++ LLVM-Clang-cl MinGW-Gnu 65 | // MSVC x x 66 | // MSVC_PURE x 67 | // CLANG x 68 | // GCC x 69 | 70 | #if defined(__clang__) 71 | // Check clang first. clang-cl also defines __MSC_VER 72 | // We set MSVC because they are mostly compatible 73 | # define CLANG 74 | #if defined(_MSC_VER) 75 | # define MSVC 76 | # define AVS_FORCEINLINE __attribute__((always_inline)) 77 | #else 78 | # define AVS_FORCEINLINE __attribute__((always_inline)) inline 79 | #endif 80 | #elif defined(_MSC_VER) 81 | # define MSVC 82 | # define MSVC_PURE 83 | # define AVS_FORCEINLINE __forceinline 84 | #elif defined(__GNUC__) 85 | # define GCC 86 | # define AVS_FORCEINLINE __attribute__((always_inline)) inline 87 | #else 88 | # error Unsupported compiler. 89 | # define AVS_FORCEINLINE inline 90 | # undef __forceinline 91 | # define __forceinline inline 92 | #endif 93 | 94 | #if defined(_WIN32) 95 | # define AVS_WINDOWS 96 | #elif defined(__linux__) 97 | # define AVS_LINUX 98 | # define AVS_POSIX 99 | #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) 100 | # define AVS_BSD 101 | # define AVS_POSIX 102 | #elif defined(__APPLE__) 103 | # define AVS_MACOS 104 | # define AVS_POSIX 105 | #elif defined(__HAIKU__) 106 | # define AVS_HAIKU 107 | # define AVS_POSIX 108 | #else 109 | # error Operating system unsupported. 110 | #endif 111 | 112 | // useful warnings disabler macros for supported compilers 113 | 114 | #if defined(_MSC_VER) 115 | #define DISABLE_WARNING_PUSH __pragma(warning( push )) 116 | #define DISABLE_WARNING_POP __pragma(warning( pop )) 117 | #define DISABLE_WARNING(warningNumber) __pragma(warning( disable : warningNumber )) 118 | 119 | #define DISABLE_WARNING_UNREFERENCED_LOCAL_VARIABLE DISABLE_WARNING(4101) 120 | #define DISABLE_WARNING_UNREFERENCED_FUNCTION DISABLE_WARNING(4505) 121 | // other warnings you want to deactivate... 122 | 123 | #elif defined(__GNUC__) || defined(__clang__) 124 | #define DO_PRAGMA(X) _Pragma(#X) 125 | #define DISABLE_WARNING_PUSH DO_PRAGMA(GCC diagnostic push) 126 | #define DISABLE_WARNING_POP DO_PRAGMA(GCC diagnostic pop) 127 | #define DISABLE_WARNING(warningName) DO_PRAGMA(GCC diagnostic ignored #warningName) 128 | 129 | #define DISABLE_WARNING_UNREFERENCED_LOCAL_VARIABLE DISABLE_WARNING(-Wunused-variable) 130 | #define DISABLE_WARNING_UNREFERENCED_FUNCTION DISABLE_WARNING(-Wunused-function) 131 | // other warnings you want to deactivate... 132 | 133 | #else 134 | #define DISABLE_WARNING_PUSH 135 | #define DISABLE_WARNING_POP 136 | #define DISABLE_WARNING_UNREFERENCED_LOCAL_VARIABLE 137 | #define DISABLE_WARNING_UNREFERENCED_FUNCTION 138 | // other warnings you want to deactivate... 139 | 140 | #endif 141 | 142 | #if defined(AVS_POSIX) 143 | #define NEW_AVSVALUE 144 | #else 145 | #define NEW_AVSVALUE 146 | #endif 147 | 148 | #if defined(AVS_WINDOWS) 149 | // Windows XP does not have proper initialization for 150 | // thread local variables. 151 | // Use workaround instead __declspec(thread) 152 | #define XP_TLS 153 | #endif 154 | 155 | #endif //AVS_CONFIG_H 156 | -------------------------------------------------------------------------------- /src/include/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 | -------------------------------------------------------------------------------- /src/render.c: -------------------------------------------------------------------------------- 1 | #include "render.h" 2 | 3 | // Kg is not parameter, calculated from Kr and Kb 4 | static void BuildMatrix(ConversionMatrix* matrix, double Kr, double Kb, int shift, int full_scale, int bits_per_pixel) 5 | { 6 | int Sy, Suv, Oy; 7 | 8 | // for 8-16 bits 9 | Oy = full_scale ? 0 : (16 << (bits_per_pixel - 8)); 10 | 11 | const int ymin = (full_scale ? 0 : 16) << (bits_per_pixel - 8); 12 | const int max_pixel_value = (1 << bits_per_pixel) - 1; 13 | const int ymax = full_scale ? max_pixel_value : (235 << (bits_per_pixel - 8)); 14 | Sy = ymax - ymin; 15 | 16 | const int cmin = full_scale ? 0 : (16 << (bits_per_pixel - 8)); 17 | const int cmax = full_scale ? max_pixel_value : (240 << (bits_per_pixel - 8)); 18 | Suv = (cmax - cmin) / 2; 19 | 20 | const double mulfac = (double)(1ULL << shift); // integer aritmetic precision scale 21 | 22 | const double Kg = 1. - Kr - Kb; 23 | 24 | const int Srgb = (1 << bits_per_pixel) - 1; 25 | matrix->y_b = (int)(Sy * Kb * mulfac / Srgb + 0.5); //B 26 | matrix->y_g = (int)(Sy * Kg * mulfac / Srgb + 0.5); //G 27 | matrix->y_r = (int)(Sy * Kr * mulfac / Srgb + 0.5); //R 28 | matrix->u_b = (int)(Suv * mulfac / Srgb + 0.5); 29 | matrix->u_g = (int)(Suv * Kg / (Kb - 1) * mulfac / Srgb + 0.5); 30 | matrix->u_r = (int)(Suv * Kr / (Kb - 1) * mulfac / Srgb + 0.5); 31 | matrix->v_b = (int)(Suv * Kb / (Kr - 1) * mulfac / Srgb + 0.5); 32 | matrix->v_g = (int)(Suv * Kg / (Kr - 1) * mulfac / Srgb + 0.5); 33 | matrix->v_r = (int)(Suv * mulfac / Srgb + 0.5); 34 | matrix->offset_y = Oy; 35 | matrix->valid = true; 36 | } 37 | 38 | void FillMatrix(ConversionMatrix* matrix, matrix_type mt) 39 | { 40 | const int bits_per_pixel = 8; 41 | const int bitshift = 16; // for integer arithmetic 42 | matrix->valid = true; 43 | 44 | switch (mt) { 45 | case MATRIX_NONE: 46 | matrix->valid = false; 47 | break; 48 | case MATRIX_BT601: 49 | BuildMatrix(matrix, 0.299, /* 0.587 */ 0.114, bitshift, false, bits_per_pixel); // false: limited range 50 | break; 51 | case MATRIX_PC601: 52 | BuildMatrix(matrix, 0.299, /* 0.587 */ 0.114, bitshift, true, bits_per_pixel); // true: full scale 53 | break; 54 | case MATRIX_BT709: 55 | BuildMatrix(matrix, 0.2126, /* 0.7152 */ 0.0722, bitshift, false, bits_per_pixel); // false: limited range 56 | break; 57 | case MATRIX_PC709: 58 | BuildMatrix(matrix, 0.2126, /* 0.7152 */ 0.0722, bitshift, true, bits_per_pixel); // true: full scale 59 | break; 60 | case MATRIX_BT2020: 61 | BuildMatrix(matrix, 0.2627, /* 0.6780 */ 0.0593, bitshift, false, bits_per_pixel); // false: limited range 62 | break; 63 | case MATRIX_PC2020: 64 | BuildMatrix(matrix, 0.2627, /* 0.6780 */ 0.0593, bitshift, true, bits_per_pixel); // true: full scale 65 | break; 66 | case MATRIX_TVFCC: 67 | BuildMatrix(matrix, 0.300, /* 0.590 */ 0.110, bitshift, false, bits_per_pixel); // false: limited range 68 | break; 69 | case MATRIX_PCFCC: 70 | BuildMatrix(matrix, 0.300, /* 0.590 */ 0.110, bitshift, true, bits_per_pixel); // true: full scale 71 | break; 72 | case MATRIX_TV240M: 73 | BuildMatrix(matrix, 0.212, /* 0.701 */ 0.087, bitshift, false, bits_per_pixel); // false: limited range 74 | break; 75 | case MATRIX_PC240M: 76 | BuildMatrix(matrix, 0.212, /* 0.701 */ 0.087, bitshift, true, bits_per_pixel); // true: full scale 77 | break; 78 | default: 79 | matrix->valid = false; 80 | } 81 | } 82 | 83 | inline void col2rgb(uint32_t* c, uint8_t* r, uint8_t* g, uint8_t* b) 84 | { 85 | *r = _r(*c); 86 | *g = _g(*c); 87 | *b = _b(*c); 88 | } 89 | 90 | inline void col2yuv(uint32_t* c, uint8_t* y, uint8_t* u, uint8_t* v, ConversionMatrix* m) 91 | { 92 | *y = div65536(m->y_r * _r(*c) + m->y_g * _g(*c) + m->y_b * _b(*c)) + m->offset_y; 93 | *u = div65536(m->u_r * _r(*c) + m->u_g * _g(*c) + m->u_b * _b(*c)) + 128; 94 | *v = div65536(m->v_r * _r(*c) + m->v_g * _g(*c) + m->v_b * _b(*c)) + 128; 95 | } 96 | 97 | void make_sub_img(ASS_Image* img, uint8_t** sub_img, uint32_t width, int bits_per_pixel, int rgb, ConversionMatrix* mx) 98 | { 99 | uint8_t c1, c2, c3, a, a1; 100 | uint8_t* src; 101 | uint8_t* dstC1, * dstC2, * dstC3, * dstA; 102 | uint32_t dsta; 103 | 104 | while (img) { 105 | if (img->w == 0 || img->h == 0) { 106 | // nothing to render 107 | img = img->next; 108 | continue; 109 | } 110 | 111 | // color comes always in 8 bits 112 | if(mx->valid) 113 | col2yuv(&img->color, &c1, &c2, &c3, mx); 114 | else 115 | col2rgb(&img->color, &c1, &c2, &c3); 116 | a1 = 255 - _a(img->color); // transparency 117 | 118 | src = img->bitmap; 119 | dstC1 = sub_img[1] + img->dst_y * width + img->dst_x; 120 | dstC2 = sub_img[2] + img->dst_y * width + img->dst_x; 121 | dstC3 = sub_img[3] + img->dst_y * width + img->dst_x; 122 | dstA = sub_img[0] + img->dst_y * width + img->dst_x; 123 | 124 | for (int i = 0; i < img->h; i++) { 125 | for (int j = 0; j < img->w; j++) { 126 | a = div255(src[j] * a1); 127 | if (a) { 128 | if (dstA[j]) { 129 | dsta = scale(a, 255, dstA[j]); 130 | dstC1[j] = dblend(a, c1, dstA[j], dstC1[j], dsta); 131 | dstC2[j] = dblend(a, c2, dstA[j], dstC2[j], dsta); 132 | dstC3[j] = dblend(a, c3, dstA[j], dstC3[j], dsta); 133 | dstA[j] = div255(dsta); 134 | } else { 135 | dstC1[j] = c1; 136 | dstC2[j] = c2; 137 | dstC3[j] = c3; 138 | dstA[j] = a; 139 | } 140 | } 141 | } 142 | 143 | src += img->stride; 144 | dstC1 += width; 145 | dstC2 += width; 146 | dstC3 += width; 147 | dstA += width; 148 | } 149 | 150 | img = img->next; 151 | } 152 | } 153 | 154 | void make_sub_img16(ASS_Image* img, uint8_t** sub_img0, uint32_t width, int bits_per_pixel, int rgb, ConversionMatrix *mx) 155 | { 156 | uint16_t** sub_img = (uint16_t**)sub_img0; 157 | 158 | uint8_t c1_8, c2_8, c3_8; 159 | 160 | int c1, c2, c3; 161 | int a1, a; 162 | 163 | uint8_t* src; 164 | uint16_t* dstC1, * dstC2, * dstC3, * dstA; 165 | uint32_t dsta; 166 | 167 | while (img) { 168 | if (img->w == 0 || img->h == 0) { 169 | // nothing to render 170 | img = img->next; 171 | continue; 172 | } 173 | 174 | // color comes always in 8 bits 175 | if (mx->valid) 176 | col2yuv(&img->color, &c1_8, &c2_8, &c3_8, mx); 177 | else 178 | col2rgb(&img->color, &c1_8, &c2_8, &c3_8); 179 | a1 = 255 - _a(img->color); // transparency, always 0..255 180 | if (rgb) { 181 | const int max_pixel_value = (1 << bits_per_pixel) - 1; 182 | // rgb needs full scale stretch 8->N bits 183 | c1 = (int)(c1_8 * max_pixel_value / 255.0f + 0.5f); 184 | c2 = (int)(c2_8 * max_pixel_value / 255.0f + 0.5f); 185 | c3 = (int)(c3_8 * max_pixel_value / 255.0f + 0.5f); 186 | } 187 | else { 188 | // YUV: bit shift 189 | c1 = c1_8 << (bits_per_pixel - 8); 190 | c2 = c2_8 << (bits_per_pixel - 8); 191 | c3 = c3_8 << (bits_per_pixel - 8); 192 | } 193 | 194 | src = img->bitmap; // always 8 bits 195 | // dst 1..3 is real bit depth 0 (alpha) is 8 bits 196 | dstC1 = sub_img[1] + img->dst_y * width + img->dst_x; 197 | dstC2 = sub_img[2] + img->dst_y * width + img->dst_x; 198 | dstC3 = sub_img[3] + img->dst_y * width + img->dst_x; 199 | dstA = sub_img[0] + img->dst_y * width + img->dst_x; 200 | 201 | for (int i = 0; i < img->h; i++) { 202 | for (int j = 0; j < img->w; j++) { 203 | a = div255(src[j] * a1); 204 | if (a) { 205 | if (dstA[j]) { 206 | // combine with existing dst transparency 207 | dsta = scale(a, 255, dstA[j]); 208 | dstC1[j] = dblend(a, c1, dstA[j], dstC1[j], dsta); 209 | dstC2[j] = dblend(a, c2, dstA[j], dstC2[j], dsta); 210 | dstC3[j] = dblend(a, c3, dstA[j], dstC3[j], dsta); 211 | dstA[j] = div255(dsta); // always 0..255 212 | } 213 | else { 214 | dstC1[j] = c1; 215 | dstC2[j] = c2; 216 | dstC3[j] = c3; 217 | dstA[j] = a; // always 0..255 218 | } 219 | } 220 | } 221 | 222 | src += img->stride; 223 | dstC1 += width; 224 | dstC2 += width; 225 | dstC3 += width; 226 | dstA += width; 227 | } 228 | 229 | img = img->next; 230 | } 231 | } 232 | 233 | void apply_rgba(uint8_t** sub_img, uint8_t** data, uint32_t* pitch, uint32_t width, uint32_t height) 234 | { 235 | uint8_t *srcA, *srcR, *srcG, *srcB, *dstA, *dstR, *dstG, *dstB; 236 | uint32_t i, j, k, dsta; 237 | 238 | srcR = sub_img[1]; 239 | srcG = sub_img[2]; 240 | srcB = sub_img[3]; 241 | srcA = sub_img[0]; 242 | 243 | // Move destination pointer to the bottom right corner of the 244 | // bounding box that contains the current overlay bitmap. 245 | // Remember that avisynth RGB bitmaps are upside down, hence we 246 | // need to render upside down. 247 | dstB = data[0] + pitch[0] * (height - 1); 248 | dstG = dstB + 1; 249 | dstR = dstB + 2; 250 | dstA = dstB + 3; 251 | 252 | for (i = 0; i < height; i++) { 253 | for (j = 0; j < width; j++) { 254 | if (srcA[j]) { 255 | k = j * 4; 256 | dsta = scale(srcA[j], 255, dstA[k]); 257 | dstR[k] = dblend(srcA[j], srcR[j], dstA[k], dstR[k], dsta); 258 | dstG[k] = dblend(srcA[j], srcG[j], dstA[k], dstG[k], dsta); 259 | dstB[k] = dblend(srcA[j], srcB[j], dstA[k], dstB[k], dsta); 260 | dstA[k] = div255(dsta); 261 | } 262 | } 263 | 264 | srcR += width; 265 | srcG += width; 266 | srcB += width; 267 | srcA += width; 268 | dstR -= pitch[0]; 269 | dstG -= pitch[0]; 270 | dstB -= pitch[0]; 271 | dstA -= pitch[0]; 272 | } 273 | } 274 | 275 | void apply_rgb(uint8_t** sub_img, uint8_t** data, uint32_t* pitch, uint32_t width, uint32_t height) 276 | { 277 | uint8_t *srcR, *srcG, *srcB, *srcA, *dstR, *dstG, *dstB; 278 | uint32_t i, j, k; 279 | 280 | srcR = sub_img[1]; 281 | srcG = sub_img[2]; 282 | srcB = sub_img[3]; 283 | srcA = sub_img[0]; 284 | 285 | // Move destination pointer to the bottom right corner of the 286 | // bounding box that contains the current overlay bitmap. 287 | // Remember that avisynth RGB bitmaps are upside down, hence we 288 | // need to render upside down. 289 | dstB = data[0] + pitch[0] * (height - 1); 290 | dstG = dstB + 1; 291 | dstR = dstB + 2; 292 | 293 | for (i = 0; i < height; i++) { 294 | for (j = 0; j < width; j++) { 295 | if (srcA[j]) { 296 | k = j * 3; 297 | dstR[k] = blend(srcA[j], srcR[j], dstR[k]); 298 | dstG[k] = blend(srcA[j], srcG[j], dstG[k]); 299 | dstB[k] = blend(srcA[j], srcB[j], dstB[k]); 300 | } 301 | } 302 | 303 | srcR += width; 304 | srcG += width; 305 | srcB += width; 306 | srcA += width; 307 | dstR -= pitch[0]; 308 | dstG -= pitch[0]; 309 | dstB -= pitch[0]; 310 | } 311 | } 312 | 313 | void apply_rgb64(uint8_t** sub_img_8, uint8_t** data_8, uint32_t* pitch, uint32_t width, uint32_t height) 314 | { 315 | uint16_t* srcA, * srcR, * srcG, * srcB, * dstA, * dstR, * dstG, * dstB; 316 | uint32_t i, j, k, dsta; 317 | uint16_t** sub_img = (uint16_t**)sub_img_8; 318 | uint16_t** data = (uint16_t**)data_8; 319 | 320 | srcR = sub_img[1]; 321 | srcG = sub_img[2]; 322 | srcB = sub_img[3]; 323 | srcA = sub_img[0]; // 0..255 always 324 | 325 | const int pitch0 = pitch[0] / sizeof(uint16_t); 326 | 327 | // Move destination pointer to the bottom right corner of the 328 | // bounding box that contains the current overlay bitmap. 329 | // Remember that avisynth RGB bitmaps are upside down, hence we 330 | // need to render upside down. 331 | dstB = data[0] + pitch0 * (height - 1); 332 | // fixme pf: don't use 4 pointers, maybe they are not recognized to optimize out 333 | dstG = dstB + 1; 334 | dstR = dstB + 2; 335 | dstA = dstB + 3; 336 | 337 | for (i = 0; i < height; i++) { 338 | for (j = 0; j < width; j++) { 339 | if (srcA[j]) { 340 | k = j * 4; 341 | dsta = scale(srcA[j], 255, dstA[k]); 342 | dstR[k] = dblend(srcA[j], srcR[j], dstA[k], dstR[k], dsta); 343 | dstG[k] = dblend(srcA[j], srcG[j], dstA[k], dstG[k], dsta); 344 | dstB[k] = dblend(srcA[j], srcB[j], dstA[k], dstB[k], dsta); 345 | dstA[k] = div255(dsta); 346 | } 347 | } 348 | 349 | srcR += width; 350 | srcG += width; 351 | srcB += width; 352 | srcA += width; 353 | dstR -= pitch0; 354 | dstG -= pitch0; 355 | dstB -= pitch0; 356 | dstA -= pitch0; 357 | } 358 | } 359 | 360 | void apply_rgb48(uint8_t** sub_img_8, uint8_t** data_8, uint32_t* pitch, uint32_t width, uint32_t height) 361 | { 362 | uint16_t* srcR, * srcG, * srcB, * srcA, * dstR, * dstG, * dstB; 363 | uint32_t i, j, k; 364 | uint16_t** sub_img = (uint16_t**)sub_img_8; 365 | uint16_t** data = (uint16_t**)data_8; 366 | 367 | srcR = sub_img[1]; 368 | srcG = sub_img[2]; 369 | srcB = sub_img[3]; 370 | srcA = sub_img[0]; // 0..255 always 371 | 372 | const int pitch0 = pitch[0] / sizeof(uint16_t); 373 | 374 | // Move destination pointer to the bottom right corner of the 375 | // bounding box that contains the current overlay bitmap. 376 | // Remember that avisynth RGB bitmaps are upside down, hence we 377 | // need to render upside down. 378 | dstB = data[0] + pitch0 * (height - 1); 379 | // fixme pf: don't use 3 pointers, maybe they are not recognized to optimize out 380 | dstG = dstB + 1; 381 | dstR = dstB + 2; 382 | 383 | for (i = 0; i < height; i++) { 384 | for (j = 0; j < width; j++) { 385 | if (srcA[j]) { 386 | k = j * 3; 387 | dstR[k] = blend(srcA[j], srcR[j], dstR[k]); 388 | dstG[k] = blend(srcA[j], srcG[j], dstG[k]); 389 | dstB[k] = blend(srcA[j], srcB[j], dstB[k]); 390 | } 391 | } 392 | 393 | srcR += width; 394 | srcG += width; 395 | srcB += width; 396 | srcA += width; 397 | dstR -= pitch0; 398 | dstG -= pitch0; 399 | dstB -= pitch0; 400 | } 401 | } 402 | 403 | void apply_yuy2(uint8_t** sub_img, uint8_t** data, uint32_t* pitch, uint32_t width, uint32_t height) 404 | { 405 | uint8_t *srcY0, *srcY1, *srcU0, *srcU1, *srcV0, *srcV1, *srcA0, *srcA1; 406 | uint8_t *dstY0, *dstU, *dstY1, *dstV; 407 | uint32_t i, j, k; 408 | 409 | srcY0 = sub_img[1]; 410 | srcY1 = sub_img[1] + 1; 411 | srcU0 = sub_img[2]; 412 | srcU1 = sub_img[2] + 1; 413 | srcV0 = sub_img[3]; 414 | srcV1 = sub_img[3] + 1; 415 | srcA0 = sub_img[0]; 416 | srcA1 = sub_img[0] + 1; 417 | 418 | // YUYV 419 | dstY0 = data[0]; 420 | dstU = data[0] + 1; 421 | dstY1 = data[0] + 2; 422 | dstV = data[0] + 3; 423 | 424 | for (i = 0; i < height; i++) { 425 | for (j = 0; j < width; j += 2) { 426 | if (srcA0[j] + srcA1[j]) { 427 | k = j * 2; 428 | dstY0[k] = blend(srcA0[j], srcY0[j], dstY0[k]); 429 | dstY1[k] = blend(srcA1[j], srcY1[j], dstY1[k]); 430 | dstU[k] = blend2(srcA0[j], srcU0[j], 431 | srcA1[j], srcU1[j], dstU[k]); 432 | dstV[k] = blend2(srcA0[j], srcV0[j], 433 | srcA1[j], srcV1[j], dstV[k]); 434 | } 435 | } 436 | 437 | srcY0 += width; 438 | srcY1 += width; 439 | srcU0 += width; 440 | srcU1 += width; 441 | srcV0 += width; 442 | srcV1 += width; 443 | srcA0 += width; 444 | srcA1 += width; 445 | dstY0 += pitch[0]; 446 | dstU += pitch[0]; 447 | dstY1 += pitch[0]; 448 | dstV += pitch[0]; 449 | } 450 | } 451 | 452 | void apply_yv12(uint8_t** sub_img, uint8_t** data, uint32_t* pitch, uint32_t width, uint32_t height) 453 | { 454 | uint8_t *srcY00, *srcU00, *srcV00, *srcA00; 455 | uint8_t *srcY01, *srcU01, *srcV01, *srcA01; 456 | uint8_t *srcY10, *srcU10, *srcV10, *srcA10; 457 | uint8_t *srcY11, *srcU11, *srcV11, *srcA11; 458 | uint8_t *dstY00, *dstY01, *dstY10, *dstY11, *dstU, *dstV; 459 | uint32_t i, j, k; 460 | 461 | srcY00 = sub_img[1]; 462 | srcY01 = sub_img[1] + 1; 463 | srcY10 = sub_img[1] + width; 464 | srcY11 = sub_img[1] + width + 1; 465 | srcU00 = sub_img[2]; 466 | srcU01 = sub_img[2] + 1; 467 | srcU10 = sub_img[2] + width; 468 | srcU11 = sub_img[2] + width + 1; 469 | srcV00 = sub_img[3]; 470 | srcV01 = sub_img[3] + 1; 471 | srcV10 = sub_img[3] + width; 472 | srcV11 = sub_img[3] + width + 1; 473 | srcA00 = sub_img[0]; 474 | srcA01 = sub_img[0] + 1; 475 | srcA10 = sub_img[0] + width; 476 | srcA11 = sub_img[0] + width + 1; 477 | 478 | dstY00 = data[0]; 479 | dstY01 = data[0] + 1; 480 | dstY10 = data[0] + pitch[0]; 481 | dstY11 = data[0] + pitch[0] + 1; 482 | dstU = data[1]; 483 | dstV = data[2]; 484 | 485 | for (i = 0; i < height; i += 2) { 486 | for (j = 0; j < width; j += 2) { 487 | k = j >> 1; 488 | if (srcA00[j] + srcA01[j] + srcA10[j] + srcA11[j]) { 489 | dstY00[j] = blend(srcA00[j], srcY00[j], dstY00[j]); 490 | dstY01[j] = blend(srcA01[j], srcY01[j], dstY01[j]); 491 | dstY10[j] = blend(srcA10[j], srcY10[j], dstY10[j]); 492 | dstY11[j] = blend(srcA11[j], srcY11[j], dstY11[j]); 493 | dstU[k] = blend4(srcA00[j], srcU00[j], 494 | srcA01[j], srcU01[j], 495 | srcA10[j], srcU10[j], 496 | srcA11[j], srcU11[j], dstU[k]); 497 | dstV[k] = blend4(srcA00[j], srcV00[j], 498 | srcA01[j], srcV01[j], 499 | srcA10[j], srcV10[j], 500 | srcA11[j], srcV11[j], dstV[k]); 501 | } 502 | } 503 | 504 | srcY00 += width * 2; 505 | srcY01 += width * 2; 506 | srcY10 += width * 2; 507 | srcY11 += width * 2; 508 | srcU00 += width * 2; 509 | srcU01 += width * 2; 510 | srcU10 += width * 2; 511 | srcU11 += width * 2; 512 | srcV00 += width * 2; 513 | srcV01 += width * 2; 514 | srcV10 += width * 2; 515 | srcV11 += width * 2; 516 | srcA00 += width * 2; 517 | srcA01 += width * 2; 518 | srcA10 += width * 2; 519 | srcA11 += width * 2; 520 | dstY00 += pitch[0] * 2; 521 | dstY01 += pitch[0] * 2; 522 | dstY10 += pitch[0] * 2; 523 | dstY11 += pitch[0] * 2; 524 | dstU += pitch[1]; 525 | dstV += pitch[1]; 526 | } 527 | } 528 | 529 | void apply_yuv420(uint8_t** sub_img_8, uint8_t** data_8, uint32_t* pitch, uint32_t width, uint32_t height) 530 | { 531 | uint16_t* srcY00, * srcU00, * srcV00, * srcA00; 532 | uint16_t* srcY01, * srcU01, * srcV01, * srcA01; 533 | uint16_t* srcY10, * srcU10, * srcV10, * srcA10; 534 | uint16_t* srcY11, * srcU11, * srcV11, * srcA11; 535 | uint16_t* dstY00, * dstY01, * dstY10, * dstY11, * dstU, * dstV; 536 | uint32_t i, j, k; 537 | 538 | uint16_t** sub_img = (uint16_t**)sub_img_8; 539 | uint16_t** data = (uint16_t**)data_8; 540 | 541 | // sub_img[0] is 0..255 always 542 | 543 | const int pitch0 = pitch[0] / sizeof(uint16_t); 544 | const int pitchUV = pitch[1] / sizeof(uint16_t); 545 | 546 | srcY00 = sub_img[1]; 547 | srcY01 = sub_img[1] + 1; 548 | srcY10 = sub_img[1] + width; 549 | srcY11 = sub_img[1] + width + 1; 550 | srcU00 = sub_img[2]; 551 | srcU01 = sub_img[2] + 1; 552 | srcU10 = sub_img[2] + width; 553 | srcU11 = sub_img[2] + width + 1; 554 | srcV00 = sub_img[3]; 555 | srcV01 = sub_img[3] + 1; 556 | srcV10 = sub_img[3] + width; 557 | srcV11 = sub_img[3] + width + 1; 558 | srcA00 = sub_img[0]; 559 | srcA01 = sub_img[0] + 1; 560 | srcA10 = sub_img[0] + width; 561 | srcA11 = sub_img[0] + width + 1; 562 | 563 | dstY00 = data[0]; 564 | dstY01 = data[0] + 1; 565 | dstY10 = data[0] + pitch0; 566 | dstY11 = data[0] + pitch0 + 1; 567 | dstU = data[1]; 568 | dstV = data[2]; 569 | 570 | //4:2:0 : 2x2 Y for each chroma 571 | for (i = 0; i < height; i += 2) { 572 | for (j = 0; j < width; j += 2) { 573 | k = j >> 1; 574 | if (srcA00[j] + srcA01[j] + srcA10[j] + srcA11[j]) { 575 | dstY00[j] = blend(srcA00[j], srcY00[j], dstY00[j]); 576 | dstY01[j] = blend(srcA01[j], srcY01[j], dstY01[j]); 577 | dstY10[j] = blend(srcA10[j], srcY10[j], dstY10[j]); 578 | dstY11[j] = blend(srcA11[j], srcY11[j], dstY11[j]); 579 | dstU[k] = blend4(srcA00[j], srcU00[j], 580 | srcA01[j], srcU01[j], 581 | srcA10[j], srcU10[j], 582 | srcA11[j], srcU11[j], dstU[k]); 583 | dstV[k] = blend4(srcA00[j], srcV00[j], 584 | srcA01[j], srcV01[j], 585 | srcA10[j], srcV10[j], 586 | srcA11[j], srcV11[j], dstV[k]); 587 | } 588 | } 589 | 590 | srcY00 += width * 2; 591 | srcY01 += width * 2; 592 | srcY10 += width * 2; 593 | srcY11 += width * 2; 594 | srcU00 += width * 2; 595 | srcU01 += width * 2; 596 | srcU10 += width * 2; 597 | srcU11 += width * 2; 598 | srcV00 += width * 2; 599 | srcV01 += width * 2; 600 | srcV10 += width * 2; 601 | srcV11 += width * 2; 602 | srcA00 += width * 2; 603 | srcA01 += width * 2; 604 | srcA10 += width * 2; 605 | srcA11 += width * 2; 606 | dstY00 += pitch0 * 2; 607 | dstY01 += pitch0 * 2; 608 | dstY10 += pitch0 * 2; 609 | dstY11 += pitch0 * 2; 610 | dstU += pitchUV; 611 | dstV += pitchUV; 612 | } 613 | } 614 | 615 | void apply_yv411(uint8_t** sub_img, uint8_t** data, uint32_t* pitch, uint32_t width, uint32_t height) 616 | { 617 | uint8_t* srcY, * srcU, * srcV, * srcA; 618 | uint8_t* dstY0, * dstV, *dstU; 619 | 620 | srcY = sub_img[1]; 621 | srcU = sub_img[2]; 622 | srcV = sub_img[3]; 623 | srcA = sub_img[0]; 624 | 625 | dstY0 = data[0]; 626 | dstU = data[1]; 627 | dstV = data[2]; 628 | 629 | for (unsigned int i = 0; i < height; i++) { 630 | for (unsigned int j = 0; j < width / 4; j++) { 631 | int jy = j * 4; 632 | if (srcA[jy] + srcA[jy + 1] + srcA[jy + 2] + srcA[jy + 3]) { 633 | dstY0[jy + 0] = blend(srcA[jy + 0], srcY[jy + 0], dstY0[jy + 0]); 634 | dstY0[jy + 1] = blend(srcA[jy + 1], srcY[jy + 1], dstY0[jy + 1]); 635 | dstY0[jy + 2] = blend(srcA[jy + 2], srcY[jy + 2], dstY0[jy + 2]); 636 | dstY0[jy + 3] = blend(srcA[jy + 3], srcY[jy + 3], dstY0[jy + 3]); 637 | dstU[j] = blend4(srcA[jy + 0], srcU[jy + 0], 638 | srcA[jy + 1], srcU[jy + 1], 639 | srcA[jy + 2], srcU[jy + 2], 640 | srcA[jy + 3], srcU[jy + 3], 641 | dstU[j]); 642 | dstV[j] = blend4(srcA[jy + 0], srcV[jy + 0], 643 | srcA[jy + 1], srcV[jy + 1], 644 | srcA[jy + 2], srcV[jy + 2], 645 | srcA[jy + 3], srcV[jy + 3], 646 | dstV[j]); 647 | } 648 | } 649 | 650 | srcY += width; 651 | srcU += width; 652 | srcV += width; 653 | srcA += width; 654 | dstY0 += pitch[0]; 655 | dstU += pitch[1]; 656 | dstV += pitch[1]; 657 | } 658 | } 659 | 660 | void apply_yv16(uint8_t** sub_img, uint8_t** data, uint32_t* pitch, uint32_t width, uint32_t height) 661 | { 662 | uint8_t *srcY0, *srcY1, *srcU0, *srcU1, *srcV0, *srcV1, *srcA0, *srcA1; 663 | uint8_t *dstY0, *dstU, *dstY1, *dstV; 664 | uint32_t i, j, k; 665 | 666 | srcY0 = sub_img[1]; 667 | srcY1 = sub_img[1] + 1; 668 | srcU0 = sub_img[2]; 669 | srcU1 = sub_img[2] + 1; 670 | srcV0 = sub_img[3]; 671 | srcV1 = sub_img[3] + 1; 672 | srcA0 = sub_img[0]; 673 | srcA1 = sub_img[0] + 1; 674 | 675 | dstY0 = data[0]; 676 | dstU = data[1]; 677 | dstY1 = data[0] + 1; 678 | dstV = data[2]; 679 | 680 | for (i = 0; i < height; i++) { 681 | for (j = 0; j < width; j += 2) { 682 | k = j >> 1; 683 | if (srcA0[j] + srcA1[j]) { 684 | dstY0[j] = blend(srcA0[j], srcY0[j], dstY0[j]); 685 | dstY1[j] = blend(srcA1[j], srcY1[j], dstY1[j]); 686 | dstU[k] = blend2(srcA0[j], srcU0[j], 687 | srcA1[j], srcU1[j], dstU[k]); 688 | dstV[k] = blend2(srcA0[j], srcV0[j], 689 | srcA1[j], srcV1[j], dstV[k]); 690 | } 691 | } 692 | 693 | srcY0 += width; 694 | srcY1 += width; 695 | srcU0 += width; 696 | srcU1 += width; 697 | srcV0 += width; 698 | srcV1 += width; 699 | srcA0 += width; 700 | srcA1 += width; 701 | dstY0 += pitch[0]; 702 | dstY1 += pitch[0]; 703 | dstU += pitch[1]; 704 | dstV += pitch[1]; 705 | } 706 | } 707 | 708 | void apply_yuv422(uint8_t** sub_img_8, uint8_t** data_8, uint32_t* pitch, uint32_t width, uint32_t height) 709 | { 710 | uint16_t* srcY0, * srcY1, * srcU0, * srcU1, * srcV0, * srcV1, * srcA0, * srcA1; 711 | uint16_t* dstY0, * dstU, * dstY1, * dstV; 712 | uint32_t i, j, k; 713 | 714 | uint16_t** sub_img = (uint16_t**)sub_img_8; 715 | uint16_t** data = (uint16_t**)data_8; 716 | 717 | // sub_img[0] is 0..255 always 718 | 719 | const int pitch0 = pitch[0] / sizeof(uint16_t); 720 | const int pitchUV = pitch[1] / sizeof(uint16_t); 721 | 722 | srcY0 = sub_img[1]; 723 | srcY1 = sub_img[1] + 1; 724 | srcU0 = sub_img[2]; 725 | srcU1 = sub_img[2] + 1; 726 | srcV0 = sub_img[3]; 727 | srcV1 = sub_img[3] + 1; 728 | srcA0 = sub_img[0]; 729 | srcA1 = sub_img[0] + 1; 730 | 731 | dstY0 = data[0]; 732 | dstU = data[1]; 733 | dstY1 = data[0] + 1; 734 | dstV = data[2]; 735 | 736 | for (i = 0; i < height; i++) { 737 | for (j = 0; j < width; j += 2) { 738 | k = j >> 1; 739 | if (srcA0[j] + srcA1[j]) { 740 | dstY0[j] = blend(srcA0[j], srcY0[j], dstY0[j]); 741 | dstY1[j] = blend(srcA1[j], srcY1[j], dstY1[j]); 742 | dstU[k] = blend2(srcA0[j], srcU0[j], 743 | srcA1[j], srcU1[j], dstU[k]); 744 | dstV[k] = blend2(srcA0[j], srcV0[j], 745 | srcA1[j], srcV1[j], dstV[k]); 746 | } 747 | } 748 | 749 | srcY0 += width; 750 | srcY1 += width; 751 | srcU0 += width; 752 | srcU1 += width; 753 | srcV0 += width; 754 | srcV1 += width; 755 | srcA0 += width; 756 | srcA1 += width; 757 | dstY0 += pitch0; 758 | dstY1 += pitch0; 759 | dstU += pitchUV; 760 | dstV += pitchUV; 761 | } 762 | } 763 | 764 | void apply_yv24(uint8_t** sub_img, uint8_t** data, uint32_t* pitch, uint32_t width, uint32_t height) 765 | { 766 | uint8_t *srcY, *srcU, *srcV, *srcA, *dstY, *dstU, *dstV; 767 | uint32_t i, j; 768 | 769 | srcY = sub_img[1]; 770 | srcU = sub_img[2]; 771 | srcV = sub_img[3]; 772 | srcA = sub_img[0]; 773 | 774 | dstY = data[0]; 775 | dstU = data[1]; 776 | dstV = data[2]; 777 | 778 | for (i = 0; i < height; i++) { 779 | for (j = 0; j < width; j++) { 780 | if (srcA[j]) { 781 | dstY[j] = blend(srcA[j], srcY[j], dstY[j]); 782 | dstU[j] = blend(srcA[j], srcU[j], dstU[j]); 783 | dstV[j] = blend(srcA[j], srcV[j], dstV[j]); 784 | } 785 | } 786 | 787 | srcY += width; 788 | srcU += width; 789 | srcV += width; 790 | srcA += width; 791 | dstY += pitch[0]; 792 | dstU += pitch[0]; 793 | dstV += pitch[0]; 794 | } 795 | } 796 | 797 | void apply_yuv444(uint8_t** sub_img_8, uint8_t** data_8, uint32_t* pitch, uint32_t width, uint32_t height) 798 | { 799 | // planar RGB as well 800 | uint16_t* srcY, * srcU, * srcV, * srcA, * dstY, * dstU, * dstV; 801 | uint32_t i, j; 802 | 803 | uint16_t** sub_img = (uint16_t**)sub_img_8; 804 | uint16_t** data = (uint16_t**)data_8; 805 | 806 | // sub_img[0] is 0..255 always 807 | 808 | const int pitch0 = pitch[0] / sizeof(uint16_t); 809 | 810 | srcY = sub_img[1]; 811 | srcU = sub_img[2]; 812 | srcV = sub_img[3]; 813 | srcA = sub_img[0]; 814 | 815 | dstY = data[0]; 816 | dstU = data[1]; 817 | dstV = data[2]; 818 | 819 | for (i = 0; i < height; i++) { 820 | for (j = 0; j < width; j++) { 821 | if (srcA[j]) { 822 | dstY[j] = blend(srcA[j], srcY[j], dstY[j]); 823 | dstU[j] = blend(srcA[j], srcU[j], dstU[j]); 824 | dstV[j] = blend(srcA[j], srcV[j], dstV[j]); 825 | } 826 | } 827 | 828 | srcY += width; 829 | srcU += width; 830 | srcV += width; 831 | srcA += width; 832 | dstY += pitch0; 833 | dstU += pitch0; 834 | dstV += pitch0; 835 | } 836 | } 837 | 838 | void apply_y8(uint8_t** sub_img, uint8_t** data, uint32_t* pitch, uint32_t width, uint32_t height) 839 | { 840 | uint8_t *srcY, *srcA, *dstY; 841 | uint32_t i, j; 842 | 843 | srcY = sub_img[1]; 844 | srcA = sub_img[0]; 845 | 846 | dstY = data[0]; 847 | 848 | for (i = 0; i < height; i++) { 849 | for (j = 0; j < width; j++) { 850 | if (srcA[j]) { 851 | dstY[j] = blend(srcA[j], srcY[j], dstY[j]); 852 | } 853 | } 854 | 855 | srcY += width; 856 | srcA += width; 857 | dstY += pitch[0]; 858 | } 859 | } 860 | 861 | void apply_y(uint8_t** sub_img_8, uint8_t** data_8, uint32_t* pitch, uint32_t width, uint32_t height) 862 | { 863 | uint16_t* srcY, * srcA, * dstY; 864 | uint32_t i, j; 865 | 866 | uint16_t** sub_img = (uint16_t**)sub_img_8; 867 | uint16_t** data = (uint16_t**)data_8; 868 | 869 | // sub_img[0] is 0..255 always 870 | 871 | const int pitch0 = pitch[0] / sizeof(uint16_t); 872 | 873 | srcY = sub_img[1]; 874 | srcA = sub_img[0]; 875 | 876 | dstY = data[0]; 877 | 878 | for (i = 0; i < height; i++) { 879 | for (j = 0; j < width; j++) { 880 | if (srcA[j]) { 881 | dstY[j] = blend(srcA[j], srcY[j], dstY[j]); 882 | } 883 | } 884 | 885 | srcY += width; 886 | srcA += width; 887 | dstY += pitch0; 888 | } 889 | } 890 | 891 | AVS_VideoFrame* AVSC_CC assrender_get_frame(AVS_FilterInfo* p, int n) 892 | { 893 | udata* ud = (udata*)p->user_data; 894 | ASS_Image* img; 895 | AVS_VideoFrame* src; 896 | 897 | int64_t ts; 898 | int changed; 899 | 900 | src = avs_get_frame(p->child, n); 901 | 902 | avs_make_writable(p->env, &src); 903 | 904 | if (!ud->isvfr) { 905 | // it’s a casting party! 906 | ts = (int64_t)n * (int64_t)1000 * (int64_t)p->vi.fps_denominator / (int64_t)p->vi.fps_numerator; 907 | } else { 908 | ts = ud->timestamp[n]; 909 | } 910 | 911 | img = ass_render_frame(ud->ass_renderer, ud->ass, ts, &changed); 912 | 913 | if (img) { 914 | uint32_t height, width, pitch[2]; 915 | uint8_t* data[3]; 916 | 917 | if (avs_is_planar(&p->vi) && !ud->greyscale) { 918 | if (avs_is_rgb(&p->vi)) { 919 | // planar RGB as 444 920 | data[0] = avs_get_write_ptr_p(src, AVS_PLANAR_R); 921 | data[1] = avs_get_write_ptr_p(src, AVS_PLANAR_G); 922 | data[2] = avs_get_write_ptr_p(src, AVS_PLANAR_B); 923 | pitch[0] = avs_get_pitch(src); 924 | } 925 | else { 926 | data[0] = avs_get_write_ptr_p(src, AVS_PLANAR_Y); 927 | data[1] = avs_get_write_ptr_p(src, AVS_PLANAR_U); 928 | data[2] = avs_get_write_ptr_p(src, AVS_PLANAR_V); 929 | pitch[0] = avs_get_pitch_p(src, AVS_PLANAR_Y); 930 | pitch[1] = avs_get_pitch_p(src, AVS_PLANAR_U); 931 | } 932 | } 933 | else { 934 | data[0] = avs_get_write_ptr(src); 935 | pitch[0] = avs_get_pitch(src); 936 | } 937 | 938 | height = p->vi.height; 939 | width = p->vi.width; 940 | 941 | if (changed) { 942 | memset(ud->sub_img[0], 0x00, height * width * ud->pixelsize); 943 | ud->f_make_sub_img(img, ud->sub_img, width, ud->bits_per_pixel, ud->rgb_fullscale, &ud->mx); 944 | } 945 | 946 | ud->apply(ud->sub_img, data, pitch, width, height); 947 | } 948 | 949 | return src; 950 | } 951 | -------------------------------------------------------------------------------- /src/render.h: -------------------------------------------------------------------------------- 1 | #ifndef _RENDER_H_ 2 | #define _RENDER_H_ 3 | 4 | #include "assrender.h" 5 | 6 | #define _r(c) (( (c) >> 24)) 7 | #define _g(c) ((((c) >> 16) & 0xFF)) 8 | #define _b(c) ((((c) >> 8) & 0xFF)) 9 | #define _a(c) (( (c) & 0xFF)) 10 | 11 | #define div256(x) (((x + 128) >> 8)) 12 | #define div65536(x) (((x + 32768) >> 16)) 13 | #define div255(x) ((div256(x + div256(x)))) 14 | #define div65535(x) ((div65536(x + div65536(x)))) 15 | 16 | #define blend(srcA, srcC, dstC) \ 17 | ((div255(srcA * srcC + (255 - srcA) * dstC))) 18 | #define blend2(src1A, src1C, src2A, src2C, dstC) \ 19 | ((div255(((src1A * src1C + src2A * src2C + (510 - src1A - src2A) * dstC + 1) >> 1)))) 20 | #define blend4(src1A, src1C, src2A, src2C, src3A, src3C, src4A, src4C, dstC) \ 21 | ((div255(((src1A * src1C + src2A * src2C + src3A * src3C + src4A * src4C + (1020 - src1A - src2A - src3A - src4A) * dstC + 2) >> 2)))) 22 | #define scale(srcA, srcC, dstC) \ 23 | ((srcA * srcC + (255 - srcA) * dstC)) 24 | #define dblend(srcA, srcC, dstA, dstC, outA) \ 25 | (((srcA * srcC * 255 + dstA * dstC * (255 - srcA) + (outA >> 1)) / outA)) 26 | 27 | void FillMatrix(ConversionMatrix* matrix, matrix_type mt); 28 | 29 | void make_sub_img(ASS_Image* img, uint8_t** sub_img, uint32_t width, int bits_per_pixel, int rgb, ConversionMatrix *mx); 30 | void make_sub_img16(ASS_Image* img, uint8_t** sub_img, uint32_t width, int bits_per_pixel, int rgb, ConversionMatrix* mx); 31 | 32 | void apply_rgba(uint8_t** sub_img, uint8_t** data, uint32_t* pitch, uint32_t width, uint32_t height); 33 | void apply_rgb(uint8_t** sub_img, uint8_t** data, uint32_t* pitch, uint32_t width, uint32_t height); 34 | void apply_rgb48(uint8_t** sub_img, uint8_t** data, uint32_t* pitch, uint32_t width, uint32_t height); 35 | void apply_rgb64(uint8_t** sub_img, uint8_t** data, uint32_t* pitch, uint32_t width, uint32_t height); 36 | void apply_yuy2(uint8_t** sub_img, uint8_t** data, uint32_t* pitch, uint32_t width, uint32_t height); 37 | void apply_yv12(uint8_t** sub_img, uint8_t** data, uint32_t* pitch, uint32_t width, uint32_t height); 38 | void apply_yv16(uint8_t** sub_img, uint8_t** data, uint32_t* pitch, uint32_t width, uint32_t height); 39 | void apply_yv24(uint8_t** sub_img, uint8_t** data, uint32_t* pitch, uint32_t width, uint32_t height); 40 | void apply_y8(uint8_t** sub_img, uint8_t** data, uint32_t* pitch, uint32_t width, uint32_t height); 41 | void apply_yuv420(uint8_t** sub_img, uint8_t** data, uint32_t* pitch, uint32_t width, uint32_t height); 42 | void apply_yuv422(uint8_t** sub_img, uint8_t** data, uint32_t* pitch, uint32_t width, uint32_t height); 43 | void apply_yuv444(uint8_t** sub_img, uint8_t** data, uint32_t* pitch, uint32_t width, uint32_t height); 44 | void apply_y(uint8_t** sub_img, uint8_t** data, uint32_t* pitch, uint32_t width, uint32_t height); 45 | void apply_yv411(uint8_t** sub_img, uint8_t** data, uint32_t* pitch, uint32_t width, uint32_t height); 46 | 47 | AVS_VideoFrame* AVSC_CC assrender_get_frame(AVS_FilterInfo* p, int n); 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /src/sub.c: -------------------------------------------------------------------------------- 1 | #include "sub.h" 2 | 3 | void ass_read_matrix(const char* f, char* csp) { 4 | char buf[BUFSIZ]; 5 | FILE* fh = fopen(f, "r"); 6 | 7 | if (!fh) 8 | return; 9 | 10 | while (fgets(buf, BUFSIZ - 1, fh) != NULL) { 11 | if (buf[0] == 0 || buf[0] == '\n' || buf[0] == '\r') 12 | continue; 13 | 14 | if (sscanf(buf, "YCbCr Matrix: %s", csp) == 1) 15 | break; 16 | 17 | if (sscanf(buf, "Video Colorspace: %s", csp) == 1) 18 | break; 19 | 20 | if (!strcmp(buf, "[Events]")) 21 | break; 22 | } 23 | 24 | fclose(fh); 25 | } 26 | 27 | ASS_Track* parse_srt(const char* f, udata* ud, const char* srt_font) 28 | { 29 | char l[BUFSIZ], buf[BUFSIZ]; 30 | int start[4], end[4], isn; 31 | ASS_Track* ass = ass_new_track(ud->ass_library); 32 | FILE* fh = fopen(f, "r"); 33 | 34 | if (!fh) 35 | return NULL; 36 | 37 | sprintf(buf, "[V4+ Styles]\nStyle: Default,%s,20,&H1EFFFFFF,&H00FFFFFF," 38 | "&H29000000,&H3C000000,0,0,0,0,100,100,0,0,1,1,1.2,2,10,10," 39 | "12,1\n\n[Events]\n", 40 | srt_font); 41 | 42 | ass_process_data(ass, buf, BUFSIZ - 1); 43 | 44 | while (fgets(l, BUFSIZ - 1, fh) != NULL) { 45 | if (l[0] == 0 || l[0] == '\n' || l[0] == '\r') 46 | continue; 47 | 48 | if (sscanf(l, "%d:%d:%d,%d --> %d:%d:%d,%d", &start[0], &start[1], 49 | &start[2], &start[3], &end[0], &end[1], &end[2], 50 | &end[3]) == 8) { 51 | sprintf(buf, "Dialogue: 0,%d:%02d:%02d.%02d,%d:%02d:%02d.%02d," 52 | "Default,,0,0,0,,{\\blur0.7}", 53 | start[0], start[1], start[2], 54 | (int)((double)start[3] / 10.0 + 0.5), end[0], end[1], 55 | end[2], (int)((double)end[3] / 10.0 + 0.5)); 56 | isn = 0; 57 | 58 | while (fgets(l, BUFSIZ - 1, fh) != NULL) { 59 | if (l[0] == 0 || l[0] == '\n' || l[0] == '\r') 60 | break; 61 | 62 | if (l[strlen(l) - 1] == '\n' || l[strlen(l) - 1] == '\r') 63 | l[strlen(l) - 1] = 0; 64 | 65 | if (isn) { 66 | strcat(buf, "\\N"); 67 | } 68 | 69 | strncat(buf, l, BUFSIZ - 1); 70 | isn = 1; 71 | } 72 | 73 | ass_process_data(ass, buf, BUFSIZ - 1); 74 | } 75 | } 76 | 77 | fclose(fh); 78 | 79 | return ass; 80 | } 81 | 82 | void msg_callback(int level, const char* fmt, va_list va, void* data) 83 | { 84 | if (level > (intptr_t)data) 85 | return; 86 | 87 | fprintf(stderr, "libass: "); 88 | vfprintf(stderr, fmt, va); 89 | fprintf(stderr, "\n"); 90 | } 91 | 92 | int init_ass(int w, int h, double scale, double line_spacing, 93 | ASS_Hinting hinting, double dar, double sar, int top, 94 | int bottom, int left, int right, int verbosity, 95 | const char* fontdir, udata* ud) 96 | { 97 | ASS_Renderer* ass_renderer; 98 | ASS_Library* ass_library = ass_library_init(); 99 | 100 | if (!ass_library) 101 | return 0; 102 | 103 | ass_set_message_cb(ass_library, msg_callback, (void*)(intptr_t)verbosity); 104 | ass_set_extract_fonts(ass_library, 0); 105 | ass_set_style_overrides(ass_library, 0); 106 | 107 | ass_renderer = ass_renderer_init(ass_library); 108 | 109 | if (!ass_renderer) 110 | return 0; 111 | 112 | ass_set_font_scale(ass_renderer, scale); 113 | ass_set_hinting(ass_renderer, hinting); 114 | ass_set_frame_size(ass_renderer, w, h); 115 | ass_set_storage_size(ass_renderer, w, h); 116 | ass_set_margins(ass_renderer, top, bottom, left, right); 117 | ass_set_use_margins(ass_renderer, 1); 118 | 119 | if (line_spacing) 120 | ass_set_line_spacing(ass_renderer, line_spacing); 121 | 122 | if (dar && sar) 123 | ass_set_pixel_aspect(ass_renderer, dar / sar); 124 | 125 | if (strcmp(fontdir, "")) 126 | ass_set_fonts_dir(ass_library, fontdir); 127 | 128 | ass_set_fonts(ass_renderer, NULL, NULL, 1, NULL, 1); 129 | ud->ass_library = ass_library; 130 | ud->ass_renderer = ass_renderer; 131 | 132 | return 1; 133 | } 134 | -------------------------------------------------------------------------------- /src/sub.h: -------------------------------------------------------------------------------- 1 | #ifndef _SUB_H_ 2 | #define _SUB_H_ 3 | 4 | #include 5 | #include "assrender.h" 6 | 7 | void ass_read_matrix(const char* f, char* csp); 8 | 9 | ASS_Track* parse_srt(const char* f, udata* ud, const char* srt_font); 10 | 11 | int init_ass(int w, int h, double scale, double line_spacing, 12 | ASS_Hinting hinting, double dar, double sar, int top, 13 | int bottom, int left, int right, int verbosity, 14 | const char* fontdir, udata* ud); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /src/timecodes.c: -------------------------------------------------------------------------------- 1 | #include "timecodes.h" 2 | 3 | int parse_timecodesv1(FILE* f, int total, udata* ud) 4 | { 5 | int start, end, n = 0; 6 | double t = 0.0, basefps = 0.0, fps; 7 | char l[BUFSIZ]; 8 | int64_t* ts = calloc(total, sizeof(int64_t)); 9 | 10 | if (!ts) 11 | return 0; 12 | 13 | while ((fgets(l, BUFSIZ - 1, f) != NULL) && n < total) { 14 | if (l[0] == 0 || l[0] == '\n' || l[0] == '\r' || l[0] == '#') 15 | continue; 16 | 17 | if (sscanf(l, "Assume %lf", &basefps) == 1) 18 | continue; 19 | 20 | if (!(sscanf(l, "%d,%d,%lf", &start, &end, &fps) == 3)) 21 | continue; 22 | 23 | if (basefps == 0.0) 24 | continue; 25 | 26 | while (n < start && n < total) { 27 | ts[n++] = (int64_t)(t + 0.5); 28 | t += 1000.0 / basefps; 29 | } 30 | 31 | while (n <= end && n < total) { 32 | ts[n++] = (int64_t)(t + 0.5); 33 | t += 1000.0 / fps; 34 | } 35 | } 36 | 37 | if (basefps == 0.0) { 38 | free(ts); 39 | return 0; 40 | } 41 | 42 | while (n < total) { 43 | ts[n++] = (int64_t)(t + 0.5); 44 | t += 1000.0 / basefps; 45 | } 46 | 47 | ud->timestamp = ts; 48 | 49 | return 1; 50 | } 51 | 52 | int parse_timecodesv2(FILE* f, int total, udata* ud) 53 | { 54 | int n = 0; 55 | int64_t* ts = calloc(total, sizeof(int64_t)); 56 | char l[BUFSIZ]; 57 | 58 | if (!ts) { 59 | return 0; 60 | } 61 | 62 | while ((fgets(l, BUFSIZ - 1, f) != NULL) && n < total) { 63 | if (l[0] == 0 || l[0] == '\n' || l[0] == '\r' || l[0] == '#') 64 | continue; 65 | 66 | ts[n++] = atoll(l); 67 | } 68 | 69 | if (n < total) { 70 | free(ts); 71 | return 0; 72 | } 73 | 74 | ud->timestamp = ts; 75 | 76 | return 1; 77 | } 78 | -------------------------------------------------------------------------------- /src/timecodes.h: -------------------------------------------------------------------------------- 1 | #ifndef _TIMECODE_H_ 2 | #define _TIMECODE_H_ 3 | 4 | #include "assrender.h" 5 | 6 | int parse_timecodesv1(FILE* f, int total, udata* ud); 7 | 8 | int parse_timecodesv2(FILE* f, int total, udata* ud); 9 | 10 | #endif 11 | --------------------------------------------------------------------------------