diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..b88a67a --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: weekly diff --git a/.github/workflows/check-smp.yml b/.github/workflows/check-smp.yml deleted file mode 100644 index b0cdc19..0000000 --- a/.github/workflows/check-smp.yml +++ /dev/null @@ -1,84 +0,0 @@ -name: Update data -on: - push: - branches: - - main - schedule: - - cron: '0 5 * * *' - workflow_dispatch: # - -env: - submodule_owner: ShiftMediaProject - submodule_folder: SMP - -jobs: - check_smp: - runs-on: ubuntu-latest - strategy: - matrix: - submodule: - - fontconfig - - freetype2 - - fribidi - - harfbuzz - - libass - - libiconv - - liblzma - - libxml2 - - zlib - steps: - - name: Git checkout - uses: actions/checkout@v3 - with: - ref: master - - name: Set submodule current - run: | - git submodule update --init --recursive "${{ env.submodule_folder }}/${{ matrix.submodule }}" - cd ${{ env.submodule_folder }}/${{ matrix.submodule }} - echo SUBMODULE_NAME=${{ matrix.submodule }} >> $GITHUB_ENV - echo SUBMODULE_REV=$(git describe --tags --first-parent --abbrev=7 --long --dirty) >> $GITHUB_ENV - echo SUBMODULE_SHA=$(git rev-parse HEAD) >> $GITHUB_ENV - - name: Get submodule current remote - id: current - uses: cardinalby/git-get-release-action@1.2.2 - env: - GITHUB_TOKEN: ${{ github.token }} - with: - repo: ${{ env.submodule_owner }}/${{ matrix.submodule }} - commitSha: ${{ env.SUBMODULE_SHA }} - doNotFailIfNotFound: true - - name: Get submodule latest remote - id: latest - uses: cardinalby/git-get-release-action@1.2.2 - env: - GITHUB_TOKEN: ${{ github.token }} - with: - repo: ${{ env.submodule_owner }}/${{ matrix.submodule }} - latest: true - prerelease: false - doNotFailIfNotFound: true - - name: Set submodule current remote - if: steps.current.outputs.tag_name != '' - run: echo SUBMODULE_REV=${{ steps.current.outputs.tag_name }} >> $GITHUB_ENV - - name: Check if need update - if: | - steps.latest.outputs.tag_name != '' && - steps.current.outputs.tag_name == '' || - steps.latest.outputs.tag_name != '' && - steps.current.outputs.tag_name != steps.latest.outputs.tag_name - run: | - cd ${{ env.submodule_folder }}/${{ matrix.submodule }} - git checkout ${{ steps.latest.outputs.tag_name }} - echo NEED_UPDATE=1 >> $GITHUB_ENV - - name: Run update - if: ${{ env.NEED_UPDATE }} == '1' - uses: peter-evans/create-pull-request@v4 - with: - commit-message: Update ${{ matrix.submodule }} to ${{ steps.latest.outputs.tag_name }} - branch: submodule-${{ matrix.submodule }}-${{ steps.latest.outputs.tag_name }} - base: master - delete-branch: true - title: Update ${{ matrix.submodule }} to ${{ steps.latest.outputs.tag_name }} - body: | - Update ${{ matrix.submodule }} to ${{ steps.latest.outputs.tag_name }} - Current: ${{ env.SUBMODULE_REV }} diff --git a/.github/workflows/github-ci.yml b/.github/workflows/github-ci.yml index 5665cd5..53f18d8 100644 --- a/.github/workflows/github-ci.yml +++ b/.github/workflows/github-ci.yml @@ -5,101 +5,136 @@ on: pull_request: workflow_dispatch: # +env: + ass_repo: https://github.com/libass/libass + ass_ver: 0.17.4 + avs_repo: https://github.com/AviSynth/AviSynthPlus + avs_ver: 3.7.5 + avs_date: 20250420 + jobs: build-linux: runs-on: ubuntu-latest steps: - name: Git checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install dependencies run: | - sudo apt-get update - sudo apt-get install cmake git ninja-build checkinstall - sudo apt-get install -y --no-install-recommends build-essential g++ gcc libass-dev pkg-config - git clone https://github.com/AviSynth/AviSynthPlus avsplus - cd avsplus - cmake -G "Ninja" -B avisynth-build -S . - cd avisynth-build - ninja - 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 - - name: Build binary + sudo apt-get update && sudo apt-get install -y ninja-build nasm libfontconfig1-dev meson + + git clone ${{ env.avs_repo }}.git -b v${{ env.avs_ver }} --depth=1 avsplus + + cd ./avsplus + cmake -DCMAKE_INSTALL_PREFIX=/usr/local -S . -B avisynth-build + cmake --build avisynth-build --config Release -j 2 + sudo cmake --install avisynth-build --config Release + cd .. + + git clone ${{ env.ass_repo }}.git -b ${{ env.ass_ver }} --depth=1 libass + + cd ./libass + meson wrap update-db + meson wrap install fribidi + meson wrap install freetype2 + meson wrap install expat + meson wrap install harfbuzz + meson wrap install libpng + meson wrap install zlib + + meson setup build -Ddefault_library=static -Dbuildtype=release -Dasm=enabled -Dc_std=c11 -Dcpp_std=c++17 + meson compile -C build + sudo meson install -C build + - name: Build & Save binary run: | cmake -B build -S . cmake --build build --clean-first - - name: Copy binary - run: cmake -E copy "build/src/libassrender.so" "dist/libassrender.so" + cmake -E copy "build/src/libassrender.so" "dist/libassrender.so" - name: Upload artifact - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: assrender_bin_linux path: dist build-win: - runs-on: windows-2019 + runs-on: windows-latest steps: - name: Git checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install dependencies run: | - git submodule update --init --recursive - git clone https://github.com/ShiftMediaProject/VSYASM.git - .\VSYASM\install_script.bat - git clone https://github.com/ShiftMediaProject/VSNASM.git - .\VSNASM\install_script.bat - md avsplus - # - name: Install MSYS2 with dependencies - # uses: msys2/setup-msys2@v2 - # with: - # update: true - # install: base-devel git mingw-w64-x86_64-gcc mingw-w64-x86_64-cmake mingw-w64-x86_64-libass - # msystem: MINGW64 - # path-type: inherit - - name: Parse AviSynth+ release metadata - uses: actions/github-script@v6 - with: - script: | - const req = await github.request('https://api.github.com/repos/avisynth/avisynthplus/releases'); - const data = req.data; - let link = ''; - for(let rel of data){ - if(rel.prerelease||rel.draft){ - continue; - } - for(let asset of rel.assets){ - if(asset.name.match(/-filesonly.7z$/i)){ - link = asset.browser_download_url; - } - } - if(link != ''){ - break; - } - } - core.exportVariable('PACKAGE_URL', link); - - name: Download AviSynth+ latest release - run: curl -L "${{ env.PACKAGE_URL }}" -o "./avsplus/avisynthplus-latest-filesonly.7z" - - name: Move libs files - run: | + choco install ninja nasm pkgconfiglite + + python -m pip install --upgrade pip + pip install meson + + curl -L "${{ env.avs_repo }}/releases/download/v${{ env.avs_ver }}/AviSynthPlus_${{ env.avs_ver }}_${{ env.avs_date }}-filesonly.7z" ` + --create-dirs -o "./avsplus/avisynthplus-latest-filesonly.7z" 7z e "avsplus\*-filesonly.7z" -o"lib\x86-32" "*\x86\c_api\AviSynth.lib" 7z e "avsplus\*-filesonly.7z" -o"lib\x86-64" "*\x64\c_api\AviSynth.lib" - - name: Add MSBuild to PATH - uses: microsoft/setup-msbuild@v1 - - name: Build x86 binary - run: MSBuild.exe /t:Rebuild /p:PlatformToolset=v142 /m /p:Configuration=Release /p:Platform=x86 - - name: Build x64 binary - run: MSBuild.exe /t:Rebuild /p:PlatformToolset=v142 /m /p:Configuration=Release /p:Platform=x64 - # - name: Build MINGW64 binary - # shell: msys2 {0} - # run: | - # cmake -G "MinGW Makefiles" -B build -S . - # cmake --build build --config Release --clean-first - - name: Copy x86 binary - run: cmake -E copy "bin\Release_Win32\assrender.dll" "dist\Release_x86\assrender.dll" - - name: Copy x64 binary - run: cmake -E copy "bin\Release_x64\assrender.dll" "dist\Release_x64\assrender.dll" - # - name: Copy MINGW64 binary - # run: cmake -E copy "build\src\assrender.dll" "dist\Release_MINGW64\assrender.dll" + + git clone ${{ env.ass_repo }}.git -b ${{ env.ass_ver }} --depth=1 libass + + cd ./libass + meson wrap update-db + meson wrap install fribidi + meson wrap install fontconfig + meson wrap install freetype2 + meson wrap install expat + meson wrap install harfbuzz + meson wrap install libpng + meson wrap install zlib + - name: Setup MSVC (x64) + uses: ilammy/msvc-dev-cmd@v1 + with: + arch: x64 + - name: Meson + CMake build (x64) + env: + PKG_CONFIG_PATH: C:/assdeps/x64/lib/pkgconfig + run: | + cd libass + meson setup build_x64 ` + --prefix "C:/assdeps/x64" ` + --libdir "lib" ` + -Ddefault_library=static ` + -Dbuildtype=release ` + -Dasm=enabled ` + -Db_vscrt=static_from_buildtype ` + -Dc_std=c11 ` + -Dcpp_std=c++17 + meson compile -C build_x64 + meson install -C build_x64 + cd .. + + cmake -D CMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded -A x64 -S . -B build_x64 + msbuild /t:Rebuild /m /p:Configuration=Release /p:Platform=x64 ".\build_x64\assrender.sln" + cmake -E copy "build_x64\src\Release\assrender.dll" "dist\Release_x64\assrender.dll" + - name: Setup MSVC (Win32) + uses: ilammy/msvc-dev-cmd@v1 + with: + arch: x86 + - name: Meson + CMake build (Win32) + env: + PKG_CONFIG_PATH: C:/assdeps/x86/lib/pkgconfig + run: | + cd libass + meson setup build_Win32 ` + --prefix "C:/assdeps/x86" ` + --libdir "lib" ` + -Ddefault_library=static ` + -Dbuildtype=release ` + -Dasm=enabled ` + -Db_vscrt=static_from_buildtype ` + -Dc_std=c11 ` + -Dcpp_std=c++17 + meson compile -C build_Win32 + meson install -C build_Win32 + cd .. + + cmake -D CMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded -A Win32 -S . -B build_Win32 + msbuild /t:Rebuild /m /p:Configuration=Release /p:Platform=Win32 ".\build_Win32\assrender.sln" + cmake -E copy "build_Win32\src\Release\assrender.dll" "dist\Release_Win32\assrender.dll" - name: Upload artifact - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: assrender_bin_win path: dist diff --git a/.gitignore b/.gitignore index 5e66065..bc97daa 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ lib/*/avisynth.lib +*.7z CMakeCache.txt CMakeFiles/* @@ -11,6 +12,8 @@ cmake.db *.sdf *.suo *.user +*.wrap +wrapdb.json #cmake generated files cmake_install.cmake cmake_uninstall.cmake @@ -25,8 +28,11 @@ avsplus/ SMP/ VSNASM/ VSYASM/ +libass* +testbuild.bat #*/build/.vs +build/* */build/Win32 */build/x64 Test diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 70fb190..0000000 --- a/.gitmodules +++ /dev/null @@ -1,30 +0,0 @@ -[submodule "SMP/libass"] - path = SMP/libass - url = https://github.com/ShiftMediaProject/libass.git -[submodule "SMP/libiconv"] - path = SMP/libiconv - url = https://github.com/ShiftMediaProject/libiconv.git -[submodule "SMP/harfbuzz"] - path = SMP/harfbuzz - url = https://github.com/ShiftMediaProject/harfbuzz.git -[submodule "SMP/fontconfig"] - path = SMP/fontconfig - url = https://github.com/ShiftMediaProject/fontconfig.git -[submodule "SMP/freetype2"] - path = SMP/freetype2 - url = https://github.com/ShiftMediaProject/freetype2.git -[submodule "SMP/libxml2"] - path = SMP/libxml2 - url = https://github.com/ShiftMediaProject/libxml2.git -[submodule "fribidi"] - path = fribidi - url = https://github.com/ShiftMediaProject/fribidi.git -[submodule "SMP/fribidi"] - path = SMP/fribidi - url = https://github.com/ShiftMediaProject/fribidi.git -[submodule "SMP/liblzma"] - path = SMP/liblzma - url = https://github.com/ShiftMediaProject/liblzma.git -[submodule "SMP/zlib"] - path = SMP/zlib - url = https://github.com/ShiftMediaProject/zlib.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 901642b..ff37af4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,16 +1,15 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 3.12) -PROJECT(assrender) +cmake_minimum_required(VERSION 3.15) +project(assrender) include(GNUInstallDirs) -ADD_SUBDIRECTORY(src) +if(MINGW) + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-libgcc -Wl,--add-stdcall-alias") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -Wpedantic") + set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "-s") +endif() -IF(MINGW) - SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-libgcc -Wl,--add-stdcall-alias") - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -Wpedantic") - SET(CMAKE_SHARED_LINKER_FLAGS_RELEASE "-s") - SET(CMAKE_C_FLAGS_RELEASE "-O3") -ENDIF() +add_subdirectory(src) # uninstall target configure_file( diff --git a/SMP/fontconfig b/SMP/fontconfig deleted file mode 160000 index 9494f72..0000000 --- a/SMP/fontconfig +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 9494f72785e90425e05d0a04e44c0f65f5f42d17 diff --git a/SMP/freetype2 b/SMP/freetype2 deleted file mode 160000 index af28639..0000000 --- a/SMP/freetype2 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit af286399587d3351c04c3b9072ed018e8b445550 diff --git a/SMP/fribidi b/SMP/fribidi deleted file mode 160000 index 3098731..0000000 --- a/SMP/fribidi +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 30987310c395a48ccd61e34357bd8de8055a095d diff --git a/SMP/harfbuzz b/SMP/harfbuzz deleted file mode 160000 index d78c270..0000000 --- a/SMP/harfbuzz +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d78c270f0f016cb297ac1de5d54cedc3cd7f8fe3 diff --git a/SMP/libass b/SMP/libass deleted file mode 160000 index 1e35ba9..0000000 --- a/SMP/libass +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1e35ba9573476dcd51d1115230651b5ee3fc1052 diff --git a/SMP/libiconv b/SMP/libiconv deleted file mode 160000 index 2b0ab07..0000000 --- a/SMP/libiconv +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2b0ab07e1069d1934298395e497e8177710102ac diff --git a/SMP/liblzma b/SMP/liblzma deleted file mode 160000 index 049434b..0000000 --- a/SMP/liblzma +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 049434b955bf59e725d64baa9ea7aeb2971801d9 diff --git a/SMP/libxml2 b/SMP/libxml2 deleted file mode 160000 index c853c26..0000000 --- a/SMP/libxml2 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c853c26f459dfe584d875f5378ea8dc1f635353a diff --git a/SMP/zlib b/SMP/zlib deleted file mode 160000 index dd62a8b..0000000 --- a/SMP/zlib +++ /dev/null @@ -1 +0,0 @@ -Subproject commit dd62a8b7f89469e3f53d5d5744e41fa29f383b3c diff --git a/assrender.sln b/assrender.sln deleted file mode 100644 index c4bc502..0000000 --- a/assrender.sln +++ /dev/null @@ -1,353 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "assrender", "assrender.vcxproj", "{A8A845C1-48C9-4D03-8D1D-6A6C023EE319}" - ProjectSection(ProjectDependencies) = postProject - {19677DFD-C020-434D-9CB1-D0F105E72770} = {19677DFD-C020-434D-9CB1-D0F105E72770} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libfontconfig", "SMP\fontconfig\SMP\libfontconfig.vcxproj", "{DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}" - ProjectSection(ProjectDependencies) = postProject - {E62DC439-DE3B-4F2F-84DF-B34E51FA1969} = {E62DC439-DE3B-4F2F-84DF-B34E51FA1969} - {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B} = {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B} - {CFE70273-7A79-4815-AF95-1E02E2675E37} = {CFE70273-7A79-4815-AF95-1E02E2675E37} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libfreetype2", "SMP\freetype2\SMP\libfreetype2.vcxproj", "{E62DC439-DE3B-4F2F-84DF-B34E51FA1969}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libfribidi", "SMP\fribidi\SMP\libfribidi.vcxproj", "{08091723-A142-478B-A092-20741BA8FAE2}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libharfbuzz", "SMP\harfbuzz\SMP\libharfbuzz.vcxproj", "{9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}" - ProjectSection(ProjectDependencies) = postProject - {E62DC439-DE3B-4F2F-84DF-B34E51FA1969} = {E62DC439-DE3B-4F2F-84DF-B34E51FA1969} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libass", "SMP\libass\SMP\libass.vcxproj", "{19677DFD-C020-434D-9CB1-D0F105E72770}" - ProjectSection(ProjectDependencies) = postProject - {08091723-A142-478B-A092-20741BA8FAE2} = {08091723-A142-478B-A092-20741BA8FAE2} - {E62DC439-DE3B-4F2F-84DF-B34E51FA1969} = {E62DC439-DE3B-4F2F-84DF-B34E51FA1969} - {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B} = {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B} - {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF} = {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF} - {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC} = {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libiconv", "SMP\libiconv\SMP\libiconv.vcxproj", "{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "liblzma", "SMP\liblzma\SMP\liblzma.vcxproj", "{85763F39-23DF-4C04-B7DF-7FBE3E7CF336}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxml2", "SMP\libxml2\SMP\libxml2.vcxproj", "{CFE70273-7A79-4815-AF95-1E02E2675E37}" - ProjectSection(ProjectDependencies) = postProject - {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32} = {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32} - {85763F39-23DF-4C04-B7DF-7FBE3E7CF336} = {85763F39-23DF-4C04-B7DF-7FBE3E7CF336} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libzlib", "SMP\zlib\SMP\libzlib.vcxproj", "{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - DebugDLL|x64 = DebugDLL|x64 - DebugDLL|x86 = DebugDLL|x86 - DebugDLLStaticDeps|x64 = DebugDLLStaticDeps|x64 - DebugDLLStaticDeps|x86 = DebugDLLStaticDeps|x86 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - ReleaseDLL|x64 = ReleaseDLL|x64 - ReleaseDLL|x86 = ReleaseDLL|x86 - ReleaseDLLStaticDeps|x64 = ReleaseDLLStaticDeps|x64 - ReleaseDLLStaticDeps|x86 = ReleaseDLLStaticDeps|x86 - ReleaseLTO|x64 = ReleaseLTO|x64 - ReleaseLTO|x86 = ReleaseLTO|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.Debug|x64.ActiveCfg = Debug|x64 - {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.Debug|x64.Build.0 = Debug|x64 - {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.Debug|x86.ActiveCfg = Debug|Win32 - {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.Debug|x86.Build.0 = Debug|Win32 - {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.DebugDLL|x64.ActiveCfg = Debug|x64 - {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.DebugDLL|x64.Build.0 = Debug|x64 - {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.DebugDLL|x86.ActiveCfg = Debug|Win32 - {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.DebugDLL|x86.Build.0 = Debug|Win32 - {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.DebugDLLStaticDeps|x64.ActiveCfg = Debug|x64 - {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.DebugDLLStaticDeps|x64.Build.0 = Debug|x64 - {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.DebugDLLStaticDeps|x86.ActiveCfg = Debug|Win32 - {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.DebugDLLStaticDeps|x86.Build.0 = Debug|Win32 - {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.Release|x64.ActiveCfg = Release|x64 - {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.Release|x64.Build.0 = Release|x64 - {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.Release|x86.ActiveCfg = Release|Win32 - {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.Release|x86.Build.0 = Release|Win32 - {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.ReleaseDLL|x64.ActiveCfg = Release|x64 - {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.ReleaseDLL|x64.Build.0 = Release|x64 - {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.ReleaseDLL|x86.ActiveCfg = Release|Win32 - {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.ReleaseDLL|x86.Build.0 = Release|Win32 - {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.ReleaseDLLStaticDeps|x64.ActiveCfg = Release|x64 - {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.ReleaseDLLStaticDeps|x64.Build.0 = Release|x64 - {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.ReleaseDLLStaticDeps|x86.ActiveCfg = Release|Win32 - {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.ReleaseDLLStaticDeps|x86.Build.0 = Release|Win32 - {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.ReleaseLTO|x64.ActiveCfg = Release|x64 - {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.ReleaseLTO|x64.Build.0 = Release|x64 - {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.ReleaseLTO|x86.ActiveCfg = Release|Win32 - {A8A845C1-48C9-4D03-8D1D-6A6C023EE319}.ReleaseLTO|x86.Build.0 = Release|Win32 - {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.Debug|x64.ActiveCfg = Debug|x64 - {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.Debug|x64.Build.0 = Debug|x64 - {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.Debug|x86.ActiveCfg = Debug|Win32 - {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.Debug|x86.Build.0 = Debug|Win32 - {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 - {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.DebugDLL|x64.Build.0 = DebugDLL|x64 - {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32 - {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.DebugDLL|x86.Build.0 = DebugDLL|Win32 - {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLLWinRT|x64 - {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.DebugDLLStaticDeps|x64.Build.0 = DebugDLLWinRT|x64 - {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLLWinRT|Win32 - {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.DebugDLLStaticDeps|x86.Build.0 = DebugDLLWinRT|Win32 - {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.Release|x64.ActiveCfg = Release|x64 - {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.Release|x64.Build.0 = Release|x64 - {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.Release|x86.ActiveCfg = Release|Win32 - {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.Release|x86.Build.0 = Release|Win32 - {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 - {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 - {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32 - {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32 - {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLLStaticDeps|x64 - {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLLStaticDeps|x64 - {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLLStaticDeps|Win32 - {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLLStaticDeps|Win32 - {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.ReleaseLTO|x64.ActiveCfg = ReleaseWinRT|x64 - {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.ReleaseLTO|x64.Build.0 = ReleaseWinRT|x64 - {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.ReleaseLTO|x86.ActiveCfg = ReleaseWinRT|Win32 - {DBF1E8F7-5B7D-4CBF-842A-B7E0C02520DC}.ReleaseLTO|x86.Build.0 = ReleaseWinRT|Win32 - {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.Debug|x64.ActiveCfg = Debug|x64 - {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.Debug|x64.Build.0 = Debug|x64 - {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.Debug|x86.ActiveCfg = Debug|Win32 - {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.Debug|x86.Build.0 = Debug|Win32 - {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 - {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.DebugDLL|x64.Build.0 = DebugDLL|x64 - {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32 - {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.DebugDLL|x86.Build.0 = DebugDLL|Win32 - {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLL|x64 - {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.DebugDLLStaticDeps|x64.Build.0 = DebugDLL|x64 - {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLL|Win32 - {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.DebugDLLStaticDeps|x86.Build.0 = DebugDLL|Win32 - {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.Release|x64.ActiveCfg = Release|x64 - {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.Release|x64.Build.0 = Release|x64 - {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.Release|x86.ActiveCfg = Release|Win32 - {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.Release|x86.Build.0 = Release|Win32 - {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 - {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 - {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32 - {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32 - {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLL|x64 - {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLL|x64 - {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLL|Win32 - {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLL|Win32 - {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.ReleaseLTO|x64.ActiveCfg = ReleaseWinRT|x64 - {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.ReleaseLTO|x64.Build.0 = ReleaseWinRT|x64 - {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.ReleaseLTO|x86.ActiveCfg = ReleaseWinRT|Win32 - {E62DC439-DE3B-4F2F-84DF-B34E51FA1969}.ReleaseLTO|x86.Build.0 = ReleaseWinRT|Win32 - {08091723-A142-478B-A092-20741BA8FAE2}.Debug|x64.ActiveCfg = Debug|x64 - {08091723-A142-478B-A092-20741BA8FAE2}.Debug|x64.Build.0 = Debug|x64 - {08091723-A142-478B-A092-20741BA8FAE2}.Debug|x86.ActiveCfg = Debug|Win32 - {08091723-A142-478B-A092-20741BA8FAE2}.Debug|x86.Build.0 = Debug|Win32 - {08091723-A142-478B-A092-20741BA8FAE2}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 - {08091723-A142-478B-A092-20741BA8FAE2}.DebugDLL|x64.Build.0 = DebugDLL|x64 - {08091723-A142-478B-A092-20741BA8FAE2}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32 - {08091723-A142-478B-A092-20741BA8FAE2}.DebugDLL|x86.Build.0 = DebugDLL|Win32 - {08091723-A142-478B-A092-20741BA8FAE2}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLL|x64 - {08091723-A142-478B-A092-20741BA8FAE2}.DebugDLLStaticDeps|x64.Build.0 = DebugDLL|x64 - {08091723-A142-478B-A092-20741BA8FAE2}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLL|Win32 - {08091723-A142-478B-A092-20741BA8FAE2}.DebugDLLStaticDeps|x86.Build.0 = DebugDLL|Win32 - {08091723-A142-478B-A092-20741BA8FAE2}.Release|x64.ActiveCfg = Release|x64 - {08091723-A142-478B-A092-20741BA8FAE2}.Release|x64.Build.0 = Release|x64 - {08091723-A142-478B-A092-20741BA8FAE2}.Release|x86.ActiveCfg = Release|Win32 - {08091723-A142-478B-A092-20741BA8FAE2}.Release|x86.Build.0 = Release|Win32 - {08091723-A142-478B-A092-20741BA8FAE2}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 - {08091723-A142-478B-A092-20741BA8FAE2}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 - {08091723-A142-478B-A092-20741BA8FAE2}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32 - {08091723-A142-478B-A092-20741BA8FAE2}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32 - {08091723-A142-478B-A092-20741BA8FAE2}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLL|x64 - {08091723-A142-478B-A092-20741BA8FAE2}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLL|x64 - {08091723-A142-478B-A092-20741BA8FAE2}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLL|Win32 - {08091723-A142-478B-A092-20741BA8FAE2}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLL|Win32 - {08091723-A142-478B-A092-20741BA8FAE2}.ReleaseLTO|x64.ActiveCfg = ReleaseWinRT|x64 - {08091723-A142-478B-A092-20741BA8FAE2}.ReleaseLTO|x64.Build.0 = ReleaseWinRT|x64 - {08091723-A142-478B-A092-20741BA8FAE2}.ReleaseLTO|x86.ActiveCfg = ReleaseWinRT|Win32 - {08091723-A142-478B-A092-20741BA8FAE2}.ReleaseLTO|x86.Build.0 = ReleaseWinRT|Win32 - {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.Debug|x64.ActiveCfg = Debug|x64 - {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.Debug|x64.Build.0 = Debug|x64 - {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.Debug|x86.ActiveCfg = Debug|Win32 - {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.Debug|x86.Build.0 = Debug|Win32 - {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 - {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.DebugDLL|x64.Build.0 = DebugDLL|x64 - {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32 - {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.DebugDLL|x86.Build.0 = DebugDLL|Win32 - {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLLWinRT|x64 - {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.DebugDLLStaticDeps|x64.Build.0 = DebugDLLWinRT|x64 - {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLLWinRT|Win32 - {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.DebugDLLStaticDeps|x86.Build.0 = DebugDLLWinRT|Win32 - {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.Release|x64.ActiveCfg = Release|x64 - {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.Release|x64.Build.0 = Release|x64 - {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.Release|x86.ActiveCfg = Release|Win32 - {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.Release|x86.Build.0 = Release|Win32 - {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 - {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 - {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32 - {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32 - {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLLStaticDeps|x64 - {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLLStaticDeps|x64 - {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLLStaticDeps|Win32 - {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLLStaticDeps|Win32 - {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.ReleaseLTO|x64.ActiveCfg = ReleaseWinRT|x64 - {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.ReleaseLTO|x64.Build.0 = ReleaseWinRT|x64 - {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.ReleaseLTO|x86.ActiveCfg = ReleaseWinRT|Win32 - {9DB795B7-E8BD-4846-82A5-C6D2577B1AAF}.ReleaseLTO|x86.Build.0 = ReleaseWinRT|Win32 - {19677DFD-C020-434D-9CB1-D0F105E72770}.Debug|x64.ActiveCfg = Debug|x64 - {19677DFD-C020-434D-9CB1-D0F105E72770}.Debug|x64.Build.0 = Debug|x64 - {19677DFD-C020-434D-9CB1-D0F105E72770}.Debug|x86.ActiveCfg = Debug|Win32 - {19677DFD-C020-434D-9CB1-D0F105E72770}.Debug|x86.Build.0 = Debug|Win32 - {19677DFD-C020-434D-9CB1-D0F105E72770}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 - {19677DFD-C020-434D-9CB1-D0F105E72770}.DebugDLL|x64.Build.0 = DebugDLL|x64 - {19677DFD-C020-434D-9CB1-D0F105E72770}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32 - {19677DFD-C020-434D-9CB1-D0F105E72770}.DebugDLL|x86.Build.0 = DebugDLL|Win32 - {19677DFD-C020-434D-9CB1-D0F105E72770}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLLWinRT|x64 - {19677DFD-C020-434D-9CB1-D0F105E72770}.DebugDLLStaticDeps|x64.Build.0 = DebugDLLWinRT|x64 - {19677DFD-C020-434D-9CB1-D0F105E72770}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLLWinRT|Win32 - {19677DFD-C020-434D-9CB1-D0F105E72770}.DebugDLLStaticDeps|x86.Build.0 = DebugDLLWinRT|Win32 - {19677DFD-C020-434D-9CB1-D0F105E72770}.Release|x64.ActiveCfg = Release|x64 - {19677DFD-C020-434D-9CB1-D0F105E72770}.Release|x64.Build.0 = Release|x64 - {19677DFD-C020-434D-9CB1-D0F105E72770}.Release|x86.ActiveCfg = Release|Win32 - {19677DFD-C020-434D-9CB1-D0F105E72770}.Release|x86.Build.0 = Release|Win32 - {19677DFD-C020-434D-9CB1-D0F105E72770}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 - {19677DFD-C020-434D-9CB1-D0F105E72770}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 - {19677DFD-C020-434D-9CB1-D0F105E72770}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32 - {19677DFD-C020-434D-9CB1-D0F105E72770}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32 - {19677DFD-C020-434D-9CB1-D0F105E72770}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLLStaticDeps|x64 - {19677DFD-C020-434D-9CB1-D0F105E72770}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLLStaticDeps|x64 - {19677DFD-C020-434D-9CB1-D0F105E72770}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLLStaticDeps|Win32 - {19677DFD-C020-434D-9CB1-D0F105E72770}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLLStaticDeps|Win32 - {19677DFD-C020-434D-9CB1-D0F105E72770}.ReleaseLTO|x64.ActiveCfg = ReleaseWinRT|x64 - {19677DFD-C020-434D-9CB1-D0F105E72770}.ReleaseLTO|x64.Build.0 = ReleaseWinRT|x64 - {19677DFD-C020-434D-9CB1-D0F105E72770}.ReleaseLTO|x86.ActiveCfg = ReleaseWinRT|Win32 - {19677DFD-C020-434D-9CB1-D0F105E72770}.ReleaseLTO|x86.Build.0 = ReleaseWinRT|Win32 - {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Debug|x64.ActiveCfg = Debug|x64 - {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Debug|x64.Build.0 = Debug|x64 - {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Debug|x86.ActiveCfg = Debug|Win32 - {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Debug|x86.Build.0 = Debug|Win32 - {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 - {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLL|x64.Build.0 = DebugDLL|x64 - {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32 - {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLL|x86.Build.0 = DebugDLL|Win32 - {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLL|x64 - {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLLStaticDeps|x64.Build.0 = DebugDLL|x64 - {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLL|Win32 - {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLLStaticDeps|x86.Build.0 = DebugDLL|Win32 - {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Release|x64.ActiveCfg = Release|x64 - {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Release|x64.Build.0 = Release|x64 - {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Release|x86.ActiveCfg = Release|Win32 - {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Release|x86.Build.0 = Release|Win32 - {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 - {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 - {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32 - {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32 - {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLL|x64 - {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLL|x64 - {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLL|Win32 - {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLL|Win32 - {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseLTO|x64.ActiveCfg = ReleaseWinRT|x64 - {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseLTO|x64.Build.0 = ReleaseWinRT|x64 - {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseLTO|x86.ActiveCfg = ReleaseWinRT|Win32 - {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseLTO|x86.Build.0 = ReleaseWinRT|Win32 - {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.Debug|x64.ActiveCfg = Debug|x64 - {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.Debug|x64.Build.0 = Debug|x64 - {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.Debug|x86.ActiveCfg = Debug|Win32 - {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.Debug|x86.Build.0 = Debug|Win32 - {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 - {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.DebugDLL|x64.Build.0 = DebugDLL|x64 - {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32 - {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.DebugDLL|x86.Build.0 = DebugDLL|Win32 - {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLL|x64 - {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.DebugDLLStaticDeps|x64.Build.0 = DebugDLL|x64 - {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLL|Win32 - {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.DebugDLLStaticDeps|x86.Build.0 = DebugDLL|Win32 - {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.Release|x64.ActiveCfg = Release|x64 - {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.Release|x64.Build.0 = Release|x64 - {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.Release|x86.ActiveCfg = Release|Win32 - {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.Release|x86.Build.0 = Release|Win32 - {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 - {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 - {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32 - {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32 - {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLL|x64 - {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLL|x64 - {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLL|Win32 - {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLL|Win32 - {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.ReleaseLTO|x64.ActiveCfg = ReleaseWinRT|x64 - {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.ReleaseLTO|x64.Build.0 = ReleaseWinRT|x64 - {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.ReleaseLTO|x86.ActiveCfg = ReleaseWinRT|Win32 - {85763F39-23DF-4C04-B7DF-7FBE3E7CF336}.ReleaseLTO|x86.Build.0 = ReleaseWinRT|Win32 - {CFE70273-7A79-4815-AF95-1E02E2675E37}.Debug|x64.ActiveCfg = Debug|x64 - {CFE70273-7A79-4815-AF95-1E02E2675E37}.Debug|x64.Build.0 = Debug|x64 - {CFE70273-7A79-4815-AF95-1E02E2675E37}.Debug|x86.ActiveCfg = Debug|Win32 - {CFE70273-7A79-4815-AF95-1E02E2675E37}.Debug|x86.Build.0 = Debug|Win32 - {CFE70273-7A79-4815-AF95-1E02E2675E37}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 - {CFE70273-7A79-4815-AF95-1E02E2675E37}.DebugDLL|x64.Build.0 = DebugDLL|x64 - {CFE70273-7A79-4815-AF95-1E02E2675E37}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32 - {CFE70273-7A79-4815-AF95-1E02E2675E37}.DebugDLL|x86.Build.0 = DebugDLL|Win32 - {CFE70273-7A79-4815-AF95-1E02E2675E37}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLLWinRT|x64 - {CFE70273-7A79-4815-AF95-1E02E2675E37}.DebugDLLStaticDeps|x64.Build.0 = DebugDLLWinRT|x64 - {CFE70273-7A79-4815-AF95-1E02E2675E37}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLLWinRT|Win32 - {CFE70273-7A79-4815-AF95-1E02E2675E37}.DebugDLLStaticDeps|x86.Build.0 = DebugDLLWinRT|Win32 - {CFE70273-7A79-4815-AF95-1E02E2675E37}.Release|x64.ActiveCfg = Release|x64 - {CFE70273-7A79-4815-AF95-1E02E2675E37}.Release|x64.Build.0 = Release|x64 - {CFE70273-7A79-4815-AF95-1E02E2675E37}.Release|x86.ActiveCfg = Release|Win32 - {CFE70273-7A79-4815-AF95-1E02E2675E37}.Release|x86.Build.0 = Release|Win32 - {CFE70273-7A79-4815-AF95-1E02E2675E37}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 - {CFE70273-7A79-4815-AF95-1E02E2675E37}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 - {CFE70273-7A79-4815-AF95-1E02E2675E37}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32 - {CFE70273-7A79-4815-AF95-1E02E2675E37}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32 - {CFE70273-7A79-4815-AF95-1E02E2675E37}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLLStaticDeps|x64 - {CFE70273-7A79-4815-AF95-1E02E2675E37}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLLStaticDeps|x64 - {CFE70273-7A79-4815-AF95-1E02E2675E37}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLLStaticDeps|Win32 - {CFE70273-7A79-4815-AF95-1E02E2675E37}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLLStaticDeps|Win32 - {CFE70273-7A79-4815-AF95-1E02E2675E37}.ReleaseLTO|x64.ActiveCfg = ReleaseWinRT|x64 - {CFE70273-7A79-4815-AF95-1E02E2675E37}.ReleaseLTO|x64.Build.0 = ReleaseWinRT|x64 - {CFE70273-7A79-4815-AF95-1E02E2675E37}.ReleaseLTO|x86.ActiveCfg = ReleaseWinRT|Win32 - {CFE70273-7A79-4815-AF95-1E02E2675E37}.ReleaseLTO|x86.Build.0 = ReleaseWinRT|Win32 - {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Debug|x64.ActiveCfg = Debug|x64 - {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Debug|x64.Build.0 = Debug|x64 - {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Debug|x86.ActiveCfg = Debug|Win32 - {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Debug|x86.Build.0 = Debug|Win32 - {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 - {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLL|x64.Build.0 = DebugDLL|x64 - {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32 - {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLL|x86.Build.0 = DebugDLL|Win32 - {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLL|x64 - {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLLStaticDeps|x64.Build.0 = DebugDLL|x64 - {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLL|Win32 - {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLLStaticDeps|x86.Build.0 = DebugDLL|Win32 - {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Release|x64.ActiveCfg = Release|x64 - {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Release|x64.Build.0 = Release|x64 - {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Release|x86.ActiveCfg = Release|Win32 - {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Release|x86.Build.0 = Release|Win32 - {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 - {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 - {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32 - {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32 - {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLL|x64 - {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLL|x64 - {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLL|Win32 - {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLL|Win32 - {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseLTO|x64.ActiveCfg = ReleaseWinRT|x64 - {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseLTO|x64.Build.0 = ReleaseWinRT|x64 - {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseLTO|x86.ActiveCfg = ReleaseWinRT|Win32 - {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseLTO|x86.Build.0 = ReleaseWinRT|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {77479689-0075-4EB6-8C55-A03013A8AFFF} - EndGlobalSection -EndGlobal diff --git a/assrender.vcxproj b/assrender.vcxproj deleted file mode 100644 index 8d24c49..0000000 --- a/assrender.vcxproj +++ /dev/null @@ -1,191 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - {A8A845C1-48C9-4D03-8D1D-6A6C023EE319} - Win32Proj - assrender - 10.0 - - - - DynamicLibrary - true - v142 - Unicode - - - DynamicLibrary - false - v142 - true - Unicode - - - DynamicLibrary - true - v142 - Unicode - - - DynamicLibrary - false - v142 - true - Unicode - - - - - - - - - - - - - - - - - - - - - true - $(SolutionDir)bin\$(Configuration)_$(Platform)\ - $(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\ - $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(SolutionDir)lib\x86-32 - - - true - $(SolutionDir)bin\$(Configuration)_$(Platform)\ - $(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\ - $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(SolutionDir)lib\x86-64 - - - false - $(SolutionDir)bin\$(Configuration)_$(Platform)\ - $(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\ - $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(SolutionDir)lib\x86-32 - - - false - $(SolutionDir)bin\$(Configuration)_$(Platform)\ - $(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\ - $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(SolutionDir)lib\x86-64 - - - - - - Level3 - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;ASSRENDER_EXPORTS;%(PreprocessorDefinitions) - $(SolutionDir)msvc\include\;$(SolutionDir)src\include\%(AdditionalIncludeDirectories) - - - Windows - true - $(SolutionDir)msvc\lib\$(PlatformTarget)\ - libassd.lib;AviSynth.lib;%(AdditionalDependencies) - $(ProjectDir)src\assrender.def - - - - - - - Level3 - Disabled - _DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;ASSRENDER_EXPORTS;%(PreprocessorDefinitions) - $(SolutionDir)msvc\include\;$(SolutionDir)src\include\%(AdditionalIncludeDirectories) - - - Windows - true - $(SolutionDir)msvc\lib\$(PlatformTarget)\ - libassd.lib;AviSynth.lib;%(AdditionalDependencies) - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDL;_CRT_SECURE_NO_WARNINGSL;ASSRENDER_EXPORTS;%(PreprocessorDefinitions) - $(SolutionDir)msvc\include\;$(SolutionDir)src\include\%(AdditionalIncludeDirectories) - - - Windows - true - true - true - $(SolutionDir)msvc\lib\$(PlatformTarget)\ - libass.lib;AviSynth.lib;%(AdditionalDependencies) - $(ProjectDir)src\assrender.def - - - - - Level3 - - - MaxSpeed - true - true - NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;ASSRENDER_EXPORTS;%(PreprocessorDefinitions) - $(SolutionDir)msvc\include\;$(SolutionDir)src\include\%(AdditionalIncludeDirectories) - - - Windows - true - true - true - $(SolutionDir)msvc\lib\$(PlatformTarget)\ - libass.lib;AviSynth.lib;%(AdditionalDependencies) - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/assrender.vcxproj.filters b/assrender.vcxproj.filters deleted file mode 100644 index e63f2d6..0000000 --- a/assrender.vcxproj.filters +++ /dev/null @@ -1,58 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {00a049c9-4f7f-4366-8b58-2449e50a609d} - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Resource Files - - - - - Include - - - \ No newline at end of file diff --git a/assrender_with_latest_sdk.bat b/assrender_with_latest_sdk.bat deleted file mode 100644 index 06cd6a7..0000000 --- a/assrender_with_latest_sdk.bat +++ /dev/null @@ -1,59 +0,0 @@ -@ECHO OFF - -SET PROJECT=assrender - -@REM Detect the newest available Windows SDK -CALL :GetWindowsSdkVer - -@REM Open the project -%PROJECT%.sln - -EXIT /B 0 - -:GetWindowsSdkVer -SET WindowsTargetPlatformVersion= - -IF "%WindowsTargetPlatformVersion%"=="" CALL :GetWin10SdkVer -IF "%WindowsTargetPlatformVersion%"=="" CALL :GetWin81SdkVer -EXIT /B 0 - -:GetWin10SdkVer -CALL :GetWin10SdkVerHelper HKLM\SOFTWARE\Wow6432Node > nul 2>&1 -IF errorlevel 1 CALL :GetWin10SdkVerHelper HKCU\SOFTWARE\Wow6432Node > nul 2>&1 -IF errorlevel 1 CALL :GetWin10SdkVerHelper HKLM\SOFTWARE > nul 2>&1 -IF errorlevel 1 CALL :GetWin10SdkVerHelper HKCU\SOFTWARE > nul 2>&1 -IF errorlevel 1 EXIT /B 1 -EXIT /B 0 - -:GetWin10SdkVerHelper -@REM Get Windows 10 SDK installed folder -FOR /F "tokens=1,2*" %%i IN ('reg query "%1\Microsoft\Microsoft SDKs\Windows\v10.0" /v "InstallationFolder"') DO ( - IF "%%i"=="InstallationFolder" ( - SET WindowsSdkDir=%%~k - ) -) - -@REM get windows 10 sdk version number -SETLOCAL enableDelayedExpansion -IF NOT "%WindowsSdkDir%"=="" FOR /f %%i IN ('dir "%WindowsSdkDir%include\" /b /ad-h /on') DO ( - @REM Skip if Windows.h is not found in %%i\um. This would indicate that only the UCRT MSIs were - @REM installed for this Windows SDK version. - IF EXIST "%WindowsSdkDir%include\%%i\um\Windows.h" ( - SET result=%%i - IF "!result:~0,3!"=="10." ( - SET SDK=!result! - IF "!result!"=="%VSCMD_ARG_WINSDK%" SET findSDK=1 - ) - ) -) - -IF "%findSDK%"=="1" SET SDK=%VSCMD_ARG_WINSDK% -ENDLOCAL & SET WindowsTargetPlatformVersion=%SDK% -IF "%WindowsTargetPlatformVersion%"=="" ( - EXIT /B 1 -) -EXIT /B 0 - -:GetWin81SdkVer -SET WindowsTargetPlatformVersion=8.1 -EXIT /B 0 diff --git a/docs/BUILD.md b/docs/BUILD.md index 03ab041..9b75ab7 100644 --- a/docs/BUILD.md +++ b/docs/BUILD.md @@ -1,112 +1,46 @@ ## Build instructions -### Windows Visual Studio 2019 +### Windows -* Prequisite: vsnasm integration - - get VSNASM from https://github.com/ShiftMediaProject/VSNASM - - run install_script.bat +* Prequisite: install nasm, ninja, pkg-config-lite and meson + - `winget install Ninja-build.Ninja NASM.NASM bloodrock.pkg-config-lite mesonbuild.meson` + - set PKG_CONFIG_PATH env `setx PKG_CONFIG_PATH "C:/lib/pkgconfig"` -* Clone repo - - Clone https://github.com/pinterf/assrender from VS IDE or - - git clone https://github.com/pinterf/assrender - git submodule update --init --recursive --remote +* Clone repos + - Clone `git clone https://github.com/seiya-dev/assrender.git` + - and clone libass as subdirectory `cd assrender && git clone https://github.com/libass/libass.git` * Prequisite: avisynth.lib versions (x86 and x64) - When you have installed Avisynth through an installer and have installed FilterSDK get it from c:\Program Files (x86)\AviSynth+\FilterSDK\lib\x86 and x64 - Or get it from the 'filesonly' builds at Avisynth+ releases - https://github.com/AviSynth/AviSynthPlus/releases - - Copy lib files to assrender\lib\x86-64\ and assrender\lib\x86-32\ - 32 and 64 bit versions respectively + https://github.com/AviSynth/AviSynthPlus/releases + - Copy lib files to assrender\lib\x86-64\ and assrender\lib\x86-32\ + 32 and 64 bit versions respectively * Build: - Open solution file from IDE - -### Windows GCC (mingw installed by msys2) - -* Clone repo - - git clone https://github.com/pinterf/assrender - - This environment is not using the git submodules, we need libass as a package. - There is no need for submodule update. - -* Prequisite: avisynth.lib versions (x86 and x64) - - When you have installed Avisynth through an installer and have installed FilterSDK - get it from c:\Program Files (x86)\AviSynth+\FilterSDK\lib\x86 and x64 - - Or get it from the 'filesonly' builds at [Avisynth+ releases](https://github.com/AviSynth/AviSynthPlus/releases) - - Copy lib files to assrender\lib\x86-64\ and assrender\lib\x86-32\ - 32 and 64 bit versions respectively - -* Prequisite: libass package - - - List libass versions - - $ pacman -Ss libass - - Output: - - mingw32/mingw-w64-i686-libass 0.16.0-1 - A portable library for SSA/ASS subtitles rendering (mingw-w64) - mingw64/mingw-w64-x86_64-libass 0.16.0-1 - A portable library for SSA/ASS subtitles rendering (mingw-w64) - - - Get package - - Example for x64 version: - - $ pacman -S mingw64/mingw-w64-x86_64-libass - - Output: - - resolving dependencies... - looking for conflicting packages... - warning: dependency cycle detected: - warning: mingw-w64-x86_64-harfbuzz will be installed before its mingw-w64-x86_64-freetype dependency - - Packages (10) mingw-w64-x86_64-fontconfig-2.13.93-1 - mingw-w64-x86_64-freetype-2.10.4-1 - mingw-w64-x86_64-fribidi-1.0.10-2 - mingw-w64-x86_64-glib2-2.66.4-1 - mingw-w64-x86_64-graphite2-1.3.14-2 - mingw-w64-x86_64-harfbuzz-2.7.4-1 - mingw-w64-x86_64-libpng-1.6.37-3 mingw-w64-x86_64-pcre-8.44-2 - mingw-w64-x86_64-wineditline-2.205-3 - mingw-w64-x86_64-libass-0.15.0-1 - - Total Download Size: 6.92 MiB - Total Installed Size: 42.31 MiB - - :: Proceed with installation? [Y/n] - - Choose Y and wait - -* Build - under project root: - - rm -r build - cmake -G "MinGW Makefiles" -B build -S . - cmake --build build --config Release --clean-first + - run command `call "C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Auxiliary\Build\vcvars64.bat"` + - go to `libass` folder and run `meson wrap update-db && meson wrap install fribidi && meson wrap install freetype2 && meson wrap install expat && meson wrap install harfbuzz && meson wrap install libpng && meson wrap install zlib` + - run `meson setup build -Ddefault_library=static -Dbuildtype=release -Dasm=enabled -Db_vscrt=static_from_buildtype -Dc_std=c11 -Dcpp_std=c++17` + - run `meson compile -C build` + - run `meson install -C build` + - back to assrender folder and run ... + - run `cmake -D CMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded -A x64 -S . -B build` + - run `msbuild /t:Rebuild /m /p:Configuration=Release /p:Platform=x64 .\build\assrender.sln` ### Linux * Clone repo + - git clone https://github.com/seiya-dev/assrender + - cd assrender + - cmake -B build -S . + - cmake --build build --clean-first - git clone https://github.com/pinterf/assrender - cd assrender - cmake -B build -S . - cmake --build build --clean-first - - Remark: submodules are not needed, libass is used as a package. +* Remark: + - submodules are not needed, libass is used as a package. * Find binaries at - - build/assrender/libassrender.so + - build/assrender/libassrender.so * Install binaries - - cd build - sudo make install + - cd build + - sudo make install diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index f2c159b..bb094ae 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,5 +1,19 @@ ## Change log +### 0.36.0-dev.3 (20251202) +* Use frame properties if they available for "YCbCr Matrix: None" + +### 0.36.0-dev.2 (20251201) +* Restore x86-32 assrender.dll build + +### 0.36.0-dev.1 (20251201) +* Switch submodule build system to meson +* Update avisynth(plus) headers to v12 +* Unicode-safe file reading +* Add frame size parameters +* Add set_default_storage_size boolean +* Update libass to 0.17.4 + ### 0.35 (20210304) * Windows MSVC: Update to libass v0.15 (git submodule update --init --recursive --remote) diff --git a/docs/README.md b/docs/README.md index 913240d..88c21a4 100644 --- a/docs/README.md +++ b/docs/README.md @@ -6,46 +6,54 @@ This also means that it is much more picky about script syntax than VSFilter and ## Usage -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]) +assrender(clip, string file, [string vfr, int hinting, float scale, float line_spacing, int frame_width, int frame_height, bool set_default_storage_size, float dar, float sar, int top, int bottom, int left, int right, string charset, int debuglevel, string fontdir, string srt_font, string colorspace]) `string file` Your subtitle file. May be ASS, SSA or SRT. - + `string vfr` Specify timecodes v1 or v2 file when working with VFRaC. - + `int hinting` Font hinting mode. Choose between none (0, default), light (1), normal (2) and Freetype native (3) autohinting. - + `float scale` Font scale. Defaults to 1.0. - + `float line_spacing` Line spacing in pixels. Defaults to 1.0 and won’t be scaled with frame size. - + +`int frame_width`, `int frame_height` + + Actual displayed size, provide more information than `dar` & `sar`. Of course you need to set both parameters. + `float dar`, `float sar` -Aspect ratio. Of course you need to set both parameters. - +Aspect ratio, less priority than `frame_width` & `frame_height`. You need to set both parameters, too. + +`set_default_storage_size` + +Whether to render ASS according to storage size, default is True. + `int top`, `int bottom`, `int left`, `int right` Margins. They will be added to the frame size and may be negative. - + `string charset` Character set to use, in GNU iconv or enca format. Defaults to UTF-8. Example enca format: `enca:pl:cp1250` (guess the encoding for Polish, fall back on `cp1250`) - + `int debuglevel` How much crap assrender is supposed to spam to stderr. - + `string fontdir` Additional font directory. @@ -56,7 +64,7 @@ Default value: C:/Windows/Fonts or /usr/share/fonts (Windows and linux respectiv Font to use for SRT subtitles. Defaults to whatever Fontconfig chooses for “sans-serif”. - + `string colorspace` The color space of your (YUV) video. Possible values: @@ -82,12 +90,8 @@ See: [BUILD.md](BUILD.md) ## Change log See: [CHANGELOG.md](CHANGELOG.md) -## Licenses - For all modules: see msvc/licenses - ## Links * Doom9 forum: https://forum.doom9.org/showthread.php?t=148926 * Avisynth wiki: http://avisynth.nl/index.php/AssRender -* libass original: https://github.com/libass/libass -* libass submodule used for msvc https://github.com/ShiftMediaProject/libass -* Aegisub: https://github.com/Aegisub/Aegisub +* libass: https://github.com/libass/libass +* Aegisub: https://github.com/TypesettingTools/Aegisub diff --git a/src/ASSRender.rc b/src/ASSRender.rc index bd4357f..b5f5941 100644 --- a/src/ASSRender.rc +++ b/src/ASSRender.rc @@ -1,8 +1,8 @@ #include #pragma code_page(65001) VS_VERSION_INFO VERSIONINFO -FILEVERSION 0, 35, 0, 0 -PRODUCTVERSION 0, 35, 0, 0 +FILEVERSION 0, 36, 0, 0 +PRODUCTVERSION 0, 36, 0, 0 FILEFLAGSMASK VS_FFI_FILEFLAGSMASK FILEFLAGS 0 FILEOS VOS_NT_WINDOWS32 @@ -19,12 +19,12 @@ BEGIN BEGIN VALUE "CompanyName", "" VALUE "FileDescription", "a plugin for AviSynth to rend ASS/SSA subtitles using libass" - VALUE "FileVersion", "0.35.0.0" + VALUE "FileVersion", "0.36.0.0" VALUE "InternalName", "ASSRENDER.DLL" VALUE "LegalCopyright", "" VALUE "OriginalFilename", "LIBASSRENDER.DLL" VALUE "ProductName", "ASSRender plugin for AVISynth" - VALUE "ProductVersion", "0.35.0.0" + VALUE "ProductVersion", "0.36.0.0" END END BLOCK "VarFileInfo" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 812ca95..6b38234 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -7,24 +7,15 @@ endif() set(ProjectName "${PluginName}") project(${ProjectName} LANGUAGES C) -SET(ASSRender_SRC - assrender.c - assrender.h - render.c - render.h - sub.c - sub.h - timecodes.c - timecodes.h - ) +file(GLOB ASSRender_SRC *.c) -IF( WIN32 ) - LIST(APPEND ASSRender_SRC "ASSRender.rc") - if(NOT MINGW AND CMAKE_SIZEOF_VOID_P EQUAL 4) - # 32 bit VS only: decoration remove for old Avisynth 2.6 - LIST(APPEND ASSRender_SRC "assrender.def") - ENDIF() -ENDIF() +if(WIN32) + list(APPEND ASSRender_SRC "ASSRender.rc") + if(NOT MINGW AND CMAKE_SIZEOF_VOID_P EQUAL 4) + # 32 bit VS only: decoration remove for old Avisynth 2.6 + LIST(APPEND ASSRender_SRC "assrender.def") + endif() +endif() add_library(${PluginName} SHARED ${ASSRender_SRC}) @@ -34,36 +25,37 @@ if (MINGW) set_target_properties(${PluginName} PROPERTIES IMPORT_PREFIX "") endif() -IF (NOT WIN32 OR MINGW) - FIND_PACKAGE(PkgConfig REQUIRED) - IF (NOT MINGW) - PKG_CHECK_MODULES(AVISYNTH REQUIRED avisynth>=3.5.0) - ENDIF() - PKG_CHECK_MODULES(LIBASS REQUIRED libass>=0.12.0) - target_include_directories(${PluginName} PRIVATE ${AVISYNTH_INCLUDE_DIR} ${LIBASS_INCLUDE_DIR}) -ENDIF() +find_package(PkgConfig REQUIRED) + +if (NOT WIN32 OR MINGW) + if (NOT MINGW) + PKG_CHECK_MODULES(AVISYNTH REQUIRED avisynth>=3.7.5) + endif() + target_include_directories(${PluginName} PRIVATE ${AVISYNTH_INCLUDE_DIR}) +endif() #dedicated include dir for avisynth.h target_include_directories(${ProjectName} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) +PKG_CHECK_MODULES(LIBASS REQUIRED libass>=0.17.0) +target_include_directories(${PluginName} PRIVATE ${LIBASS_INCLUDE_DIRS}) +target_link_libraries(${ProjectName} ${LIBASS_LINK_LIBRARIES}) + if (WIN32) # avisynth.lib for C API if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(AVS_LIBDIR ${CMAKE_CURRENT_SOURCE_DIR}/../lib/x86-64) + set(AVS_LIBDIR ${CMAKE_CURRENT_SOURCE_DIR}/../lib/x86-64) else() - set(AVS_LIBDIR ${CMAKE_CURRENT_SOURCE_DIR}/../lib/x86-32) + set(AVS_LIBDIR ${CMAKE_CURRENT_SOURCE_DIR}/../lib/x86-32) endif() if (MINGW) - TARGET_LINK_LIBRARIES(${ProjectName} ${LIBASS_LDFLAGS} ${AVS_LIBDIR}/avisynth.lib) + target_link_libraries(${ProjectName} ${LIBASS_LDFLAGS} ${AVS_LIBDIR}/avisynth.lib) else() - # msvc: IDE based, with subprojects - TARGET_LINK_LIBRARIES(${ProjectName} ${AVS_LIBDIR}/avisynth.lib) + target_link_libraries(${ProjectName} ${AVS_LIBDIR}/avisynth.lib) endif() else() - TARGET_LINK_LIBRARIES(${ProjectName} ${AVISYNTH_LDFLAGS} ${LIBASS_LDFLAGS} ) + target_link_libraries(${ProjectName} ${LIBASS_LDFLAGS} ${AVISYNTH_LDFLAGS}) endif() include(GNUInstallDirs) - -INSTALL(TARGETS ${ProjectName} - LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}/avisynth") +install(TARGETS ${ProjectName} LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}/avisynth") diff --git a/src/assrender.c b/src/assrender.c index fb6c556..3107785 100644 --- a/src/assrender.c +++ b/src/assrender.c @@ -3,6 +3,106 @@ #include "sub.h" #include "timecodes.h" +static char* read_file_bytes(FILE* fp, size_t* bufsize) +{ + int res; + long sz; + long bytes_read; + char* buf; + res = fseek(fp, 0, SEEK_END); + if (res == -1) { + fclose(fp); + return 0; + } + + sz = ftell(fp); + rewind(fp); + + buf = sz < SIZE_MAX ? malloc(sz + 1) : NULL; + if (!buf) { + fclose(fp); + return NULL; + } + bytes_read = 0; + do { + res = fread(buf + bytes_read, 1, sz - bytes_read, fp); + if (res <= 0) { + fclose(fp); + free(buf); + return 0; + } + bytes_read += res; + } while (sz - bytes_read > 0); + buf[sz] = '\0'; + fclose(fp); + + if (bufsize) + *bufsize = sz; + return buf; +} + +static const char* detect_bom(const char* buf, const size_t bufsize) { + if (bufsize >= 4) { + if (!strncmp(buf, "\xef\xbb\xbf", 3)) + return "UTF-8"; + if (!strncmp(buf, "\x00\x00\xfe\xff", 4)) + return "UTF-32BE"; + if (!strncmp(buf, "\xff\xfe\x00\x00", 4)) + return "UTF-32LE"; + if (!strncmp(buf, "\xfe\xff", 2)) + return "UTF-16BE"; + if (!strncmp(buf, "\xff\xfe", 2)) + return "UTF-16LE"; + } + return "UTF-8"; +} + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#else +#include +#endif + +#ifdef _WIN32 +static wchar_t *utf8_to_utf16le(const char *data) { + const int out_size = MultiByteToWideChar(CP_UTF8, 0, data, -1, NULL, 0); + wchar_t *out = malloc(out_size * sizeof(wchar_t)); + MultiByteToWideChar(CP_UTF8, 0, data, -1, out, out_size); + return out; +} +#endif + +bool file_exists(const char *path) { +#ifdef _WIN32 + wchar_t *path_utf16le = utf8_to_utf16le(path); + DWORD dwAttrib = GetFileAttributesW(path_utf16le); + free(path_utf16le); + return (dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); +#else + struct stat path_stat; + if (stat(path, &path_stat) != 0) { + return false; + } + return S_ISREG(path_stat.st_mode); +#endif +} + +static FILE* open_utf8_filename(const char* f, const char* m) +{ + if (!file_exists(f)) return NULL; +#ifdef _WIN32 + wchar_t* file_name = utf8_to_utf16le(f); + wchar_t* mode = utf8_to_utf16le(m); + FILE* fp = _wfopen(file_name, mode); + free(file_name); + free(mode); + return fp; +#else + return fopen(f, m); +#endif +} + void AVSC_CC assrender_destroy(void* ud, AVS_ScriptEnvironment* env) { ass_renderer_done(((udata*)ud)->ass_renderer); @@ -20,48 +120,144 @@ void AVSC_CC assrender_destroy(void* ud, AVS_ScriptEnvironment* env) free(ud); } +static matrix_type matrix_from_frame_props( + AVS_ScriptEnvironment *env, + AVS_Clip *clip, + const AVS_VideoInfo *vi, + int *ok_out) +{ + *ok_out = 0; + + if (!avs_has_video(vi) || !avs_is_yuv(vi)) + return MATRIX_NONE; + + AVS_VideoFrame *frame = avs_get_frame(clip, 0); + if (!frame) + return MATRIX_NONE; + + int err; + const AVS_Map *props = avs_get_frame_props_ro(env, frame); + if (!props) { + avs_release_video_frame(frame); + return MATRIX_NONE; + } + + // _Matrix: ITU-T H.265 Table E.5 / AviSynth+ AVS_MATRIX_* index + int matrix = avs_prop_get_int(env, props, "_Matrix", 0, &err); + if (err) { + avs_release_video_frame(frame); + return MATRIX_NONE; + } + + // _ColorRange: 0 = full (PC), 1 = limited (TV) + int range = avs_prop_get_int(env, props, "_ColorRange", 0, &err); + if (err) + range = 1; // default to TV/limited for YUV if not present + + avs_release_video_frame(frame); + + const int full = (range == 0); + + /* + * _Matrix values (H.265 / AviSynth+): + * 0: RGB + * 1: BT.709 + * 2: unspecified + * 4: FCC (BT.470M) + * 5: BT.470BG / Rec.601 + * 6: ST.170M (also 601) + * 7: ST.240M + * 9: BT.2020 (non-constant luminance) + * 10: BT.2020 (constant luminance) + * (others ignored here) + */ + + matrix_type mt = MATRIX_NONE; + + switch (matrix) { + case 1: // BT.709 + mt = full ? MATRIX_PC709 : MATRIX_BT709; + break; + + case 5: // BT.470BG / Rec.601 + case 6: // ST.170M (treated as 601) + mt = full ? MATRIX_PC601 : MATRIX_BT601; + break; + + case 4: // FCC + mt = full ? MATRIX_PCFCC : MATRIX_TVFCC; + break; + + case 7: // 240M + mt = full ? MATRIX_PC240M : MATRIX_TV240M; + break; + + case 9: // BT.2020 (ncl) + case 10:// BT.2020 (cl) + mt = full ? MATRIX_PC2020 : MATRIX_BT2020; + break; + + default: + // 0 (RGB), 2 (unspec), 8 (YCgCo), 12/13/14… → we don’t trust it + mt = MATRIX_NONE; + break; + } + + if (mt != MATRIX_NONE) + *ok_out = 1; + + return mt; +} + AVS_Value AVSC_CC assrender_create(AVS_ScriptEnvironment* env, AVS_Value args, void* ud) { AVS_Value v; AVS_FilterInfo* fi; AVS_Clip* c = avs_new_c_filter(env, &fi, avs_array_elt(args, 0), 1); + const AVS_VideoInfo *vi = &fi->vi; char e[250]; const char* f = avs_as_string(avs_array_elt(args, 1)); const char* vfr = avs_as_string(avs_array_elt(args, 2)); - int h = avs_is_int(avs_array_elt(args, 3)) ? - avs_as_int(avs_array_elt(args, 3)) : 0; + int hint = avs_is_int(avs_array_elt(args, 3)) ? + avs_as_int(avs_array_elt(args, 3)) : 0; double scale = avs_is_float(avs_array_elt(args, 4)) ? avs_as_float(avs_array_elt(args, 4)) : 1.0; double line_spacing = avs_is_float(avs_array_elt(args, 5)) ? avs_as_float(avs_array_elt(args, 5)) : 0; - double dar = avs_is_float(avs_array_elt(args, 6)) ? - avs_as_float(avs_array_elt(args, 6)) : 0; - double sar = avs_is_float(avs_array_elt(args, 7)) ? - avs_as_float(avs_array_elt(args, 7)) : 0; - int top = avs_is_int(avs_array_elt(args, 8)) ? - avs_as_int(avs_array_elt(args, 8)) : 0; - int bottom = avs_is_int(avs_array_elt(args, 9)) ? - avs_as_int(avs_array_elt(args, 9)) : 0; - int left = avs_is_int(avs_array_elt(args, 10)) ? - avs_as_int(avs_array_elt(args, 10)) : 0; - int right = avs_is_int(avs_array_elt(args, 11)) ? - avs_as_int(avs_array_elt(args, 11)) : 0; - const char* cs = avs_as_string(avs_array_elt(args, 12)) ? - avs_as_string(avs_array_elt(args, 12)) : "UTF-8"; - int debuglevel = avs_is_int(avs_array_elt(args, 13)) ? - avs_as_int(avs_array_elt(args, 13)) : 0; - const char* fontdir = avs_as_string(avs_array_elt(args, 14)) ? + int frame_width = avs_is_int(avs_array_elt(args, 6)) ? + avs_as_int(avs_array_elt(args, 6)) : 0; + int frame_height = avs_is_int(avs_array_elt(args, 7)) ? + avs_as_int(avs_array_elt(args, 7)) : 0; + double dar = avs_is_float(avs_array_elt(args, 8)) ? + avs_as_float(avs_array_elt(args, 8)) : 0; + double sar = avs_is_float(avs_array_elt(args, 9)) ? + avs_as_float(avs_array_elt(args, 9)) : 0; + bool defstorage = avs_as_bool(avs_array_elt(args, 10)) ? + avs_as_bool(avs_array_elt(args, 10)) : true; + int top = avs_is_int(avs_array_elt(args, 11)) ? + avs_as_int(avs_array_elt(args, 11)) : 0; + int bottom = avs_is_int(avs_array_elt(args, 12)) ? + avs_as_int(avs_array_elt(args, 12)) : 0; + int left = avs_is_int(avs_array_elt(args, 13)) ? + avs_as_int(avs_array_elt(args, 13)) : 0; + int right = avs_is_int(avs_array_elt(args, 14)) ? + avs_as_int(avs_array_elt(args, 14)) : 0; + /* Allow charset auto-detection via BOM if omitted */ + const char* cs = avs_as_string(avs_array_elt(args, 15)); + int debuglevel = avs_is_int(avs_array_elt(args, 16)) ? + avs_as_int(avs_array_elt(args, 16)) : 0; + const char* fontdir = avs_as_string(avs_array_elt(args, 17)) ? #ifdef AVS_WINDOWS - avs_as_string(avs_array_elt(args, 14)) : "C:/Windows/Fonts"; + avs_as_string(avs_array_elt(args, 17)) : "C:/Windows/Fonts"; #else - avs_as_string(avs_array_elt(args, 14)) : "/usr/share/fonts"; + avs_as_string(avs_array_elt(args, 17)) : "/usr/share/fonts"; #endif - const char* srt_font = avs_as_string(avs_array_elt(args, 15)) ? - avs_as_string(avs_array_elt(args, 15)) : "sans-serif"; - const char* colorspace = avs_as_string(avs_array_elt(args, 16)) ? - avs_as_string(avs_array_elt(args, 16)) : ""; + const char* srt_font = avs_as_string(avs_array_elt(args, 18)) ? + avs_as_string(avs_array_elt(args, 18)) : "sans-serif"; + const char* colorspace = avs_as_string(avs_array_elt(args, 19)) ? + avs_as_string(avs_array_elt(args, 19)) : ""; char* tmpcsp = calloc(1, BUFSIZ); strncpy(tmpcsp, colorspace, BUFSIZ - 1); @@ -70,6 +266,8 @@ AVS_Value AVSC_CC assrender_create(AVS_ScriptEnvironment* env, AVS_Value args, udata* data; ASS_Track* ass; + FILE* fp; + /* no unsupported colorspace left, bitness is checked at other place if (0 == 1) { @@ -86,7 +284,7 @@ AVS_Value AVSC_CC assrender_create(AVS_ScriptEnvironment* env, AVS_Value args, return v; } - switch (h) { + switch (hint) { case 0: hinting = ASS_HINTING_NONE; break; @@ -107,19 +305,56 @@ AVS_Value AVSC_CC assrender_create(AVS_ScriptEnvironment* env, AVS_Value args, data = malloc(sizeof(udata)); - if (!init_ass(fi->vi.width, fi->vi.height, scale, line_spacing, - hinting, dar, sar, top, bottom, left, right, - debuglevel, fontdir, data)) { + if (!init_ass(fi->vi.width, fi->vi.height, scale, line_spacing, hinting, + frame_width, frame_height, dar, sar, defstorage, + top, bottom, left, right, debuglevel, + fontdir, data)) { v = avs_new_value_error("AssRender: failed to initialize"); avs_release_clip(c); return v; } - if (!strcasecmp(strrchr(f, '.'), ".srt")) - ass = parse_srt(f, data, srt_font); - else { - ass = ass_read_file(data->ass_library, (char*)f, (char*)cs); - ass_read_matrix(f, tmpcsp); + /* Improved Unicode / BOM / file validation loading logic */ + if (!strcasecmp(strrchr(f, '.'), ".srt")) { + FILE* fp = open_utf8_filename(f, "r"); + if (!fp) { + sprintf(e, "AssRender: input file '%s' does not exist or is not a regular file", f); + v = avs_new_value_error(e); + avs_release_clip(c); + return v; + } + ass = parse_srt(fp, data, srt_font); + } else { + size_t bufsize = 0; + char* buf; + + fp = open_utf8_filename(f, "rb"); + if (!fp) { + sprintf(e, "AssRender: input file '%s' does not exist or is not a regular file", f); + v = avs_new_value_error(e); + avs_release_clip(c); + return v; + } + + buf = read_file_bytes(fp, &bufsize); + if (!buf) { + sprintf(e, "AssRender: unable to read '%s'", f); + v = avs_new_value_error(e); + avs_release_clip(c); + return v; + } + + if (cs == NULL) + cs = detect_bom(buf, bufsize); + + ass = ass_read_memory(data->ass_library, buf, bufsize, (char*)cs); + free(buf); + + fp = open_utf8_filename(f, "r"); + if (fp) { + ass_read_matrix(fp, tmpcsp); + fclose(fp); + } } if (!ass) { @@ -133,7 +368,7 @@ AVS_Value AVSC_CC assrender_create(AVS_ScriptEnvironment* env, AVS_Value args, if (vfr) { int ver; - FILE* fh = fopen(vfr, "r"); + FILE* fh = open_utf8_filename(vfr, "r"); if (!fh) { sprintf(e, "AssRender: could not read timecodes file '%s'", vfr); @@ -221,10 +456,23 @@ AVS_Value AVSC_CC assrender_create(AVS_ScriptEnvironment* env, AVS_Value args, color_mt = MATRIX_BT2020; else */ - if (fi->vi.width > 1280 || fi->vi.height > 576) - color_mt = MATRIX_PC709; - else - color_mt = MATRIX_PC601; + + int mt_from_props_ok = 0; + matrix_type mt_from_props = MATRIX_NONE; + + if (avs_get_version(c) >= 9) { + mt_from_props = matrix_from_frame_props(env, c, vi, &mt_from_props_ok); + } + + if (mt_from_props_ok && mt_from_props != MATRIX_NONE) { + color_mt = mt_from_props; + } else { + if (vi->width >= 1280 || vi->height >= 576) { + color_mt = MATRIX_PC709; + } else { + color_mt = MATRIX_PC601; + } + } } else { color_mt = MATRIX_BT601; @@ -356,9 +604,25 @@ AVS_Value AVSC_CC assrender_create(AVS_ScriptEnvironment* env, AVS_Value args, const char* AVSC_CC avisynth_c_plugin_init(AVS_ScriptEnvironment* env) { avs_add_function(env, "assrender", - "c[file]s[vfr]s[hinting]i[scale]f[line_spacing]f[dar]f" - "[sar]f[top]i[bottom]i[left]i[right]i[charset]s" - "[debuglevel]i[fontdir]s[srt_font]s[colorspace]s", + "c[file]s" + "[vfr]s" + "[hinting]i" + "[scale]f" + "[line_spacing]f" + "[frame_width]i" + "[frame_height]i" + "[dar]f" + "[sar]f" + "[set_default_storage_size]b" + "[top]i" + "[bottom]i" + "[left]i" + "[right]i" + "[charset]s" + "[debuglevel]i" + "[fontdir]s" + "[srt_font]s" + "[colorspace]s", assrender_create, 0); return "AssRender: draws text subtitles better and faster than ever before"; } diff --git a/src/assrender.h b/src/assrender.h index 302ee51..fa40b7c 100644 --- a/src/assrender.h +++ b/src/assrender.h @@ -3,8 +3,11 @@ #include #include +#include +#include #include #include +#include #include #include "avs/config.h" #ifdef AVS_WINDOWS diff --git a/src/include/avisynth_c.h b/src/include/avisynth_c.h index b42a0b1..1f665f1 100644 --- a/src/include/avisynth_c.h +++ b/src/include/avisynth_c.h @@ -2,6 +2,7 @@ // Copyright 2003 Kevin Atkinson // Copyright 2020 AviSynth+ project +// Actual C Interface version follows the global Avisynth+ IF version numbers. // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -53,23 +54,98 @@ // Example#1: e.g. avs_is_444 will call the existing avs_is_yv24 instead // Example#2: avs_bits_per_component will return 8 for all colorspaces (Classic Avisynth supports only 8 bits/pixel) // Thus the Avisynth+ specific API functions are safely callable even when connected to classic Avisynth DLL -// 202002xx non-Windows friendly additions -// 20200305 avs_vsprintf parameter type change: (void *) to va_list -// 20200330: (remove test SIZETMOD define for clarity) -// 20200513: user must use explicite #define AVS26_FALLBACK_SIMULATION for having fallback helpers in dynamic loaded library section -// 20200513: Follow AviSynth+ V8 interface additions -// AVS_VideoFrame struct extended with placeholder for frame property pointer -// avs_subframe_planar_a -// avs_copy_frame_props -// avs_get_frame_props_ro, avs_get_frame_props_rw -// avs_prop_num_keys, avs_prop_get_key, avs_prop_num_elements, avs_prop_get_type, avs_prop_get_data_size -// 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 -// 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 -// avs_prop_delete_key, avs_clear_map -// avs_new_video_frame_p, avs_new_video_frame_p_a -// avs_get_env_property (internal system properties), AVS_AEP_xxx (AvsEnvProperty) enums -// avs_get_var_try, avs_get_var_bool, avs_get_var_int, avs_get_var_double, avs_get_var_string, avs_get_var_long -// avs_pool_allocate, avs_pool_free +// 2002xx non-Windows friendly additions +// 200305 avs_vsprintf parameter type change: (void *) to va_list +// 200330: (remove test SIZETMOD define for clarity) +// 200513: user must use explicite #define AVS26_FALLBACK_SIMULATION for having fallback helpers in dynamic loaded library section +// 200513: Follow AviSynth+ V8 interface additions +// AVS_VideoFrame struct extended with placeholder for frame property pointer +// avs_subframe_planar_a +// avs_copy_frame_props +// avs_get_frame_props_ro, avs_get_frame_props_rw +// avs_prop_num_keys, avs_prop_get_key, avs_prop_num_elements, avs_prop_get_type, avs_prop_get_data_size +// 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 +// 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 +// avs_prop_delete_key, avs_clear_map +// avs_new_video_frame_p, avs_new_video_frame_p_a +// avs_get_env_property (internal system properties), AVS_AEP_xxx (AvsEnvProperty) enums +// avs_get_var_try, avs_get_var_bool, avs_get_var_int, avs_get_var_double, avs_get_var_string, avs_get_var_long +// avs_pool_allocate, avs_pool_free +// 2021: Follow AviSynth+ V9 interface additions +// avs_is_property_writable, avs_make_property_writable +// Add enum AVISYNTHPLUS_INTERFACE_BUGFIX_VERSION (AVISYNTH_INTERFACE_VERSION still exists) +// Add enum AVS_AEP_HOST_SYSTEM_ENDIANNESS to system property request types (avs_get_env_property) +// Add enums AVS_AEP_INTERFACE_VERSION and AVS_AEP_INTERFACE_BUGFIX for direct interface version system property request types (avs_get_env_property) +// Bugfix 9.1: fix avs_prop_get_data +// 2023: Follow AviSynth+ V10 interface additions +// Add enum AVS_DEFAULT_PLANE (as 0) to plane constants +// prop_src argument now const in avs_new_video_frame_p and avs_new_video_frame_p_a (no change in use) +// Add pixel_type to struct AVS_VideoFrame +// Add avs_video_frame_get_pixel_type and avs_video_frame_amend_pixel_type for getting and setting AVS_VideoFrame pixel_type +// Additional AviSynth+ V10 interface additions: +// Add enum AVS_SPEAKER_xxx, AVS_IT_SPEAKER_xxx +// Audio channel mask support API: avs_is_channel_mask_known, avs_set_channel_mask, avs_get_channel_mask + +// 2025 Follow AviSynth+ V11 interface additions (AVSValue new 64-bit types); +// Setters are all accept AVS_Value by reference, like avs_set_to_clip did so far. (unlike avs_new_xxx inline helpers, which returns AVS_Value directly) +// - avs_val_defined = avs_defined +// - avs_val_is_xxx = avs_is_xxx (bool, clip, int, long_strict, string, float_strict, float, error, array) +// - avs_set_to_xxx ~avs_new_value_xxx (bool, clip, int, long, string, float, double, error, array) +// - avs_set_to_void = AVS_void constant direct assignment +// - avs_get_as_xxx = avs_as_xxx (bool, clip, int, long, string, float, error, array) +// - avs_get_array_size = avs_array_size +// - avs_get_array_elt = avs_array_elt +// Including: +// Modified INLINE typecheck and getter helpers for 64-bit data type awareness: +// - avs_is_int, avs_is_float +// - avs_as_int, avs_as_float +// Strict type checkers +// - avs_val_is_long_strict, avs_val_is_floatf_strict +// New INLINE getter helpers for 64-bit data (prefer using API calls): +// - avs_as_long +// New optional plugin entry point: avisynth_c_plugin_init2 +// - A C plugin signals to AviSynth that it is V11 interface (64-bit data) ready by implementing avisynth_c_plugin_init2 as well. +// avisynth_c_plugin_init2 has the same signature as avisynth_c_plugin_init and can +// simply call forward to the old avisynth_c_plugin_init entry point. Both entry points can be implemented; +// AviSynth+ will first check avisynth_c_plugin_init2, then avisynth_c_plugin_init. +// Don't forget to add a new +// avisynth_c_plugin_init2@4 = _avisynth_c_plugin_init2@4 +// line to your existing .def file on Win32. +// Deprecated inline helper functions, which in turn would call API. +// - avs_get_pitch => avs_get_pitch_p(p, AVS_DEFAULT_PLANE) +// avs_get_row_size => avs_get_row_size_p(p, AVS_DEFAULT_PLANE) +// avs_get_height => avs_get_height_p(p, AVS_DEFAULT_PLANE) +// avs_get_read_ptr => avs_get_read_ptr_p(p, AVS_DEFAULT_PLANE) +// avs_get_write_ptr => vs_get_write_ptr_p(p, AVS_DEFAULT_PLANE) +// avs_release_frame => avs_release_video_frame +// avs_copy_frame => avs_copy_video_frame +// - Use #define AVSC_ALLOW_DEPRECATED if they still need for you, +// but better fix your code: use the recommended replacements. +// Intentionally renamed AVS_VideoFrame internal fields, direct access was always prohibited, next API will remove the access. +// Add missing AVS_MT_xxxx mode constants to header like c++ header enum MtMode +// Add AVS_PROPDATATYPEHINT_xxx for AVSPropDataTypeHint +// New avs_prop_get_int_saturated and avs_prop_get_float_saturated +// New avs_prop_get_data_type_hint +// New avs_prop_set_data_h +// New avs_add_func_r: alternative avs_add_func which returns the result in a byref parameter +// New AVS_ApplyFuncR type +// 20250415 V11.1 Fix AVS_Value 64 bit data member declaration for 64-bit non Intel (other than X86_X64) systems. +// 20250601 V12 Global lock acquire and release: avs_acquire_global_lock, avs_release_global_lock + +// Notes. +// Choose either method: +// By loading avisynth.dll/.so/.dylib dinamically, AviSynth versions with different API level can be supported. +// - Use #define AVSC_NO_DECLSPEC for function pointer definitions only. +// - Load the library dynamically and get the necessary API functions as needed. +// - Earlier AviSynth versions may contain fewer API functions. +// By detecting the loaded AviSynth/interface version, it's the caller's responsibility +// to call only those API functions which have valid function pointers and are documented to work. +// E.g., you should only use frame property-related functions when lib.avs_get_version(clip) >= 9. +// For linking avisynth.lib/libavisynth directly to your module: +// - Leave AVSC_NO_DECLSPEC undefined. +// - Link the provided .lib to your module. +// - Your plugin/software won't work with older AviSynth instances if it uses newer API functions. +// The plugin DLL won't load due to dependency issues. (On Windows: platform returned code 127) #ifndef __AVISYNTH_C__ @@ -85,102 +161,109 @@ // Constants // -#ifndef __AVISYNTH_8_H__ +#ifndef __AVISYNTH_12_H__ enum { AVISYNTH_INTERFACE_CLASSIC_VERSION = 6, - AVISYNTH_INTERFACE_VERSION = 8 + AVISYNTH_INTERFACE_VERSION = 12, + AVISYNTHPLUS_INTERFACE_BUGFIX_VERSION = 0 // reset to zero whenever the normal interface version bumps }; #endif -enum {AVS_SAMPLE_INT8 = 1<<0, - AVS_SAMPLE_INT16 = 1<<1, - AVS_SAMPLE_INT24 = 1<<2, - AVS_SAMPLE_INT32 = 1<<3, - AVS_SAMPLE_FLOAT = 1<<4}; - -enum {AVS_PLANAR_Y=1<<0, - AVS_PLANAR_U=1<<1, - AVS_PLANAR_V=1<<2, - AVS_PLANAR_ALIGNED=1<<3, - AVS_PLANAR_Y_ALIGNED=AVS_PLANAR_Y|AVS_PLANAR_ALIGNED, - AVS_PLANAR_U_ALIGNED=AVS_PLANAR_U|AVS_PLANAR_ALIGNED, - AVS_PLANAR_V_ALIGNED=AVS_PLANAR_V|AVS_PLANAR_ALIGNED, - AVS_PLANAR_A=1<<4, - AVS_PLANAR_R=1<<5, - AVS_PLANAR_G=1<<6, - AVS_PLANAR_B=1<<7, - AVS_PLANAR_A_ALIGNED=AVS_PLANAR_A|AVS_PLANAR_ALIGNED, - AVS_PLANAR_R_ALIGNED=AVS_PLANAR_R|AVS_PLANAR_ALIGNED, - AVS_PLANAR_G_ALIGNED=AVS_PLANAR_G|AVS_PLANAR_ALIGNED, - AVS_PLANAR_B_ALIGNED=AVS_PLANAR_B|AVS_PLANAR_ALIGNED}; - - // Colorspace properties. enum { - AVS_CS_YUVA = 1 << 27, - AVS_CS_BGR = 1 << 28, - AVS_CS_YUV = 1 << 29, - AVS_CS_INTERLEAVED = 1 << 30, - AVS_CS_PLANAR = 1 << 31, - - AVS_CS_SHIFT_SUB_WIDTH = 0, - AVS_CS_SHIFT_SUB_HEIGHT = 8, - AVS_CS_SHIFT_SAMPLE_BITS = 16, - - AVS_CS_SUB_WIDTH_MASK = 7 << AVS_CS_SHIFT_SUB_WIDTH, - AVS_CS_SUB_WIDTH_1 = 3 << AVS_CS_SHIFT_SUB_WIDTH, // YV24 - AVS_CS_SUB_WIDTH_2 = 0 << AVS_CS_SHIFT_SUB_WIDTH, // YV12, I420, YV16 - AVS_CS_SUB_WIDTH_4 = 1 << AVS_CS_SHIFT_SUB_WIDTH, // YUV9, YV411 - - AVS_CS_VPLANEFIRST = 1 << 3, // YV12, YV16, YV24, YV411, YUV9 - AVS_CS_UPLANEFIRST = 1 << 4, // I420 - - AVS_CS_SUB_HEIGHT_MASK = 7 << AVS_CS_SHIFT_SUB_HEIGHT, - AVS_CS_SUB_HEIGHT_1 = 3 << AVS_CS_SHIFT_SUB_HEIGHT, // YV16, YV24, YV411 - AVS_CS_SUB_HEIGHT_2 = 0 << AVS_CS_SHIFT_SUB_HEIGHT, // YV12, I420 - AVS_CS_SUB_HEIGHT_4 = 1 << AVS_CS_SHIFT_SUB_HEIGHT, // YUV9 - - AVS_CS_SAMPLE_BITS_MASK = 7 << AVS_CS_SHIFT_SAMPLE_BITS, - AVS_CS_SAMPLE_BITS_8 = 0 << AVS_CS_SHIFT_SAMPLE_BITS, - AVS_CS_SAMPLE_BITS_10 = 5 << AVS_CS_SHIFT_SAMPLE_BITS, - AVS_CS_SAMPLE_BITS_12 = 6 << AVS_CS_SHIFT_SAMPLE_BITS, - AVS_CS_SAMPLE_BITS_14 = 7 << AVS_CS_SHIFT_SAMPLE_BITS, - AVS_CS_SAMPLE_BITS_16 = 1 << AVS_CS_SHIFT_SAMPLE_BITS, - AVS_CS_SAMPLE_BITS_32 = 2 << AVS_CS_SHIFT_SAMPLE_BITS, - - 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, - AVS_CS_PLANAR_FILTER = ~(AVS_CS_VPLANEFIRST | AVS_CS_UPLANEFIRST), - - AVS_CS_RGB_TYPE = 1 << 0, - AVS_CS_RGBA_TYPE = 1 << 1, - - 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 - 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 - 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 - AVS_CS_GENERIC_Y = AVS_CS_PLANAR | AVS_CS_INTERLEAVED | AVS_CS_YUV, // Y only (4:0:0) - AVS_CS_GENERIC_RGBP = AVS_CS_PLANAR | AVS_CS_BGR | AVS_CS_RGB_TYPE, // planar RGB - AVS_CS_GENERIC_RGBAP = AVS_CS_PLANAR | AVS_CS_BGR | AVS_CS_RGBA_TYPE, // planar RGBA - 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 - 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 - 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 - - - // Specific color formats + AVS_SAMPLE_INT8 = 1 << 0, + AVS_SAMPLE_INT16 = 1 << 1, + AVS_SAMPLE_INT24 = 1 << 2, + AVS_SAMPLE_INT32 = 1 << 3, + AVS_SAMPLE_FLOAT = 1 << 4 +}; + +enum { + AVS_DEFAULT_PLANE = 0, + AVS_PLANAR_Y = 1 << 0, + AVS_PLANAR_U = 1 << 1, + AVS_PLANAR_V = 1 << 2, + AVS_PLANAR_ALIGNED = 1 << 3, + AVS_PLANAR_Y_ALIGNED = AVS_PLANAR_Y | AVS_PLANAR_ALIGNED, + AVS_PLANAR_U_ALIGNED = AVS_PLANAR_U | AVS_PLANAR_ALIGNED, + AVS_PLANAR_V_ALIGNED = AVS_PLANAR_V | AVS_PLANAR_ALIGNED, + AVS_PLANAR_A = 1 << 4, + AVS_PLANAR_R = 1 << 5, + AVS_PLANAR_G = 1 << 6, + AVS_PLANAR_B = 1 << 7, + AVS_PLANAR_A_ALIGNED = AVS_PLANAR_A | AVS_PLANAR_ALIGNED, + AVS_PLANAR_R_ALIGNED = AVS_PLANAR_R | AVS_PLANAR_ALIGNED, + AVS_PLANAR_G_ALIGNED = AVS_PLANAR_G | AVS_PLANAR_ALIGNED, + AVS_PLANAR_B_ALIGNED = AVS_PLANAR_B | AVS_PLANAR_ALIGNED +}; + +// Colorspace properties. +enum { + AVS_CS_YUVA = 1 << 27, + AVS_CS_BGR = 1 << 28, + AVS_CS_YUV = 1 << 29, + AVS_CS_INTERLEAVED = 1 << 30, + AVS_CS_PLANAR = 1 << 31, + + AVS_CS_SHIFT_SUB_WIDTH = 0, + AVS_CS_SHIFT_SUB_HEIGHT = 8, + AVS_CS_SHIFT_SAMPLE_BITS = 16, + + AVS_CS_SUB_WIDTH_MASK = 7 << AVS_CS_SHIFT_SUB_WIDTH, + AVS_CS_SUB_WIDTH_1 = 3 << AVS_CS_SHIFT_SUB_WIDTH, // YV24 + AVS_CS_SUB_WIDTH_2 = 0 << AVS_CS_SHIFT_SUB_WIDTH, // YV12, I420, YV16 + AVS_CS_SUB_WIDTH_4 = 1 << AVS_CS_SHIFT_SUB_WIDTH, // YUV9, YV411 + + AVS_CS_VPLANEFIRST = 1 << 3, // YV12, YV16, YV24, YV411, YUV9 + AVS_CS_UPLANEFIRST = 1 << 4, // I420 + + AVS_CS_SUB_HEIGHT_MASK = 7 << AVS_CS_SHIFT_SUB_HEIGHT, + AVS_CS_SUB_HEIGHT_1 = 3 << AVS_CS_SHIFT_SUB_HEIGHT, // YV16, YV24, YV411 + AVS_CS_SUB_HEIGHT_2 = 0 << AVS_CS_SHIFT_SUB_HEIGHT, // YV12, I420 + AVS_CS_SUB_HEIGHT_4 = 1 << AVS_CS_SHIFT_SUB_HEIGHT, // YUV9 + + AVS_CS_SAMPLE_BITS_MASK = 7 << AVS_CS_SHIFT_SAMPLE_BITS, + AVS_CS_SAMPLE_BITS_8 = 0 << AVS_CS_SHIFT_SAMPLE_BITS, + AVS_CS_SAMPLE_BITS_10 = 5 << AVS_CS_SHIFT_SAMPLE_BITS, + AVS_CS_SAMPLE_BITS_12 = 6 << AVS_CS_SHIFT_SAMPLE_BITS, + AVS_CS_SAMPLE_BITS_14 = 7 << AVS_CS_SHIFT_SAMPLE_BITS, + AVS_CS_SAMPLE_BITS_16 = 1 << AVS_CS_SHIFT_SAMPLE_BITS, + AVS_CS_SAMPLE_BITS_32 = 2 << AVS_CS_SHIFT_SAMPLE_BITS, + + 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_WIDTH_MASK | AVS_CS_SUB_HEIGHT_MASK, + AVS_CS_PLANAR_FILTER = ~(AVS_CS_VPLANEFIRST | AVS_CS_UPLANEFIRST), + + AVS_CS_RGB_TYPE = 1 << 0, + AVS_CS_RGBA_TYPE = 1 << 1, + + AVS_CS_GENERIC_YUV444 = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_VPLANEFIRST | AVS_CS_SUB_WIDTH_1 | AVS_CS_SUB_HEIGHT_1, // 4:4:4 planar + AVS_CS_GENERIC_YUV422 = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_VPLANEFIRST | AVS_CS_SUB_WIDTH_2 | AVS_CS_SUB_HEIGHT_1, // 4:2:2 planar + AVS_CS_GENERIC_YUV420 = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_VPLANEFIRST | AVS_CS_SUB_WIDTH_2 | AVS_CS_SUB_HEIGHT_2, // 4:2:0 planar + AVS_CS_GENERIC_Y = AVS_CS_PLANAR | AVS_CS_INTERLEAVED | AVS_CS_YUV, // Y only (4:0:0) + AVS_CS_GENERIC_RGBP = AVS_CS_PLANAR | AVS_CS_BGR | AVS_CS_RGB_TYPE, // planar RGB + AVS_CS_GENERIC_RGBAP = AVS_CS_PLANAR | AVS_CS_BGR | AVS_CS_RGBA_TYPE, // planar RGBA + AVS_CS_GENERIC_YUVA444 = AVS_CS_PLANAR | AVS_CS_YUVA | AVS_CS_VPLANEFIRST | AVS_CS_SUB_WIDTH_1 | AVS_CS_SUB_HEIGHT_1, // 4:4:4:A planar + AVS_CS_GENERIC_YUVA422 = AVS_CS_PLANAR | AVS_CS_YUVA | AVS_CS_VPLANEFIRST | AVS_CS_SUB_WIDTH_2 | AVS_CS_SUB_HEIGHT_1, // 4:2:2:A planar + AVS_CS_GENERIC_YUVA420 = AVS_CS_PLANAR | AVS_CS_YUVA | AVS_CS_VPLANEFIRST | AVS_CS_SUB_WIDTH_2 | AVS_CS_SUB_HEIGHT_2 // 4:2:0:A planar +}; + +// Specific color formats enum { AVS_CS_UNKNOWN = 0, AVS_CS_BGR24 = AVS_CS_RGB_TYPE | AVS_CS_BGR | AVS_CS_INTERLEAVED, AVS_CS_BGR32 = AVS_CS_RGBA_TYPE | AVS_CS_BGR | AVS_CS_INTERLEAVED, - AVS_CS_YUY2 = 1<<2 | AVS_CS_YUV | AVS_CS_INTERLEAVED, - // AVS_CS_YV12 = 1<<3 Reserved - // AVS_CS_I420 = 1<<4 Reserved - AVS_CS_RAW32 = 1<<5 | AVS_CS_INTERLEAVED, + AVS_CS_YUY2 = 1 << 2 | AVS_CS_YUV | AVS_CS_INTERLEAVED, + // AVS_CS_YV12 = 1 << 3 Reserved + // AVS_CS_I420 = 1 << 4 Reserved + AVS_CS_RAW32 = 1 << 5 | AVS_CS_INTERLEAVED, AVS_CS_YV24 = AVS_CS_GENERIC_YUV444 | AVS_CS_SAMPLE_BITS_8, // YUV 4:4:4 planar AVS_CS_YV16 = AVS_CS_GENERIC_YUV422 | AVS_CS_SAMPLE_BITS_8, // YUV 4:2:2 planar AVS_CS_YV12 = AVS_CS_GENERIC_YUV420 | AVS_CS_SAMPLE_BITS_8, // YUV 4:2:0 planar - 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 + AVS_CS_I420 = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_SAMPLE_BITS_8 | AVS_CS_UPLANEFIRST | AVS_CS_SUB_WIDTH_2 | AVS_CS_SUB_HEIGHT_2, // YUV 4:2:0 planar AVS_CS_IYUV = AVS_CS_I420, - 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 - 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 + AVS_CS_YV411 = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_SAMPLE_BITS_8 | AVS_CS_VPLANEFIRST | AVS_CS_SUB_WIDTH_4 | AVS_CS_SUB_HEIGHT_1, // YUV 4:1:1 planar + AVS_CS_YUV9 = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_SAMPLE_BITS_8 | AVS_CS_VPLANEFIRST | AVS_CS_SUB_WIDTH_4 | AVS_CS_SUB_HEIGHT_4, // YUV 4:1:0 planar AVS_CS_Y8 = AVS_CS_GENERIC_Y | AVS_CS_SAMPLE_BITS_8, // Y 4:0:0 planar //------------------------- @@ -257,33 +340,97 @@ enum { AVS_CS_YUVA444PS = AVS_CS_GENERIC_YUVA444 | AVS_CS_SAMPLE_BITS_32, // YUVA 4:4:4 32bit samples AVS_CS_YUVA422PS = AVS_CS_GENERIC_YUVA422 | AVS_CS_SAMPLE_BITS_32, // YUVA 4:2:2 32bit samples AVS_CS_YUVA420PS = AVS_CS_GENERIC_YUVA420 | AVS_CS_SAMPLE_BITS_32, // YUVA 4:2:0 32bit samples +}; +// AvsChannelMask enum: Unshifted channel mask constants like in WAVEFORMATEXTENSIBLE +// in AvsImageTypeFlags they are shifted by 4 bits +enum { + AVS_MASK_SPEAKER_FRONT_LEFT = 0x1, + AVS_MASK_SPEAKER_FRONT_RIGHT = 0x2, + AVS_MASK_SPEAKER_FRONT_CENTER = 0x4, + AVS_MASK_SPEAKER_LOW_FREQUENCY = 0x8, + AVS_MASK_SPEAKER_BACK_LEFT = 0x10, + AVS_MASK_SPEAKER_BACK_RIGHT = 0x20, + AVS_MASK_SPEAKER_FRONT_LEFT_OF_CENTER = 0x40, + AVS_MASK_SPEAKER_FRONT_RIGHT_OF_CENTER = 0x80, + AVS_MASK_SPEAKER_BACK_CENTER = 0x100, + AVS_MASK_SPEAKER_SIDE_LEFT = 0x200, + AVS_MASK_SPEAKER_SIDE_RIGHT = 0x400, + AVS_MASK_SPEAKER_TOP_CENTER = 0x800, + AVS_MASK_SPEAKER_TOP_FRONT_LEFT = 0x1000, + AVS_MASK_SPEAKER_TOP_FRONT_CENTER = 0x2000, + AVS_MASK_SPEAKER_TOP_FRONT_RIGHT = 0x4000, + AVS_MASK_SPEAKER_TOP_BACK_LEFT = 0x8000, + AVS_MASK_SPEAKER_TOP_BACK_CENTER = 0x10000, + AVS_MASK_SPEAKER_TOP_BACK_RIGHT = 0x20000, + // Bit mask locations used up for the above positions + AVS_MASK_SPEAKER_DEFINED = 0x0003FFFF, + // Bit mask locations reserved for future use + AVS_MASK_SPEAKER_RESERVED = 0x7FFC0000, + // Used to specify that any possible permutation of speaker configurations + // Due to lack of available bits this one is put differently into image_type + AVS_MASK_SPEAKER_ALL = 0x80000000 }; +// AvsImageTypeFlags enum { - AVS_IT_BFF = 1<<0, - AVS_IT_TFF = 1<<1, - AVS_IT_FIELDBASED = 1<<2}; + AVS_IT_BFF = 1 << 0, + AVS_IT_TFF = 1 << 1, + AVS_IT_FIELDBASED = 1 << 2, + + // Audio channel mask support + AVS_IT_HAS_CHANNELMASK = 1 << 3, + // shifted by 4 bits compared to WAVEFORMATEXTENSIBLE dwChannelMask + // otherwise same as AvsChannelMask + AVS_IT_SPEAKER_FRONT_LEFT = 0x1 << 4, + AVS_IT_SPEAKER_FRONT_RIGHT = 0x2 << 4, + AVS_IT_SPEAKER_FRONT_CENTER = 0x4 << 4, + AVS_IT_SPEAKER_LOW_FREQUENCY = 0x8 << 4, + AVS_IT_SPEAKER_BACK_LEFT = 0x10 << 4, + AVS_IT_SPEAKER_BACK_RIGHT = 0x20 << 4, + AVS_IT_SPEAKER_FRONT_LEFT_OF_CENTER = 0x40 << 4, + AVS_IT_SPEAKER_FRONT_RIGHT_OF_CENTER = 0x80 << 4, + AVS_IT_SPEAKER_BACK_CENTER = 0x100 << 4, + AVS_IT_SPEAKER_SIDE_LEFT = 0x200 << 4, + AVS_IT_SPEAKER_SIDE_RIGHT = 0x400 << 4, + AVS_IT_SPEAKER_TOP_CENTER = 0x800 << 4, + AVS_IT_SPEAKER_TOP_FRONT_LEFT = 0x1000 << 4, + AVS_IT_SPEAKER_TOP_FRONT_CENTER = 0x2000 << 4, + AVS_IT_SPEAKER_TOP_FRONT_RIGHT = 0x4000 << 4, + AVS_IT_SPEAKER_TOP_BACK_LEFT = 0x8000 << 4, + AVS_IT_SPEAKER_TOP_BACK_CENTER = 0x10000 << 4, + AVS_IT_SPEAKER_TOP_BACK_RIGHT = 0x20000 << 4, + // End of officially defined speaker bits + // The next one is special, since cannot shift SPEAKER_ALL 0x80000000 further. + // Set mask and get mask handles it. + AVS_IT_SPEAKER_ALL = 0x40000 << 4, + // Mask for the defined 18 bits + SPEAKER_ALL + AVS_IT_SPEAKER_BITS_MASK = (AVS_MASK_SPEAKER_DEFINED << 4) | AVS_IT_SPEAKER_ALL, + AVS_IT_NEXT_AVAILABLE = 1 << 23 +}; enum { - AVS_FILTER_TYPE=1, - AVS_FILTER_INPUT_COLORSPACE=2, - AVS_FILTER_OUTPUT_TYPE=9, - AVS_FILTER_NAME=4, - AVS_FILTER_AUTHOR=5, - AVS_FILTER_VERSION=6, - AVS_FILTER_ARGS=7, - AVS_FILTER_ARGS_INFO=8, - AVS_FILTER_ARGS_DESCRIPTION=10, - AVS_FILTER_DESCRIPTION=11}; - -enum { //SUBTYPES - AVS_FILTER_TYPE_AUDIO=1, - AVS_FILTER_TYPE_VIDEO=2, - AVS_FILTER_OUTPUT_TYPE_SAME=3, - AVS_FILTER_OUTPUT_TYPE_DIFFERENT=4}; + AVS_FILTER_TYPE = 1, + AVS_FILTER_INPUT_COLORSPACE = 2, + AVS_FILTER_OUTPUT_TYPE = 9, + AVS_FILTER_NAME = 4, + AVS_FILTER_AUTHOR = 5, + AVS_FILTER_VERSION = 6, + AVS_FILTER_ARGS = 7, + AVS_FILTER_ARGS_INFO = 8, + AVS_FILTER_ARGS_DESCRIPTION = 10, + AVS_FILTER_DESCRIPTION = 11 +}; + +enum { // SUBTYPES + AVS_FILTER_TYPE_AUDIO = 1, + AVS_FILTER_TYPE_VIDEO = 2, + AVS_FILTER_OUTPUT_TYPE_SAME = 3, + AVS_FILTER_OUTPUT_TYPE_DIFFERENT = 4 +}; enum { + AVS_CACHE_25_NOTHING_26_UNUSED = 0, // New 2.6 explicitly defined cache hints. AVS_CACHE_NOTHING = 10, // Do not cache video. AVS_CACHE_WINDOW = 11, // Hard protect up to X frames within a range of X from the current frame N. @@ -294,41 +441,48 @@ enum { AVS_CACHE_GET_WINDOW = 31, // Get the current window h_span. AVS_CACHE_GET_RANGE = 32, // Get the current generic frame range. + // Set Audio cache mode and answers to CACHE_GETCHILD_AUDIO_MODE AVS_CACHE_AUDIO = 50, // Explicitly do cache audio, X byte cache. AVS_CACHE_AUDIO_NOTHING = 51, // Explicitly do not cache audio. AVS_CACHE_AUDIO_NONE = 52, // Audio cache off (auto mode), X byte initial cache. + AVS_CACHE_AUDIO_AUTO_START_OFF = 52, // synonym AVS_CACHE_AUDIO_AUTO = 53, // Audio cache on (auto mode), X byte initial cache. + AVS_CACHE_AUDIO_AUTO_START_ON = 53, // synonym + // These just returns actual value if clip is cached AVS_CACHE_GET_AUDIO_POLICY = 70, // Get the current audio policy. AVS_CACHE_GET_AUDIO_SIZE = 71, // Get the current audio cache size. - AVS_CACHE_PREFETCH_FRAME = 100, // Queue request to prefetch frame N. - AVS_CACHE_PREFETCH_GO = 101, // Action video prefetches. + AVS_CACHE_PREFETCH_FRAME = 100, // n/a Queue request to prefetch frame N. + AVS_CACHE_PREFETCH_GO = 101, // n/a Action video prefetches. + + AVS_CACHE_PREFETCH_AUDIO_BEGIN = 120, // n/a Begin queue request transaction to prefetch audio (take critical section). + AVS_CACHE_PREFETCH_AUDIO_STARTLO = 121, // n/a Set low 32 bits of start. + AVS_CACHE_PREFETCH_AUDIO_STARTHI = 122, // n/a Set high 32 bits of start. + AVS_CACHE_PREFETCH_AUDIO_COUNT = 123, // n/a Set low 32 bits of length. + AVS_CACHE_PREFETCH_AUDIO_COMMIT = 124, // n/a Enqueue request transaction to prefetch audio (release critical section). + AVS_CACHE_PREFETCH_AUDIO_GO = 125, // n/a Action audio prefetches. - AVS_CACHE_PREFETCH_AUDIO_BEGIN = 120, // Begin queue request transaction to prefetch audio (take critical section). - AVS_CACHE_PREFETCH_AUDIO_STARTLO = 121, // Set low 32 bits of start. - AVS_CACHE_PREFETCH_AUDIO_STARTHI = 122, // Set high 32 bits of start. - AVS_CACHE_PREFETCH_AUDIO_COUNT = 123, // Set low 32 bits of length. - AVS_CACHE_PREFETCH_AUDIO_COMMIT = 124, // Enqueue request transaction to prefetch audio (release critical section). - AVS_CACHE_PREFETCH_AUDIO_GO = 125, // Action audio prefetches. + AVS_CACHE_GETCHILD_CACHE_MODE = 200, // n/a Cache ask Child for desired video cache mode. + AVS_CACHE_GETCHILD_CACHE_SIZE = 201, // n/a Cache ask Child for desired video cache size. - AVS_CACHE_GETCHILD_CACHE_MODE = 200, // Cache ask Child for desired video cache mode. - AVS_CACHE_GETCHILD_CACHE_SIZE = 201, // Cache ask Child for desired video cache size. + // Filters are queried about their desired audio cache mode. + // Child can answer them with CACHE_AUDIO_xxx AVS_CACHE_GETCHILD_AUDIO_MODE = 202, // Cache ask Child for desired audio cache mode. AVS_CACHE_GETCHILD_AUDIO_SIZE = 203, // Cache ask Child for desired audio cache size. - AVS_CACHE_GETCHILD_COST = 220, // Cache ask Child for estimated processing cost. - AVS_CACHE_COST_ZERO = 221, // Child response of zero cost (ptr arithmetic only). - AVS_CACHE_COST_UNIT = 222, // Child response of unit cost (less than or equal 1 full frame blit). - AVS_CACHE_COST_LOW = 223, // Child response of light cost. (Fast) - AVS_CACHE_COST_MED = 224, // Child response of medium cost. (Real time) - AVS_CACHE_COST_HI = 225, // Child response of heavy cost. (Slow) + AVS_CACHE_GETCHILD_COST = 220, // n/a Cache ask Child for estimated processing cost. + AVS_CACHE_COST_ZERO = 221, // n/a Child response of zero cost (ptr arithmetic only). + AVS_CACHE_COST_UNIT = 222, // n/a Child response of unit cost (less than or equal 1 full frame blit). + AVS_CACHE_COST_LOW = 223, // n/a Child response of light cost. (Fast) + AVS_CACHE_COST_MED = 224, // n/a Child response of medium cost. (Real time) + AVS_CACHE_COST_HI = 225, // n/a Child response of heavy cost. (Slow) - AVS_CACHE_GETCHILD_THREAD_MODE = 240, // Cache ask Child for thread safety. - AVS_CACHE_THREAD_UNSAFE = 241, // Only 1 thread allowed for all instances. 2.5 filters default! - AVS_CACHE_THREAD_CLASS = 242, // Only 1 thread allowed for each instance. 2.6 filters default! - AVS_CACHE_THREAD_SAFE = 243, // Allow all threads in any instance. - AVS_CACHE_THREAD_OWN = 244, // Safe but limit to 1 thread, internally threaded. + AVS_CACHE_GETCHILD_THREAD_MODE = 240, // n/a Cache ask Child for thread safety. + AVS_CACHE_THREAD_UNSAFE = 241, // n/a Only 1 thread allowed for all instances. 2.5 filters default! + AVS_CACHE_THREAD_CLASS = 242, // n/a Only 1 thread allowed for each instance. 2.6 filters default! + AVS_CACHE_THREAD_SAFE = 243, // n/a Allow all threads in any instance. + AVS_CACHE_THREAD_OWN = 244, // n/a Safe but limit to 1 thread, internally threaded. AVS_CACHE_GETCHILD_ACCESS_COST = 260, // Cache ask Child for preferred access pattern. AVS_CACHE_ACCESS_RAND = 261, // Filter is access order agnostic. @@ -345,10 +499,12 @@ enum { AVS_CACHE_GET_SIZE = 506, AVS_CACHE_GET_REQUESTED_CAP = 507, AVS_CACHE_GET_CAPACITY = 508, - AVS_CACHE_GET_MTMODE = 509, + AVS_CACHE_GET_MTMODE = 509, // Filters specify their desired MT mode, see enum MtMode + // By returning IS_CACHE_ANS to IS_CACHE_REQ, we tell the caller we are a cache AVS_CACHE_IS_CACHE_REQ = 510, AVS_CACHE_IS_CACHE_ANS = 511, + // By returning IS_MTGUARD_ANS to IS_MTGUARD_REQ, we tell the caller we are an mt guard AVS_CACHE_IS_MTGUARD_REQ = 512, AVS_CACHE_IS_MTGUARD_ANS = 513, @@ -358,7 +514,6 @@ enum { AVS_CACHE_GET_CHILD_DEV_TYPE = 602, // Device types a fitler can receive AVS_CACHE_USER_CONSTANTS = 1000 // Smaller values are reserved for the core - }; @@ -376,8 +531,10 @@ enum { // AVSGetPropErrors for avs_prop_get_... enum { + AVS_GETPROPERROR_SUCCESS = 0, AVS_GETPROPERROR_UNSET = 1, AVS_GETPROPERROR_TYPE = 2, + AVS_GETPROPERROR_ERROR = 3, AVS_GETPROPERROR_INDEX = 4 }; @@ -385,18 +542,28 @@ enum { enum { AVS_PROPAPPENDMODE_REPLACE = 0, AVS_PROPAPPENDMODE_APPEND = 1, - AVS_PROPAPPENDMODE_TOUCH = 2 + AVS_PROPAPPENDMODE_TOUCH = 2 // n/a +}; + +// AVSPropDataTypeHint, used with prop_set_data_h +enum { + AVS_PROPDATATYPEHINT_UNKNOWN = -1, // dtUnknown = -1, + AVS_PROPDATATYPEHINT_BINARY = 0, // dtBinary = 0, + AVS_PROPDATATYPEHINT_UTF8 = 1 // dtUtf8 = 1 }; + // AvsEnvProperty for avs_get_env_property -enum -{ +enum { AVS_AEP_PHYSICAL_CPUS = 1, AVS_AEP_LOGICAL_CPUS = 2, AVS_AEP_THREADPOOL_THREADS = 3, AVS_AEP_FILTERCHAIN_THREADS = 4, AVS_AEP_THREAD_ID = 5, AVS_AEP_VERSION = 6, + AVS_AEP_HOST_SYSTEM_ENDIANNESS = 7, + AVS_AEP_INTERFACE_VERSION = 8, + AVS_AEP_INTERFACE_BUGFIX = 9, // Neo additionals AVS_AEP_NUM_DEVICES = 901, @@ -413,6 +580,17 @@ enum { AVS_ALLOCTYPE_POOLED_ALLOC = 2 }; +// Multithreading behaviour. AVS_Clip avs_set_cache_hints can return them on AVS_CACHE_GET_MTMODE query +enum { + AVS_MT_INVALID = 0, + AVS_MT_NICE_FILTER = 1, + AVS_MT_MULTI_INSTANCE = 2, + AVS_MT_SERIALIZED = 3, + AVS_MT_SPECIAL_MT = 4, + AVS_MT_MODE_COUNT = 5 +}; + + #ifdef BUILDING_AVSCORE AVSValue create_c_video_filter(AVSValue args, void * user_data, IScriptEnvironment * e0); @@ -446,7 +624,8 @@ typedef struct AVS_VideoInfo { int nchannels; // Image type properties - + // BFF, TFF, FIELDBASED. Also used for storing Channel Mask + // Manipulate it through the channelmask interface calls int image_type; } AVS_VideoInfo; @@ -497,6 +676,8 @@ AVSC_API(int, avs_bmp_size)(const AVS_VideoInfo * vi); AVSC_API(int, avs_is_color_space)(const AVS_VideoInfo * p, int c_space); // no API for these, inline helper functions + +// this is _not_ for frame properties AVSC_INLINE int avs_is_property(const AVS_VideoInfo * p, int property) { return ((p->image_type & property) == property); @@ -627,6 +808,13 @@ AVSC_API(int, avs_component_size)(const AVS_VideoInfo * p); AVSC_API(int, avs_bits_per_component)(const AVS_VideoInfo * p); +// V10 +AVSC_API(bool, avs_is_channel_mask_known)(const AVS_VideoInfo* p); + +AVSC_API(void, avs_set_channel_mask)(const AVS_VideoInfo* p, bool isChannelMaskKnown, unsigned int dwChannelMask); + +AVSC_API(unsigned int, avs_get_channel_mask)(const AVS_VideoInfo* p); + // end of Avisynth+ specific ///////////////////////////////////////////////////////////////////// @@ -640,6 +828,11 @@ AVSC_API(int, avs_bits_per_component)(const AVS_VideoInfo * p); // to be reused. The instances are deleted when the corresponding AVS // file is closed. +// DEPRECATION WARNING +// Note: The V12 API will only define +// typedef struct AVS_VideoFrame AVS_VideoFrame; +// without including any internals of AVS_VideoFrame and AVS_VideoFrameBuffer. + // AVS_VideoFrameBuffer is laid out identically to VideoFrameBuffer // DO NOT USE THIS STRUCTURE DIRECTLY typedef struct AVS_VideoFrameBuffer { @@ -656,22 +849,29 @@ typedef struct AVS_VideoFrameBuffer { // VideoFrame holds a "window" into a VideoFrameBuffer. -// AVS_VideoFrame is laid out identically to IVideoFrame +// AVS_VideoFrame is laid out identically to VideoFrame // DO NOT USE THIS STRUCTURE DIRECTLY +// In V11 header a leading '_' was added to member names intentionally. +// Stop direct access and use avs_get_xxx API calls instead! typedef struct AVS_VideoFrame { - volatile long refcount; - AVS_VideoFrameBuffer * vfb; - int offset; - int pitch, row_size, height; - int offsetU, offsetV; - int pitchUV; // U&V offsets are from top of picture. - int row_sizeUV, heightUV; // for Planar RGB offsetU, offsetV is for the 2nd and 3rd Plane. + volatile long _refcount; + AVS_VideoFrameBuffer * _vfb; + int _offset; + // DO NOT USE THEM DIRECTLY + // Use avs_get_pitch_p, avs_get_row_size_p, avs_get_height_p + int _pitch, _row_size, _height; + int _offsetU, _offsetV; + int _pitchUV; // U&V offsets are from top of picture. + int _row_sizeUV, _heightUV; // for Planar RGB offsetU, offsetV is for the 2nd and 3rd Plane. // for Planar RGB pitchUV and row_sizeUV = 0, because when no VideoInfo (MakeWriteable) // the decision on existence of UV is checked by zero pitch // AVS+ extension, avisynth.h: class does not break plugins if appended here - int offsetA; - int pitchA, row_sizeA; // 4th alpha plane support, pitch and row_size is 0 is none - void* properties; // frame properties + int _offsetA; + int _pitchA, _row_sizeA; // 4th alpha plane support, pitch and row_size is 0 is none + void* _properties; // interface V8: frame properties + // DO NOT USE DIRECTLY + // Use avs_video_frame_get_pixel_type (and avs_video_frame_amend_pixel_type in special cases) + int _pixel_type; // Interface V10: an automatically maintained copy from AVS_VideoInfo } AVS_VideoFrame; // Access functions for AVS_VideoFrame @@ -685,56 +885,34 @@ AVSC_API(const BYTE *, avs_get_read_ptr_p)(const AVS_VideoFrame * p, int plane); AVSC_API(int, avs_is_writable)(const AVS_VideoFrame * p); +// V9 +AVSC_API(int, avs_is_property_writable)(const AVS_VideoFrame* p); + AVSC_API(BYTE *, avs_get_write_ptr_p)(const AVS_VideoFrame * p, int plane); AVSC_API(void, avs_release_video_frame)(AVS_VideoFrame *); // makes a shallow copy of a video frame AVSC_API(AVS_VideoFrame *, avs_copy_video_frame)(AVS_VideoFrame *); -// no API for these, inline helper functions -#ifndef AVSC_NO_DECLSPEC -// this inline function is calling an API function -AVSC_INLINE int avs_get_pitch(const AVS_VideoFrame * p) { - return avs_get_pitch_p(p, 0); -} -#endif - -#ifndef AVSC_NO_DECLSPEC -// this inline function is calling an API function -AVSC_INLINE int avs_get_row_size(const AVS_VideoFrame * p) { - return avs_get_row_size_p(p, 0); } -#endif +// V10 +AVSC_API(int, avs_video_frame_get_pixel_type)(const AVS_VideoFrame* p); +AVSC_API(void, avs_video_frame_amend_pixel_type)(AVS_VideoFrame* p, int new_pixel_type); #ifndef AVSC_NO_DECLSPEC -// this inline function is calling an API function -AVSC_INLINE int avs_get_height(const AVS_VideoFrame * p) { - return avs_get_height_p(p, 0); -} +#ifdef AVSC_ALLOW_DEPRECATED +// Old inline helper functions which are named differently but eventually call API. +// Deprecated. If possible, do not use them any more +// Get data for plane AVS_DEFAULT_PLANE (Y or packed rgb): +AVSC_INLINE int avs_get_pitch(const AVS_VideoFrame * p) { return avs_get_pitch_p(p, AVS_DEFAULT_PLANE); } +AVSC_INLINE int avs_get_row_size(const AVS_VideoFrame * p) { return avs_get_row_size_p(p, AVS_DEFAULT_PLANE); } +AVSC_INLINE int avs_get_height(const AVS_VideoFrame * p) { return avs_get_height_p(p, AVS_DEFAULT_PLANE); } +AVSC_INLINE const BYTE* avs_get_read_ptr(const AVS_VideoFrame * p) { return avs_get_read_ptr_p(p, AVS_DEFAULT_PLANE); } +AVSC_INLINE BYTE* avs_get_write_ptr(const AVS_VideoFrame * p) { return avs_get_write_ptr_p(p, AVS_DEFAULT_PLANE); } +// named alternatively: +AVSC_INLINE void avs_release_frame(AVS_VideoFrame* f) { avs_release_video_frame(f); } +AVSC_INLINE AVS_VideoFrame* avs_copy_frame(AVS_VideoFrame* f) { return avs_copy_video_frame(f); } #endif - -#ifndef AVSC_NO_DECLSPEC -// this inline function is calling an API function -AVSC_INLINE const BYTE* avs_get_read_ptr(const AVS_VideoFrame * p) { - return avs_get_read_ptr_p(p, 0);} -#endif - -#ifndef AVSC_NO_DECLSPEC -// this inline function is calling an API function -AVSC_INLINE BYTE* avs_get_write_ptr(const AVS_VideoFrame * p) { - return avs_get_write_ptr_p(p, 0);} -#endif - -#ifndef AVSC_NO_DECLSPEC -// this inline function is calling an API function -AVSC_INLINE void avs_release_frame(AVS_VideoFrame * f) - {avs_release_video_frame(f);} -#endif - -#ifndef AVSC_NO_DECLSPEC -// this inline function is calling an API function -AVSC_INLINE AVS_VideoFrame * avs_copy_frame(AVS_VideoFrame * f) - {return avs_copy_video_frame(f);} #endif // Interface V8: frame properties @@ -760,8 +938,8 @@ typedef struct AVS_Map { // AVS_Value is laid out identically to AVSValue typedef struct AVS_Value AVS_Value; struct AVS_Value { - short type; // 'a'rray, 'c'lip, 'b'ool, 'i'nt, 'f'loat, 's'tring, 'v'oid, or 'l'ong, or fu'n'ction - // for some function e'rror + short type; // 'a'rray, 'c'lip, 'b'ool, 'i'nt, 'f'loat, 'd'ouble, 's'tring, 'v'oid, or 'l'ong, or fu'n'ction + // for some function 'e'rror short array_size; union { void * clip; // do not use directly, use avs_take_clip @@ -771,10 +949,14 @@ struct AVS_Value { const char * string; const AVS_Value * array; void * function; // not supported on C interface -#ifdef X86_64 +#if UINTPTR_MAX >= 0xffffffffffffffff // if ever, only x64 will support. It breaks struct size on 32 bit int64_t longlong; // 8 bytes double double_pt; // 8 bytes +#else + // 32 bit support workaround, pointers dont't break struct size on 32 bit + int64_t *longlong_ptr; + double *double_pt_ptr; #endif } d; }; @@ -784,42 +966,150 @@ struct AVS_Value { // with avs_copy_value. Consider it the equivalent of setting // a pointer to NULL static const AVS_Value avs_void = {'v'}; +// see also avs_set_to_void v11 API +/******************************* +* AVS_Value copy through API +*******************************/ +// requires avs_release_value! Can deep copy dyn_arrays. AVSC_API(void, avs_copy_value)(AVS_Value * dest, AVS_Value src); + +/******************************* +* AVS_Value release through API +*******************************/ AVSC_API(void, avs_release_value)(AVS_Value); -AVSC_API(AVS_Clip *, avs_take_clip)(AVS_Value, AVS_ScriptEnvironment *); -AVSC_API(void, avs_set_to_clip)(AVS_Value *, AVS_Clip *); +/************************************************* +* AVS_Value -> AVS_Clip get reference through API +*************************************************/ +// requires avs_release_clip! +AVSC_API(AVS_Clip *, avs_take_clip)(AVS_Value, AVS_ScriptEnvironment *); -// no API for these, inline helper functions +/**************************************************************************** +* AVS_Value type testers avs_is_xxxx ("baked" inline code) - NOT through API +****************************************************************************/ AVSC_INLINE int avs_defined(AVS_Value v) { return v.type != 'v'; } AVSC_INLINE int avs_is_clip(AVS_Value v) { return v.type == 'c'; } AVSC_INLINE int avs_is_bool(AVS_Value v) { return v.type == 'b'; } -AVSC_INLINE int avs_is_int(AVS_Value v) { return v.type == 'i'; } -AVSC_INLINE int avs_is_float(AVS_Value v) { return v.type == 'f' || v.type == 'i'; } +// v11: changed: for 32-bit 'int' or 64-bit 'long' as well +AVSC_INLINE int avs_is_int(AVS_Value v) { return v.type == 'i' || v.type == 'l'; } +// v11: new: for strict 64-bit 'long' content only +AVSC_INLINE int avs_is_long_strict(AVS_Value v) { return v.type == 'l'; } +// v11: changed: for 'double' and 'l'ong along with 'float' and 'int' +AVSC_INLINE int avs_is_float(AVS_Value v) { return v.type == 'd' || v.type == 'f' || v.type == 'i' || v.type == 'l'; } +// v11: new: for strict 64-bit 'long' content only +AVSC_INLINE int avs_is_floatf_strict(AVS_Value v) { return v.type == 'f'; } AVSC_INLINE int avs_is_string(AVS_Value v) { return v.type == 's'; } AVSC_INLINE int avs_is_array(AVS_Value v) { return v.type == 'a'; } AVSC_INLINE int avs_is_error(AVS_Value v) { return v.type == 'e'; } -AVSC_INLINE int avs_as_bool(AVS_Value v) - { return v.d.boolean; } +/**************************************************************************** +* AVS_Value type testers avs_val_is_xxxx (API) +****************************************************************************/ +AVSC_API(int, avs_val_defined)(AVS_Value v); +AVSC_API(int, avs_val_is_clip)(AVS_Value v); +AVSC_API(int, avs_val_is_bool)(AVS_Value v); +// v11: changed: for 32-bit 'int' or 64-bit 'long' as well +AVSC_API(int, avs_val_is_int)(AVS_Value v); +// v11: new: for strict 64-bit 'long' content only +AVSC_API(int, avs_val_is_long_strict)(AVS_Value v); +// v11: changed: for 'double' and 'l'ong along with 'float' and 'int' +AVSC_API(int, avs_val_is_float)(AVS_Value v); +// v11: new: for strict 32-bit 'float' content only +AVSC_API(int, avs_val_is_floatf_strict)(AVS_Value v); +AVSC_API(int, avs_val_is_string)(AVS_Value v); +AVSC_API(int, avs_val_is_array)(AVS_Value v); +AVSC_API(int, avs_val_is_error)(AVS_Value v); + +/*********************************************************** +* AVS_Value getters ("baked" inline code) - NOT through API +***********************************************************/ +AVSC_INLINE int avs_as_bool(AVS_Value v) { return v.d.boolean; } +// v11: avs_as_int also valid for 64-bit 'l'ong, but it gets truncated AVSC_INLINE int avs_as_int(AVS_Value v) - { return v.d.integer; } +{ + // we'll return a casted int64_t as-is +#if UINTPTR_MAX >= 0xffffffffffffffff + return v.type == 'l' ? (int)v.d.longlong : v.d.integer; +#else + return v.type == 'l' ? (int)*v.d.longlong_ptr : v.d.integer; +#endif +} +// v11: new, returns true 64 bit value, even for 32 bit content +AVSC_INLINE int64_t avs_as_long(AVS_Value v) +{ +#if UINTPTR_MAX >= 0xffffffffffffffff + return v.type == 'l' ? v.d.longlong : v.d.integer; +#else + return v.type == 'l' ? *v.d.longlong_ptr : v.d.integer; +#endif +} AVSC_INLINE const char * avs_as_string(AVS_Value v) { return avs_is_error(v) || avs_is_string(v) ? v.d.string : 0; } + +// v11: Extended for 'double' and 'l'ong AVSC_INLINE double avs_as_float(AVS_Value v) - { return avs_is_int(v) ? v.d.integer : v.d.floating_pt; } +{ +#if UINTPTR_MAX >= 0xffffffffffffffff + return v.type == 'i' ? v.d.integer : v.type=='l' ? v.d.longlong : v.type == 'd' ? v.d.double_pt : v.d.floating_pt; +#else + return v.type == 'i' ? v.d.integer : v.type == 'l' ? *v.d.longlong_ptr : v.type == 'd' ? *v.d.double_pt_ptr : v.d.floating_pt; +#endif +} AVSC_INLINE const char * avs_as_error(AVS_Value v) { return avs_is_error(v) ? v.d.string : 0; } AVSC_INLINE const AVS_Value * avs_as_array(AVS_Value v) { return v.d.array; } + +/*********************************************************** +* AVS_Value getters - using API v11 +***********************************************************/ +// API versions of the above. The AVS_Value is passed by reference everywhere +AVSC_API(int, avs_get_as_bool)(AVS_Value v); +AVSC_API(AVS_Clip *, avs_get_as_clip)(AVS_Value v, AVS_ScriptEnvironment* env); // similar to avs_take_clip +AVSC_API(int, avs_get_as_int)(AVS_Value v); +AVSC_API(int64_t, avs_get_as_long)(AVS_Value v); +AVSC_API(const char*, avs_get_as_string)(AVS_Value v); +AVSC_API(double, avs_get_as_float)(AVS_Value v); +AVSC_API(const char*, avs_get_as_error)(AVS_Value v); +AVSC_API(const AVS_Value*, avs_get_as_array)(AVS_Value v); + +/*********************************************************** +* AVS_Value array access - using API v11 +***********************************************************/ +AVSC_API(AVS_Value, avs_get_array_elt)(AVS_Value v, int index); +AVSC_API(int, avs_get_array_size)(AVS_Value v); + +/*********************************************************** +* AVS_Value array access - ("baked" inline code) - NOT through API +***********************************************************/ AVSC_INLINE int avs_array_size(AVS_Value v) { return avs_is_array(v) ? v.array_size : 1; } AVSC_INLINE AVS_Value avs_array_elt(AVS_Value v, int index) { return avs_is_array(v) ? v.d.array[index] : v; } -// only use these functions on an AVS_Value that does not already have +/******************************* +* AVS_Value setters through API +*******************************/ +AVSC_API(void, avs_set_to_clip)(AVS_Value*, AVS_Clip*); +// v11 provides setter APIs for all types beyond 'clip' +AVSC_API(void, avs_set_to_error)(AVS_Value*, const char* v0); +AVSC_API(void, avs_set_to_bool)(AVS_Value*, int v0); +AVSC_API(void, avs_set_to_int)(AVS_Value*, int v0); +AVSC_API(void, avs_set_to_float)(AVS_Value*, float v0); +AVSC_API(void, avs_set_to_string)(AVS_Value*, const char* v0); +AVSC_API(void, avs_set_to_double)(AVS_Value*, double d); // requires avs_release_value, especially on 32 bit proc +AVSC_API(void, avs_set_to_long)(AVS_Value*, int64_t l); // requires avs_release_value, especially on 32 bit proc +AVSC_API(void, avs_set_to_array)(AVS_Value*, AVS_Value* src, int size); // requires avs_release_value, multi-nested deep copied arrays +AVSC_API(void, avs_set_to_void)(AVS_Value*); // void +/*********************************************************** +* AVS_Value setters ("baked" inline code) - NOT through API +***********************************************************/ +// Each of these inline 'baked code' setters has API counterparts: +// avs_set_to_error, avs_set_to_bool, avs_set_to_int, avs_set_to_string, avs_set_to_float. +// Only use these functions on an AVS_Value that does not already have // an active value. Remember, treat AVS_Value as a fat pointer. +// These do not require avs_release_value AVSC_INLINE AVS_Value avs_new_value_bool(int v0) { AVS_Value v; v.type = 'b'; v.d.boolean = v0 == 0 ? 0 : 1; return v; } AVSC_INLINE AVS_Value avs_new_value_int(int v0) @@ -830,14 +1120,23 @@ AVSC_INLINE AVS_Value avs_new_value_float(float v0) { AVS_Value v; v.type = 'f'; v.d.floating_pt = v0; return v;} AVSC_INLINE AVS_Value avs_new_value_error(const char * v0) { AVS_Value v; v.type = 'e'; v.d.string = v0; return v; } +AVSC_INLINE AVS_Value avs_new_value_array(AVS_Value * v0, int size) + { AVS_Value v; v.type = 'a'; v.d.array = v0; v.array_size = (short)size; return v; } +/*********************************************************** +* AVS_Value setters - inline wrappers using API +***********************************************************/ #ifndef AVSC_NO_DECLSPEC -// this inline function is calling an API function -AVSC_INLINE AVS_Value avs_new_value_clip(AVS_Clip * v0) +// Use avs_release_value / avs_copy_value +AVSC_INLINE AVS_Value avs_new_value_clip(AVS_Clip* v0) { AVS_Value v; avs_set_to_clip(&v, v0); return v; } #endif -AVSC_INLINE AVS_Value avs_new_value_array(AVS_Value * v0, int size) - { AVS_Value v; v.type = 'a'; v.d.array = v0; v.array_size = (short)size; return v; } -// end of inline helper functions +/*********************************************************** +* AVS_Value setters - inline wrappers using API v11 +* None of them. For Avisynth arrays, 64 bit long and double use API +***********************************************************/ +// No avs_new_value_double => use avs_set_to_double API instead +// No avs_new_value_long => use avs_set_to_long API instead +// for arrays use avs_set_to_array API call for Avisynth deep smart arrays ///////////////////////////////////////////////////////////////////// // @@ -870,10 +1169,15 @@ AVSC_API(int, avs_set_cache_hints)(AVS_Clip *, typedef AVS_Value (AVSC_CC * AVS_ApplyFunc) (AVS_ScriptEnvironment *, AVS_Value args, void * user_data); +// v11 alternative of avs_add_function with return value by reference +// This is the callback type used by avs_add_function_r +typedef void(AVSC_CC* AVS_ApplyFuncR) +(AVS_ScriptEnvironment*, AVS_Value* ret, AVS_Value args, void* user_data); + typedef struct AVS_FilterInfo AVS_FilterInfo; struct AVS_FilterInfo { - // these members should not be modified outside of the AVS_ApplyFunc callback + // these members should not be modified outside of the AVS_ApplyFunc or AVS_ApplyFuncR callback AVS_Clip * child; AVS_VideoInfo vi; AVS_ScriptEnvironment * env; @@ -893,11 +1197,11 @@ struct AVS_FilterInfo }; // Create a new filter -// fi is set to point to the AVS_FilterInfo so that you can +// 'fi' is set to point to the AVS_FilterInfo so that you can // modify it once it is initialized. -// store_child should generally be set to true. If it is not -// set than ALL methods (the function pointers) must be defined -// If it is set than you do not need to worry about freeing the child +// 'store_child' should generally be set to true. If it is not +// set then ALL methods (the function pointers) must be defined +// If it is set then you do not need to worry about freeing the child // clip. AVSC_API(AVS_Clip *, avs_new_c_filter)(AVS_ScriptEnvironment * e, AVS_FilterInfo * * fi, @@ -958,10 +1262,16 @@ AVSC_API(char *, avs_sprintf)(AVS_ScriptEnvironment *, const char * fmt, ...); AVSC_API(char *, avs_vsprintf)(AVS_ScriptEnvironment *, const char * fmt, va_list val); +// avs_add_function, the callback (apply) returns result as return value (AVS_Value) AVSC_API(int, avs_add_function)(AVS_ScriptEnvironment *, const char * name, const char * params, AVS_ApplyFunc apply, void * user_data); +// v11 avs_add_function_r, the callback (apply) returns result in byref parameter (AVS_Value *) +AVSC_API(int, avs_add_function_r)(AVS_ScriptEnvironment*, + const char* name, const char* params, + AVS_ApplyFuncR apply, void* user_data); + AVSC_API(int, avs_function_exists)(AVS_ScriptEnvironment *, const char * name); AVSC_API(AVS_Value, avs_invoke)(AVS_ScriptEnvironment *, const char * name, @@ -1002,6 +1312,9 @@ AVSC_INLINE AVS_VideoFrame * avs_new_frame(AVS_ScriptEnvironment * env, AVSC_API(int, avs_make_writable)(AVS_ScriptEnvironment *, AVS_VideoFrame * * pvf); +// V9 +AVSC_API(int, avs_make_property_writable)(AVS_ScriptEnvironment*, AVS_VideoFrame** pvf); + AVSC_API(void, avs_bit_blt)(AVS_ScriptEnvironment *, BYTE* dstp, int dst_pitch, const BYTE* srcp, int src_pitch, int row_size, int height); typedef void (AVSC_CC *AVS_ShutdownFunc)(void* user_data, AVS_ScriptEnvironment * env); @@ -1017,15 +1330,30 @@ AVSC_API(int, avs_set_memory_max)(AVS_ScriptEnvironment *, int mem); AVSC_API(int, avs_set_working_dir)(AVS_ScriptEnvironment *, const char * newdir); +// V12 +// Acquire a global named lock. +// 'env' is the environment handle, 'name' is the lock identifier (e.g., "fftw"). +// Returns 1 on success, 0 on failure. +AVSC_API(int, avs_acquire_global_lock)(AVS_ScriptEnvironment *, const char* name); +// V12 +// Release a global named lock. +// 'env' is the environment handle, 'name' is the lock identifier. +AVSC_API(void, avs_release_global_lock)(AVS_ScriptEnvironment *, const char* name); + // avisynth.dll exports this; it's a way to use it as a library, without // writing an AVS script or without going through AVIFile. AVSC_API(AVS_ScriptEnvironment *, avs_create_script_environment)(int version); -// this symbol is the entry point for the plugin and must -// be defined +// This symbol serves as the entry point for the plugin (up to Avisynth 3.7.3, non-64-bit aware) +AVSC_EXPORT +const char* AVSC_CC avisynth_c_plugin_init(AVS_ScriptEnvironment* env); + +// This symbol serves as the entry point for the 64-bit aware plugin. Since V11 AVSC_EXPORT -const char * AVSC_CC avisynth_c_plugin_init(AVS_ScriptEnvironment* env); +const char* AVSC_CC avisynth_c_plugin_init2(AVS_ScriptEnvironment* env); +// Either one or both must be defined for a plugin +// avisynth_c_plugin_init2 is checked before avisynth_c_plugin_init AVSC_API(void, avs_delete_script_environment)(AVS_ScriptEnvironment *); @@ -1050,10 +1378,17 @@ AVSC_API(char, avs_prop_get_type)(AVS_ScriptEnvironment* p, const AVS_Map* map, // see AVS_GETPROPERROR_... enums AVSC_API(int64_t, avs_prop_get_int)(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key, int index, int* error); AVSC_API(double, avs_prop_get_float)(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key, int index, int* error); +// Note: avs_prop_get_data was fixed in interface V9.1 AVSC_API(const char*, avs_prop_get_data)(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key, int index, int* error); AVSC_API(int, avs_prop_get_data_size)(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key, int index, int* error); +// V11 +AVSC_API(int, avs_prop_get_data_type_hint)(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key, int index, int* error); AVSC_API(AVS_Clip*, avs_prop_get_clip)(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key, int index, int* error); AVSC_API(const AVS_VideoFrame*, avs_prop_get_frame)(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key, int index, int* error); +// V11 +AVSC_API(int, avs_prop_get_int_saturated)(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key, int index, int* error); +// V11 +AVSC_API(float, avs_prop_get_float_saturated)(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key, int index, int* error); AVSC_API(int, avs_prop_delete_key)(AVS_ScriptEnvironment* p, AVS_Map* map, const char* key); @@ -1061,6 +1396,9 @@ AVSC_API(int, avs_prop_delete_key)(AVS_ScriptEnvironment* p, AVS_Map* map, const AVSC_API(int, avs_prop_set_int)(AVS_ScriptEnvironment* p, AVS_Map* map, const char* key, int64_t i, int append); AVSC_API(int, avs_prop_set_float)(AVS_ScriptEnvironment* p, AVS_Map* map, const char* key, double d, int append); AVSC_API(int, avs_prop_set_data)(AVS_ScriptEnvironment* p, AVS_Map* map, const char* key, const char* d, int length, int append); +// v11 +// SEE AVS_PROPDATATYPEHINT_... enums +AVSC_API(int, avs_prop_set_data_h)(AVS_ScriptEnvironment* p, AVS_Map* map, const char* key, const char* d, int length, int type, int append); AVSC_API(int, avs_prop_set_clip)(AVS_ScriptEnvironment* p, AVS_Map* map, const char* key, AVS_Clip* clip, int append); AVSC_API(int, avs_prop_set_frame)(AVS_ScriptEnvironment* p, AVS_Map* map, const char* key, const AVS_VideoFrame* frame, int append); @@ -1073,11 +1411,11 @@ AVSC_API(void, avs_clear_map)(AVS_ScriptEnvironment* p, AVS_Map* map); // with frame property source AVSC_API(AVS_VideoFrame*, avs_new_video_frame_p)(AVS_ScriptEnvironment*, - const AVS_VideoInfo* vi, AVS_VideoFrame* propSrc); + const AVS_VideoInfo* vi, const AVS_VideoFrame* prop_src); // with frame property source AVSC_API(AVS_VideoFrame*, avs_new_video_frame_p_a)(AVS_ScriptEnvironment*, - const AVS_VideoInfo* vi, AVS_VideoFrame* propSrc, int align); + const AVS_VideoInfo* vi, const AVS_VideoFrame* prop_src, int align); // Generic query to ask for various system properties, see AVS_AEP_xxx enums AVSC_API(size_t, avs_get_env_property)(AVS_ScriptEnvironment*, int avs_aep_prop); @@ -1102,6 +1440,11 @@ AVSC_API(double, avs_get_var_double)(AVS_ScriptEnvironment*, const char* name, d AVSC_API(const char*, avs_get_var_string)(AVS_ScriptEnvironment*, const char* name, const char* def); AVSC_API(int64_t, avs_get_var_long)(AVS_ScriptEnvironment*, const char* name, int64_t def); +// This is an example of dynamically loading Avisynth function addresses +// instead of statically linked library. (Windows API) +// In general: define AVSC_NO_DECLSPEC for only API prototypes, then manually load and get +// function addresses from avisynth.dll/libavisynth.so + #if defined(AVS_WINDOWS) // The following stuff is only relevant for Windows DLL handling; Linux does it completely differently. #ifdef AVSC_NO_DECLSPEC @@ -1129,9 +1472,9 @@ typedef struct AVS_Library AVS_Library; // e.g. "AVSC_DECLARE_FUNC(avs_add_function);" // is a shortcut for "avs_add_function_func avs_add_function;" -// Note: AVSC_INLINE functions which call into API, -// are guarded by #ifndef AVSC_NO_DECLSPEC -// They should call the appropriate library-> API entry +// Note: AVSC_INLINE functions, which call into API, +// are guarded by #ifndef AVSC_NO_DECLSPEC. +// They should call the appropriate library-> API entry. struct AVS_Library { HMODULE handle; @@ -1266,6 +1609,62 @@ struct AVS_Library { AVSC_DECLARE_FUNC(avs_pool_allocate); AVSC_DECLARE_FUNC(avs_pool_free); + + // V9 + AVSC_DECLARE_FUNC(avs_is_property_writable); + AVSC_DECLARE_FUNC(avs_make_property_writable); + + // V10 + AVSC_DECLARE_FUNC(avs_video_frame_get_pixel_type); + AVSC_DECLARE_FUNC(avs_video_frame_amend_pixel_type); + + AVSC_DECLARE_FUNC(avs_is_channel_mask_known); + AVSC_DECLARE_FUNC(avs_set_channel_mask); + AVSC_DECLARE_FUNC(avs_get_channel_mask); + + // V11 + // setters for all types (except clip, which have already existed) + AVSC_DECLARE_FUNC(avs_set_to_error); + AVSC_DECLARE_FUNC(avs_set_to_bool); + AVSC_DECLARE_FUNC(avs_set_to_int); + AVSC_DECLARE_FUNC(avs_set_to_string); + AVSC_DECLARE_FUNC(avs_set_to_float); + AVSC_DECLARE_FUNC(avs_set_to_long); + AVSC_DECLARE_FUNC(avs_set_to_double); + AVSC_DECLARE_FUNC(avs_set_to_array); + AVSC_DECLARE_FUNC(avs_set_to_void); + // getters for all basic types. note: avs_get_as_float returns double + AVSC_DECLARE_FUNC(avs_get_as_error); + AVSC_DECLARE_FUNC(avs_get_as_array); + AVSC_DECLARE_FUNC(avs_get_as_bool); + AVSC_DECLARE_FUNC(avs_get_as_clip); + AVSC_DECLARE_FUNC(avs_get_as_int); + AVSC_DECLARE_FUNC(avs_get_as_string); + AVSC_DECLARE_FUNC(avs_get_as_float); + AVSC_DECLARE_FUNC(avs_get_as_long); + AVSC_DECLARE_FUNC(avs_get_array_size); + AVSC_DECLARE_FUNC(avs_get_array_elt); + // frame props + AVSC_DECLARE_FUNC(avs_prop_get_int_saturated); + AVSC_DECLARE_FUNC(avs_prop_get_float_saturated); + AVSC_DECLARE_FUNC(avs_prop_get_data_type_hint); + AVSC_DECLARE_FUNC(avs_prop_set_data_h); + // alternative add_function returning data in byref AVS_Value + AVSC_DECLARE_FUNC(avs_add_function_r); + // API AVS_Value type checkers + AVSC_DECLARE_FUNC(avs_val_defined); + AVSC_DECLARE_FUNC(avs_val_is_clip); + AVSC_DECLARE_FUNC(avs_val_is_bool); + AVSC_DECLARE_FUNC(avs_val_is_int); + AVSC_DECLARE_FUNC(avs_val_is_long_strict); + AVSC_DECLARE_FUNC(avs_val_is_float); + AVSC_DECLARE_FUNC(avs_val_is_floatf_strict); + AVSC_DECLARE_FUNC(avs_val_is_string); + AVSC_DECLARE_FUNC(avs_val_is_array); + AVSC_DECLARE_FUNC(avs_val_is_error); + // V12 + AVSC_DECLARE_FUNC(avs_acquire_global_lock); + AVSC_DECLARE_FUNC(avs_release_global_lock); }; #undef AVSC_DECLARE_FUNC @@ -1322,11 +1721,13 @@ AVSC_INLINE AVS_Library * avs_load_library() { #define __AVSC_STRINGIFY(x) #x #define AVSC_STRINGIFY(x) __AVSC_STRINGIFY(x) -#define AVSC_LOAD_FUNC(name) {\ +#define AVSC_DO_LOAD_FUNC(name, allow_missing) {\ library->name = (name##_func) GetProcAddress(library->handle, AVSC_STRINGIFY(name));\ - if (library->name == NULL)\ + if (!allow_missing && library->name == NULL)\ goto fail;\ } +#define AVSC_LOAD_FUNC(name) AVSC_DO_LOAD_FUNC(name, 0) +#define AVSC_LOAD_FUNC_OPT(name) AVSC_DO_LOAD_FUNC(name, 1) #ifdef AVS26_FALLBACK_SIMULATION // When an API function is not loadable, let's try a replacement @@ -1389,8 +1790,6 @@ avs_bits_per_component constant 8 (8 bits/component) AVSC_LOAD_FUNC(avs_new_c_filter); AVSC_LOAD_FUNC(avs_new_video_frame_a); - - AVSC_LOAD_FUNC(avs_release_clip); AVSC_LOAD_FUNC(avs_release_value); AVSC_LOAD_FUNC(avs_release_video_frame); @@ -1445,68 +1844,125 @@ avs_bits_per_component constant 8 (8 bits/component) AVSC_LOAD_FUNC_FALLBACK_SIMULATED(avs_bits_per_component, avs_bits_per_component_fallback); #else // Avisynth+ specific - AVSC_LOAD_FUNC(avs_is_rgb48); - AVSC_LOAD_FUNC(avs_is_rgb64); - AVSC_LOAD_FUNC(avs_is_444); - AVSC_LOAD_FUNC(avs_is_422); - AVSC_LOAD_FUNC(avs_is_420); - AVSC_LOAD_FUNC(avs_is_y); - AVSC_LOAD_FUNC(avs_is_yuva); - AVSC_LOAD_FUNC(avs_is_planar_rgb); - AVSC_LOAD_FUNC(avs_is_planar_rgba); - AVSC_LOAD_FUNC(avs_num_components); - AVSC_LOAD_FUNC(avs_component_size); - AVSC_LOAD_FUNC(avs_bits_per_component); + AVSC_LOAD_FUNC_OPT(avs_is_rgb48); + AVSC_LOAD_FUNC_OPT(avs_is_rgb64); + AVSC_LOAD_FUNC_OPT(avs_is_444); + AVSC_LOAD_FUNC_OPT(avs_is_422); + AVSC_LOAD_FUNC_OPT(avs_is_420); + AVSC_LOAD_FUNC_OPT(avs_is_y); + AVSC_LOAD_FUNC_OPT(avs_is_yuva); + AVSC_LOAD_FUNC_OPT(avs_is_planar_rgb); + AVSC_LOAD_FUNC_OPT(avs_is_planar_rgba); + AVSC_LOAD_FUNC_OPT(avs_num_components); + AVSC_LOAD_FUNC_OPT(avs_component_size); + AVSC_LOAD_FUNC_OPT(avs_bits_per_component); #endif // Avisynth+ interface V8, no backward compatible simulation - AVSC_LOAD_FUNC(avs_subframe_planar_a); + AVSC_LOAD_FUNC_OPT(avs_subframe_planar_a); // frame properties - AVSC_LOAD_FUNC(avs_copy_frame_props); - AVSC_LOAD_FUNC(avs_get_frame_props_ro); - AVSC_LOAD_FUNC(avs_get_frame_props_rw); - AVSC_LOAD_FUNC(avs_prop_num_keys); - AVSC_LOAD_FUNC(avs_prop_get_key); - AVSC_LOAD_FUNC(avs_prop_num_elements); - AVSC_LOAD_FUNC(avs_prop_get_type); - AVSC_LOAD_FUNC(avs_prop_get_int); - AVSC_LOAD_FUNC(avs_prop_get_float); - AVSC_LOAD_FUNC(avs_prop_get_data); - AVSC_LOAD_FUNC(avs_prop_get_data_size); - AVSC_LOAD_FUNC(avs_prop_get_clip); - AVSC_LOAD_FUNC(avs_prop_get_frame); - AVSC_LOAD_FUNC(avs_prop_delete_key); - AVSC_LOAD_FUNC(avs_prop_set_int); - AVSC_LOAD_FUNC(avs_prop_set_float); - AVSC_LOAD_FUNC(avs_prop_set_data); - AVSC_LOAD_FUNC(avs_prop_set_clip); - AVSC_LOAD_FUNC(avs_prop_set_frame); - - AVSC_LOAD_FUNC(avs_prop_get_int_array); - AVSC_LOAD_FUNC(avs_prop_get_float_array); - AVSC_LOAD_FUNC(avs_prop_set_int_array); - AVSC_LOAD_FUNC(avs_prop_set_float_array); - - AVSC_LOAD_FUNC(avs_clear_map); + AVSC_LOAD_FUNC_OPT(avs_copy_frame_props); + AVSC_LOAD_FUNC_OPT(avs_get_frame_props_ro); + AVSC_LOAD_FUNC_OPT(avs_get_frame_props_rw); + AVSC_LOAD_FUNC_OPT(avs_prop_num_keys); + AVSC_LOAD_FUNC_OPT(avs_prop_get_key); + AVSC_LOAD_FUNC_OPT(avs_prop_num_elements); + AVSC_LOAD_FUNC_OPT(avs_prop_get_type); + AVSC_LOAD_FUNC_OPT(avs_prop_get_int); + AVSC_LOAD_FUNC_OPT(avs_prop_get_float); + AVSC_LOAD_FUNC_OPT(avs_prop_get_data); + AVSC_LOAD_FUNC_OPT(avs_prop_get_data_size); + AVSC_LOAD_FUNC_OPT(avs_prop_get_clip); + AVSC_LOAD_FUNC_OPT(avs_prop_get_frame); + AVSC_LOAD_FUNC_OPT(avs_prop_delete_key); + AVSC_LOAD_FUNC_OPT(avs_prop_set_int); + AVSC_LOAD_FUNC_OPT(avs_prop_set_float); + AVSC_LOAD_FUNC_OPT(avs_prop_set_data); + AVSC_LOAD_FUNC_OPT(avs_prop_set_clip); + AVSC_LOAD_FUNC_OPT(avs_prop_set_frame); + + AVSC_LOAD_FUNC_OPT(avs_prop_get_int_array); + AVSC_LOAD_FUNC_OPT(avs_prop_get_float_array); + AVSC_LOAD_FUNC_OPT(avs_prop_set_int_array); + AVSC_LOAD_FUNC_OPT(avs_prop_set_float_array); + + AVSC_LOAD_FUNC_OPT(avs_clear_map); // NewVideoFrame with frame properties - AVSC_LOAD_FUNC(avs_new_video_frame_p); - AVSC_LOAD_FUNC(avs_new_video_frame_p_a); - - AVSC_LOAD_FUNC(avs_get_env_property); - - AVSC_LOAD_FUNC(avs_get_var_try); - AVSC_LOAD_FUNC(avs_get_var_bool); - AVSC_LOAD_FUNC(avs_get_var_int); - AVSC_LOAD_FUNC(avs_get_var_double); - AVSC_LOAD_FUNC(avs_get_var_string); - AVSC_LOAD_FUNC(avs_get_var_long); - - AVSC_LOAD_FUNC(avs_pool_allocate); - AVSC_LOAD_FUNC(avs_pool_free); + AVSC_LOAD_FUNC_OPT(avs_new_video_frame_p); + AVSC_LOAD_FUNC_OPT(avs_new_video_frame_p_a); + + AVSC_LOAD_FUNC_OPT(avs_get_env_property); + + AVSC_LOAD_FUNC_OPT(avs_get_var_try); + AVSC_LOAD_FUNC_OPT(avs_get_var_bool); + AVSC_LOAD_FUNC_OPT(avs_get_var_int); + AVSC_LOAD_FUNC_OPT(avs_get_var_double); + AVSC_LOAD_FUNC_OPT(avs_get_var_string); + AVSC_LOAD_FUNC_OPT(avs_get_var_long); + + AVSC_LOAD_FUNC_OPT(avs_pool_allocate); + AVSC_LOAD_FUNC_OPT(avs_pool_free); + + // V9 + AVSC_LOAD_FUNC_OPT(avs_make_property_writable); + AVSC_LOAD_FUNC_OPT(avs_is_property_writable); + + // V10 + AVSC_LOAD_FUNC_OPT(avs_video_frame_get_pixel_type); + AVSC_LOAD_FUNC_OPT(avs_video_frame_amend_pixel_type); + AVSC_LOAD_FUNC_OPT(avs_is_channel_mask_known); + AVSC_LOAD_FUNC_OPT(avs_set_channel_mask); + AVSC_LOAD_FUNC_OPT(avs_get_channel_mask); + + // V11 + // setters for all types (avs_set_to_clip already existed) + AVSC_LOAD_FUNC_OPT(avs_set_to_error); + AVSC_LOAD_FUNC_OPT(avs_set_to_bool); + AVSC_LOAD_FUNC_OPT(avs_set_to_int); + AVSC_LOAD_FUNC_OPT(avs_set_to_string); + AVSC_LOAD_FUNC_OPT(avs_set_to_float); + AVSC_LOAD_FUNC_OPT(avs_set_to_long); + AVSC_LOAD_FUNC_OPT(avs_set_to_double); + AVSC_LOAD_FUNC_OPT(avs_set_to_array); + AVSC_LOAD_FUNC_OPT(avs_set_to_void); + // these have inline equivalents as well + AVSC_LOAD_FUNC_OPT(avs_get_as_error); + AVSC_LOAD_FUNC_OPT(avs_get_as_array); + AVSC_LOAD_FUNC_OPT(avs_get_as_bool); + AVSC_LOAD_FUNC_OPT(avs_get_as_clip); + AVSC_LOAD_FUNC_OPT(avs_get_as_int); + AVSC_LOAD_FUNC_OPT(avs_get_as_string); + AVSC_LOAD_FUNC_OPT(avs_get_as_float); + AVSC_LOAD_FUNC_OPT(avs_get_as_long); + AVSC_LOAD_FUNC_OPT(avs_get_array_size); + AVSC_LOAD_FUNC_OPT(avs_get_array_elt); + // frame property + AVSC_LOAD_FUNC_OPT(avs_prop_get_int_saturated); + AVSC_LOAD_FUNC_OPT(avs_prop_get_float_saturated); + AVSC_LOAD_FUNC_OPT(avs_prop_get_data_type_hint); + AVSC_LOAD_FUNC_OPT(avs_prop_set_data_h); + // alternative add_function + AVSC_LOAD_FUNC_OPT(avs_add_function_r); + // API AVS_Value type checkers + AVSC_LOAD_FUNC_OPT(avs_val_defined); + AVSC_LOAD_FUNC_OPT(avs_val_is_clip); + AVSC_LOAD_FUNC_OPT(avs_val_is_bool); + AVSC_LOAD_FUNC_OPT(avs_val_is_int); + AVSC_LOAD_FUNC_OPT(avs_val_is_long_strict); + AVSC_LOAD_FUNC_OPT(avs_val_is_float); + AVSC_LOAD_FUNC_OPT(avs_val_is_floatf_strict); + AVSC_LOAD_FUNC_OPT(avs_val_is_string); + AVSC_LOAD_FUNC_OPT(avs_val_is_array); + AVSC_LOAD_FUNC_OPT(avs_val_is_error); + // V12 + AVSC_LOAD_FUNC_OPT(avs_acquire_global_lock); + AVSC_LOAD_FUNC_OPT(avs_release_global_lock); #undef __AVSC_STRINGIFY #undef AVSC_STRINGIFY +#undef AVSC_DO_LOAD_FUNC #undef AVSC_LOAD_FUNC +#undef AVSC_LOAD_FUNC_OPT #undef AVSC_LOAD_FUNC_FALLBACK #undef AVSC_LOAD_FUNC_FALLBACK_SIMULATED diff --git a/src/include/avs/capi.h b/src/include/avs/capi.h index 3b9c108..7629296 100644 --- a/src/include/avs/capi.h +++ b/src/include/avs/capi.h @@ -94,7 +94,11 @@ #ifdef BUILDING_AVSCORE #ifdef AVS_WINDOWS -# define AVSC_EXPORT __declspec(dllexport) +# ifndef AVS_STATIC_LIB +# define AVSC_EXPORT __declspec(dllexport) +# else +# define AVSC_EXPORT +# endif # define AVSC_API(ret, name) EXTERN_C AVSC_EXPORT ret AVSC_CC name #else # define AVSC_EXPORT EXTERN_C @@ -102,8 +106,13 @@ #endif #else # define AVSC_EXPORT EXTERN_C __declspec(dllexport) +# ifndef AVS_STATIC_LIB +# define AVSC_IMPORT __declspec(dllimport) +# else +# define AVSC_IMPORT +# endif # ifndef AVSC_NO_DECLSPEC -# define AVSC_API(ret, name) EXTERN_C __declspec(dllimport) ret AVSC_CC name +# define AVSC_API(ret, name) EXTERN_C AVSC_IMPORT ret AVSC_CC name # else # define AVSC_API(ret, name) typedef ret (AVSC_CC *name##_func) # endif diff --git a/src/include/avs/config.h b/src/include/avs/config.h index f0b550d..7001763 100644 --- a/src/include/avs/config.h +++ b/src/include/avs/config.h @@ -48,8 +48,8 @@ # define X86_64 #elif defined(_M_IX86) || defined(__i386__) # define X86_32 -// VS2017 introduced _M_ARM64 #elif defined(_M_ARM64) || defined(__aarch64__) +// _M_ARM64: MSVC; __aarch64__: GCC and Clang # define ARM64 #elif defined(_M_ARM) || defined(__arm__) # define ARM32 @@ -57,6 +57,14 @@ # define PPC64 #elif defined(_M_PPC) || defined(__PPC__) || defined(__POWERPC__) # define PPC32 +#elif defined(__riscv) +# define RISCV +#elif defined(__loongarch__) +# define LOONGARCH +#elif defined(__sparc_v9__) +# define SPARC +#elif defined(__mips__) +# define MIPS #else # error Unsupported CPU architecture. #endif @@ -73,17 +81,20 @@ # define CLANG #if defined(_MSC_VER) # define MSVC -# define AVS_FORCEINLINE __attribute__((always_inline)) -#else -# define AVS_FORCEINLINE __attribute__((always_inline)) inline #endif -#elif defined(_MSC_VER) +# define AVS_FORCEINLINE __attribute__((always_inline)) inline +#elif defined(_MSC_VER) # define MSVC # define MSVC_PURE # define AVS_FORCEINLINE __forceinline #elif defined(__GNUC__) # define GCC # define AVS_FORCEINLINE __attribute__((always_inline)) inline +#elif defined(__INTEL_COMPILER) || defined(__INTEL_LLVM_COMPILER) +// Intel C++ Compilers with MSVC command line interface will not appear here rather at _MSC_VER +# define AVS_FORCEINLINE inline +# undef __forceinline +# define __forceinline inline #else # error Unsupported compiler. # define AVS_FORCEINLINE inline @@ -109,6 +120,27 @@ # error Operating system unsupported. #endif +#if defined(AVS_WINDOWS) +# if defined(X86_32) || defined(X86_64) +# define AVS_WINDOWS_X86 +# elif defined(ARM64) || defined(ARM32) +# define AVS_WINDOWS_ARM +# endif +#endif + +#if defined(MSVC) && !defined(AVS_WINDOWS_X86) +# error Unsupported combination of compiler, operating system, and machine architecture. +#endif + +/* A kinda portable definition of the C99 restrict keyword (or its unofficial C++ equivalent) */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* Available in C99 */ +#define AVS_RESTRICT restrict +#elif defined(__cplusplus) || defined(_MSC_VER) /* Almost all relevant C++ compilers support it so just assume it works */ +#define AVS_RESTRICT __restrict +#else /* Not supported */ +#define AVS_RESTRICT +#endif + // useful warnings disabler macros for supported compilers #if defined(_MSC_VER) @@ -139,17 +171,24 @@ #endif -#if defined(AVS_POSIX) -#define NEW_AVSVALUE -#else -#define NEW_AVSVALUE -#endif - -#if defined(AVS_WINDOWS) +#if defined(AVS_WINDOWS) && defined(_USING_V110_SDK71_) // Windows XP does not have proper initialization for // thread local variables. // Use workaround instead __declspec(thread) #define XP_TLS #endif +#ifndef MSVC +// GCC and Clang can be used on big endian systems, MSVC can't. +# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define AVS_ENDIANNESS "little" +# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# define AVS_ENDIANNESS "big" +# else +# define AVS_ENDIANNESS "middle" +# endif +#else +#define AVS_ENDIANNESS "little" +#endif + #endif //AVS_CONFIG_H diff --git a/src/render.c b/src/render.c index 1e661a5..d6583b6 100644 --- a/src/render.c +++ b/src/render.c @@ -17,7 +17,7 @@ static void BuildMatrix(ConversionMatrix* matrix, double Kr, double Kb, int shif const int cmax = full_scale ? max_pixel_value : (240 << (bits_per_pixel - 8)); Suv = (cmax - cmin) / 2; - const double mulfac = (double)(1ULL << shift); // integer aritmetic precision scale + const double mulfac = (double)(1ULL << shift); // integer arithmetic precision scale const double Kg = 1. - Kr - Kb; @@ -920,7 +920,7 @@ AVS_VideoFrame* AVSC_CC assrender_get_frame(AVS_FilterInfo* p, int n) data[0] = avs_get_write_ptr_p(src, AVS_PLANAR_R); data[1] = avs_get_write_ptr_p(src, AVS_PLANAR_G); data[2] = avs_get_write_ptr_p(src, AVS_PLANAR_B); - pitch[0] = avs_get_pitch(src); + pitch[0] = avs_get_pitch_p(src, AVS_DEFAULT_PLANE); } else { data[0] = avs_get_write_ptr_p(src, AVS_PLANAR_Y); @@ -931,8 +931,8 @@ AVS_VideoFrame* AVSC_CC assrender_get_frame(AVS_FilterInfo* p, int n) } } else { - data[0] = avs_get_write_ptr(src); - pitch[0] = avs_get_pitch(src); + data[0] = avs_get_write_ptr_p(src, AVS_DEFAULT_PLANE); + pitch[0] = avs_get_pitch_p(src, AVS_DEFAULT_PLANE); } height = p->vi.height; diff --git a/src/sub.c b/src/sub.c index bbe7a0f..ef8ba4a 100644 --- a/src/sub.c +++ b/src/sub.c @@ -1,12 +1,11 @@ #include "sub.h" -void ass_read_matrix(const char* f, char* csp) { - char buf[BUFSIZ]; - FILE* fh = fopen(f, "r"); - +void ass_read_matrix(FILE* fh, char* csp) { if (!fh) return; + char buf[BUFSIZ]; + while (fgets(buf, BUFSIZ - 1, fh) != NULL) { if (buf[0] == 0 || buf[0] == '\n' || buf[0] == '\r') continue; @@ -24,15 +23,14 @@ void ass_read_matrix(const char* f, char* csp) { fclose(fh); } -ASS_Track* parse_srt(const char* f, udata* ud, const char* srt_font) +ASS_Track* parse_srt(FILE* fh, udata* ud, const char* srt_font) { + if (!fh) + return NULL; + char l[BUFSIZ], buf[BUFSIZ]; int start[4], end[4], isn; ASS_Track* ass = ass_new_track(ud->ass_library); - FILE* fh = fopen(f, "r"); - - if (!fh) - return NULL; sprintf(buf, "[V4+ Styles]\nStyle: Default,%s,20,&H1EFFFFFF,&H00FFFFFF," "&H29000000,&H3C000000,0,0,0,0,100,100,0,0,1,1,1.2,2,10,10," @@ -89,9 +87,9 @@ void msg_callback(int level, const char* fmt, va_list va, void* data) fprintf(stderr, "\n"); } -int init_ass(int w, int h, double scale, double line_spacing, - ASS_Hinting hinting, double dar, double sar, int top, - int bottom, int left, int right, int verbosity, +int init_ass(int w, int h, double scale, double line_spacing, ASS_Hinting hinting, + int frame_width, int frame_height, double dar, double sar, bool set_default_storage_size, + int top, int bottom, int left, int right, int verbosity, const char* fontdir, udata* ud) { ASS_Renderer* ass_renderer; @@ -111,16 +109,41 @@ int init_ass(int w, int h, double scale, double line_spacing, ass_set_font_scale(ass_renderer, scale); ass_set_hinting(ass_renderer, hinting); - ass_set_frame_size(ass_renderer, w, h); - ass_set_storage_size(ass_renderer, w, h); ass_set_margins(ass_renderer, top, bottom, left, right); ass_set_use_margins(ass_renderer, 1); if (line_spacing) ass_set_line_spacing(ass_renderer, line_spacing); - if (dar && sar) - ass_set_pixel_aspect(ass_renderer, dar / sar); + if (frame_width > 0 && frame_height > 0) { + ass_set_frame_size(ass_renderer, frame_width, frame_height); + ass_set_storage_size(ass_renderer, w, h); + } + else if (dar > 0.0 || sar > 0.0) { + ass_set_frame_size(ass_renderer, w, h); + + double par = 1.0; + if (dar > 0.0 && sar > 0.0) { + par = dar / sar; + } + else if (dar > 0.0) { + par = dar * (double)h / (double)w; + } + else if (sar > 0.0) { + par = sar; + } + + ass_set_pixel_aspect(ass_renderer, par); + if (set_default_storage_size) { + ass_set_storage_size(ass_renderer, w, h); + } + } + else { + ass_set_frame_size(ass_renderer, w, h); + if (set_default_storage_size) { + ass_set_storage_size(ass_renderer, w, h); + } + } if (strcmp(fontdir, "")) ass_set_fonts_dir(ass_library, fontdir); diff --git a/src/sub.h b/src/sub.h index 490c198..c1b51d8 100644 --- a/src/sub.h +++ b/src/sub.h @@ -1,16 +1,16 @@ #ifndef _SUB_H_ #define _SUB_H_ -#include +// #include #include "assrender.h" -void ass_read_matrix(const char* f, char* csp); +void ass_read_matrix(FILE* fh, char* csp); -ASS_Track* parse_srt(const char* f, udata* ud, const char* srt_font); +ASS_Track* parse_srt(FILE* fh, udata* ud, const char* srt_font); -int init_ass(int w, int h, double scale, double line_spacing, - ASS_Hinting hinting, double dar, double sar, int top, - int bottom, int left, int right, int verbosity, +int init_ass(int w, int h, double scale, double line_spacing, ASS_Hinting hinting, + int frame_width, int frame_height, double dar, double sar, bool set_default_storage_size, + int top, int bottom, int left, int right, int verbosity, const char* fontdir, udata* ud); #endif