diff --git a/.github/workflows/build_releases.yml b/.github/workflows/build_releases.yml index 440e77a6..6da25ea6 100644 --- a/.github/workflows/build_releases.yml +++ b/.github/workflows/build_releases.yml @@ -62,13 +62,11 @@ jobs: run: | curl -s -o hdr10plus_gen_0.00_${{ matrix.platform }}.7z -L https://github.com/rigaya/hdr10plus_gen/releases/download/0.00/hdr10plus_gen_0.00_${{ matrix.platform }}.7z 7z x -ohdr10plus_gen\ hdr10plus_gen_0.00_${{ matrix.platform }}.7z - curl -s -o ffmpeg_lgpl.zip -L https://github.com/rigaya/ffmpeg5_dlls_for_hwenc/archive/refs/tags/20230204.zip - 7z x -y ffmpeg_lgpl.zip - move ffmpeg5* ffmpeg_lgpl + curl -s -o ffmpeg_lgpl.7z -L https://github.com/rigaya/ffmpeg_dlls_for_hwenc/releases/download/20231123/ffmpeg_dlls_for_hwenc_20231123.7z + 7z x -offmpeg_lgpl -y ffmpeg_lgpl.7z git clone https://github.com/AviSynth/AviSynthPlus.git ..\AviSynthPlus git clone https://github.com/vapoursynth/vapoursynth.git ..\vapoursynth git clone https://github.com/KhronosGroup/OpenCL-Headers.git ..\openclheaders - git clone https://github.com/maki-rxrz/Caption2Ass_PCR.git ..\caption2ass - name: Add msbuild to PATH uses: microsoft/setup-msbuild@v1.1 @@ -80,7 +78,6 @@ jobs: set AVISYNTH_SDK=${{ github.workspace }}\..\AviSynthPlus\avs_core set VAPOURSYNTH_SDK=${{ github.workspace }}\..\vapoursynth set OPENCL_HEADERS=${{ github.workspace }}\..\openclheaders - set CAPTION2ASS_SRC=${{ github.workspace }}\..\caption2ass\src msbuild VCEEnc.sln /t:build /p:configuration=RelStatic /p:Platform=${{ matrix.platform }} -maxcpucount - name: Create Archieve @@ -144,7 +141,6 @@ jobs: git clone https://github.com/AviSynth/AviSynthPlus.git ..\AviSynthPlus git clone https://github.com/vapoursynth/vapoursynth.git ..\vapoursynth git clone https://github.com/KhronosGroup/OpenCL-Headers.git ..\openclheaders - git clone https://github.com/maki-rxrz/Caption2Ass_PCR.git ..\caption2ass - name: Add msbuild to PATH uses: microsoft/setup-msbuild@v1.1 @@ -156,7 +152,6 @@ jobs: set AVISYNTH_SDK=${{ github.workspace }}\..\AviSynthPlus\avs_core set VAPOURSYNTH_SDK=${{ github.workspace }}\..\vapoursynth set OPENCL_HEADERS=${{ github.workspace }}\..\openclheaders - set CAPTION2ASS_SRC=${{ github.workspace }}\..\caption2ass\src msbuild VCEEnc.sln /t:build /p:configuration=Release /p:Platform=Win32 -maxcpucount - name: Download auo_setup diff --git a/Build.en.md b/Build.en.md index a1d5febf..165a2cf1 100644 --- a/Build.en.md +++ b/Build.en.md @@ -35,20 +35,14 @@ git clone https://github.com/KhronosGroup/OpenCL-Headers.git setx OPENCL_HEADERS ``` -You will also need source code of [Caption2Ass_PCR](https://github.com/maki-rxrz/Caption2Ass_PCR). - -```Batchfile -git clone https://github.com/maki-rxrz/Caption2Ass_PCR -setx CAPTION2ASS_SRC /src -``` - ### 1. Download source code ```Batchfile git clone https://github.com/rigaya/VCEEnc --recursive cd VCEEnc -git clone https://github.com/rigaya/ffmpeg5_dlls_for_hwenc.git ffmpeg_lgpl +curl -s -o ffmpeg_lgpl.7z -L https://github.com/rigaya/ffmpeg_dlls_for_hwenc/releases/download/20231123/ffmpeg_dlls_for_hwenc_20231123.7z +7z x -offmpeg_lgpl -y ffmpeg_lgpl.7z ``` ### 2. Build VCEEncC.exe / VCEEnc.auo diff --git a/Build.ja.md b/Build.ja.md index 156583cb..375c2b9b 100644 --- a/Build.ja.md +++ b/Build.ja.md @@ -36,19 +36,13 @@ git clone https://github.com/KhronosGroup/OpenCL-Headers.git setx OPENCL_HEADERS ``` -さらにビルドに必要な[Caption2Ass_PCR](https://github.com/maki-rxrz/Caption2Ass_PCR)をcloneし、環境変数 "CAPTION2ASS_SRC" を設定します。 - -```Batchfile -git clone https://github.com/maki-rxrz/Caption2Ass_PCR -setx CAPTION2ASS_SRC /src -``` - ### 1. ソースのダウンロード ```Batchfile git clone https://github.com/rigaya/VCEEnc --recursive cd VCEEnc -git clone https://github.com/rigaya/ffmpeg5_dlls_for_hwenc.git ffmpeg_lgpl +curl -s -o ffmpeg_lgpl.7z -L https://github.com/rigaya/ffmpeg_dlls_for_hwenc/releases/download/20231123/ffmpeg_dlls_for_hwenc_20231123.7z +7z x -offmpeg_lgpl -y ffmpeg_lgpl.7z ``` ### 2. VCEEnc.auo / VCEEncC のビルド diff --git a/VCECore/VCECore.vcxproj b/VCECore/VCECore.vcxproj index 5bc5d782..f7d1d5d9 100644 --- a/VCECore/VCECore.vcxproj +++ b/VCECore/VCECore.vcxproj @@ -176,12 +176,6 @@ true true - - true - true - true - true - @@ -561,7 +555,6 @@ - @@ -797,7 +790,7 @@ Disabled - ..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;..\ffmpeg_lgpl\include;..\ChapterRW;..\dtl;..\cppcodec;..\tinyxml2;..\clRNG\src\include;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(CAPTION2ASS_SRC)\common;$(OPENCL_HEADERS);%(AdditionalIncludeDirectories) + ..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;..\ffmpeg_lgpl\include;..\ChapterRW;..\dtl;..\cppcodec;..\tinyxml2;..\clRNG\src\include;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(OPENCL_HEADERS);%(AdditionalIncludeDirectories) WIN32;_CRT_SECURE_NO_WARNINGS;VCE_AUO;_DEBUG;_LIB;%(PreprocessorDefinitions) false EnableFastChecks @@ -826,7 +819,7 @@ if exist rgy_rev.h.%PID%.tmp del rgy_rev.h.%PID%.tmp > nul 2>&1 Disabled - ..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;..\ffmpeg_lgpl\include;..\ChapterRW;..\dtl;..\cppcodec;..\tinyxml2;..\clRNG\src\include;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(CAPTION2ASS_SRC)\common;$(OPENCL_HEADERS);%(AdditionalIncludeDirectories) + ..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;..\ffmpeg_lgpl\include;..\ChapterRW;..\dtl;..\cppcodec;..\tinyxml2;..\clRNG\src\include;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(OPENCL_HEADERS);%(AdditionalIncludeDirectories) WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_LIB;%(PreprocessorDefinitions) false EnableFastChecks @@ -856,7 +849,7 @@ if exist rgy_rev.h.%PID%.tmp del rgy_rev.h.%PID%.tmp > nul 2>&1 Disabled - ..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;..\ffmpeg_lgpl\include;..\ChapterRW;..\dtl;..\cppcodec;..\tinyxml2;..\clRNG\src\include;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(CAPTION2ASS_SRC)\common;$(OPENCL_HEADERS);%(AdditionalIncludeDirectories) + ..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;..\ffmpeg_lgpl\include;..\ChapterRW;..\dtl;..\cppcodec;..\tinyxml2;..\clRNG\src\include;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(OPENCL_HEADERS);%(AdditionalIncludeDirectories) WIN32;_CRT_SECURE_NO_WARNINGS;VCE_AUO;_DEBUG;_LIB;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebugDLL @@ -885,7 +878,7 @@ if exist rgy_rev.h.%PID%.tmp del rgy_rev.h.%PID%.tmp > nul 2>&1 Disabled - ..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;..\ffmpeg_lgpl\include;..\ChapterRW;..\dtl;..\cppcodec;..\tinyxml2;..\clRNG\src\include;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(CAPTION2ASS_SRC)\common;$(OPENCL_HEADERS);%(AdditionalIncludeDirectories) + ..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;..\ffmpeg_lgpl\include;..\ChapterRW;..\dtl;..\cppcodec;..\tinyxml2;..\clRNG\src\include;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(OPENCL_HEADERS);%(AdditionalIncludeDirectories) WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_LIB;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebug @@ -920,7 +913,7 @@ if exist rgy_rev.h.%PID%.tmp del rgy_rev.h.%PID%.tmp > nul 2>&1Size true true - ..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;..\ffmpeg_lgpl\include;..\ChapterRW;..\dtl;..\cppcodec;..\tinyxml2;..\clRNG\src\include;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(CAPTION2ASS_SRC)\common;$(OPENCL_HEADERS);%(AdditionalIncludeDirectories) + ..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;..\ffmpeg_lgpl\include;..\ChapterRW;..\dtl;..\cppcodec;..\tinyxml2;..\clRNG\src\include;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(OPENCL_HEADERS);%(AdditionalIncludeDirectories) WIN32;_CRT_SECURE_NO_WARNINGS;VCE_AUO;NDEBUG;_LIB;%(PreprocessorDefinitions) true MultiThreadedDLL @@ -956,7 +949,7 @@ if exist rgy_rev.h.%PID%.tmp del rgy_rev.h.%PID%.tmp > nul 2>&1Size true true - ..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;..\ffmpeg_lgpl\include;..\ChapterRW;..\dtl;..\cppcodec;..\tinyxml2;..\clRNG\src\include;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(CAPTION2ASS_SRC)\common;$(OPENCL_HEADERS);%(AdditionalIncludeDirectories) + ..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;..\ffmpeg_lgpl\include;..\ChapterRW;..\dtl;..\cppcodec;..\tinyxml2;..\clRNG\src\include;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(OPENCL_HEADERS);%(AdditionalIncludeDirectories) WIN32;_CRT_SECURE_NO_WARNINGS;VCE_AUO;NDEBUG;_LIB;%(PreprocessorDefinitions) true MultiThreadedDLL @@ -993,7 +986,7 @@ if exist rgy_rev.h.%PID%.tmp del rgy_rev.h.%PID%.tmp > nul 2>&1Size true true - ..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;..\ffmpeg_lgpl\include;..\ChapterRW;..\dtl;..\cppcodec;..\tinyxml2;..\clRNG\src\include;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(CAPTION2ASS_SRC)\common;$(OPENCL_HEADERS);%(AdditionalIncludeDirectories) + ..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;..\ffmpeg_lgpl\include;..\ChapterRW;..\dtl;..\cppcodec;..\tinyxml2;..\clRNG\src\include;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(OPENCL_HEADERS);%(AdditionalIncludeDirectories) WIN32;_CRT_SECURE_NO_WARNINGS;NDEBUG;_LIB;%(PreprocessorDefinitions) true MultiThreaded @@ -1030,7 +1023,7 @@ if exist rgy_rev.h.%PID%.tmp del rgy_rev.h.%PID%.tmp > nul 2>&1Size true true - ..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;..\ffmpeg_lgpl\include;..\ChapterRW;..\dtl;..\cppcodec;..\tinyxml2;..\clRNG\src\include;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(CAPTION2ASS_SRC)\common;$(OPENCL_HEADERS);%(AdditionalIncludeDirectories) + ..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;..\ffmpeg_lgpl\include;..\ChapterRW;..\dtl;..\cppcodec;..\tinyxml2;..\clRNG\src\include;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(OPENCL_HEADERS);%(AdditionalIncludeDirectories) WIN32;_CRT_SECURE_NO_WARNINGS;NDEBUG;_LIB;%(PreprocessorDefinitions) true MultiThreaded diff --git a/VCECore/VCECore.vcxproj.filters b/VCECore/VCECore.vcxproj.filters index bbf227fb..04c7e217 100644 --- a/VCECore/VCECore.vcxproj.filters +++ b/VCECore/VCECore.vcxproj.filters @@ -123,9 +123,6 @@ ソース ファイル - - ソース ファイル - ソース ファイル @@ -440,9 +437,6 @@ ヘッダー ファイル - - ヘッダー ファイル - ヘッダー ファイル diff --git a/VCECore/rgy_caption.cpp b/VCECore/rgy_caption.cpp deleted file mode 100644 index c05b70da..00000000 --- a/VCECore/rgy_caption.cpp +++ /dev/null @@ -1,1401 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// NVEnc by rigaya -// ----------------------------------------------------------------------------------------- -// The MIT License -// -// Copyright (c) 2014-2016 rigaya -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -// -------------------------------------------------------------------------------------------- - -#include -#include -#include "rgy_osdep.h" -#include "rgy_caption.h" -#include "rgy_filesystem.h" - -#if ENABLE_AVSW_READER && (defined(_WIN32) || defined(_WIN64)) - -#include "packet_types.h" - -#define TIMESTAMP_INVALID_VALUE (-1LL) -#define WRAP_AROUND_VALUE (1LL << 33) -#define WRAP_AROUND_CHECK_VALUE ((1LL << 32) - 1) -#define PCR_MAXIMUM_INTERVAL (100 * 90) - -static const TCHAR *DEFAULT_FONT_NAME = _T("MS UI Gothic"); -static const TCHAR *DEFAULT_STYLE = _T("&H00FFFFFF,&H000000FF,&H00000000,&H00000000,0,0,0,0,100,100,15,0,1,2,2,1,10,10,10,0"); -static const TCHAR *DEFAULT_BOX_STYLE = _T("&HFFFFFFFF,&H000000FF,&H00FFFFFF,&H00FFFFFF,0,0,0,0,100,100,0,0,1,2,2,2,10,10,10,0"); -static const TCHAR *DEFAULT_RUBI_STYLE = _T("&H00FFFFFF,&H000000FF,&H00000000,&H00000000,0,0,0,0,100,100,0,0,1,2,2,1,10,10,10,0"); - -ass_setting_t::ass_setting_t() : - SWF0offset(0), - SWF5offset(0), - SWF7offset(0), - SWF9offset(0), - SWF11offset(0), - Comment1(""), - Comment2(""), - Comment3(""), - PlayResX(1920), - PlayResY(1080), - DefaultFontname(tchar_to_string(DEFAULT_FONT_NAME)), - DefaultFontsize(90), - DefaultStyle(tchar_to_string(DEFAULT_STYLE)), - BoxFontname(tchar_to_string(DEFAULT_FONT_NAME)), - BoxFontsize(90), - BoxStyle(tchar_to_string(DEFAULT_BOX_STYLE)), - RubiFontname(tchar_to_string(DEFAULT_FONT_NAME)), - RubiFontsize(50), - RubiStyle(tchar_to_string(DEFAULT_RUBI_STYLE)) { - -} -void ass_setting_t::set(const tstring& inifile, int width, int height) { -#if defined(_WIN32) || defined(_WIN64) - SWF0offset = GetPrivateProfileInt(_T("SWFModeOffset"), _T("SWF0offset"), 0, inifile.c_str()); - SWF5offset = GetPrivateProfileInt(_T("SWFModeOffset"), _T("SWF5offset"), 0, inifile.c_str()); - SWF7offset = GetPrivateProfileInt(_T("SWFModeOffset"), _T("SWF7offset"), 0, inifile.c_str()); - SWF9offset = GetPrivateProfileInt(_T("SWFModeOffset"), _T("SWF9offset"), 0, inifile.c_str()); - SWF11offset = GetPrivateProfileInt(_T("SWFModeOffset"), _T("SWF11offset"), 0, inifile.c_str()); - - static const TCHAR *KEY = (double)width / (double)height > 1.5 ? _T("Default") : _T("Default43"); - TCHAR buffer[1024]; - GetPrivateProfileString(KEY, _T("Comment1"), _T(""), buffer, _countof(buffer), inifile.c_str()); Comment1 = tchar_to_string(buffer, CP_UTF8); - GetPrivateProfileString(KEY, _T("Comment2"), _T(""), buffer, _countof(buffer), inifile.c_str()); Comment2 = tchar_to_string(buffer, CP_UTF8); - GetPrivateProfileString(KEY, _T("Comment3"), _T(""), buffer, _countof(buffer), inifile.c_str()); Comment3 = tchar_to_string(buffer, CP_UTF8); - PlayResX = GetPrivateProfileInt(KEY, _T("PlayResX"), 0, inifile.c_str()); - PlayResY = GetPrivateProfileInt(KEY, _T("PlayResY"), 0, inifile.c_str()); - - GetPrivateProfileString(KEY, _T("DefaultFontname"), DEFAULT_FONT_NAME, buffer, _countof(buffer), inifile.c_str()); DefaultFontname = tchar_to_string(buffer, CP_UTF8); - DefaultFontsize = GetPrivateProfileInt(KEY, _T("DefaultFontsize"), 0, inifile.c_str()); - GetPrivateProfileString(KEY, _T("DefaultStyle"), DEFAULT_STYLE, buffer, _countof(buffer), inifile.c_str()); DefaultStyle = tchar_to_string(buffer, CP_UTF8); - - GetPrivateProfileString(KEY, _T("BoxFontname"), DEFAULT_FONT_NAME, buffer, _countof(buffer), inifile.c_str()); BoxFontname = tchar_to_string(buffer, CP_UTF8); - BoxFontsize = GetPrivateProfileInt(KEY, _T("BoxFontsize"), 0, inifile.c_str()); - GetPrivateProfileString(KEY, _T("BoxStyle"), DEFAULT_BOX_STYLE, buffer, _countof(buffer), inifile.c_str()); BoxStyle = tchar_to_string(buffer, CP_UTF8); - - GetPrivateProfileString(KEY, _T("RubiFontname"), DEFAULT_FONT_NAME, buffer, _countof(buffer), inifile.c_str()); RubiFontname = tchar_to_string(buffer, CP_UTF8); - RubiFontsize = GetPrivateProfileInt(KEY, _T("RubiFontsize"), 0, inifile.c_str()); - GetPrivateProfileString(KEY, _T("RubiStyle"), DEFAULT_RUBI_STYLE, buffer, _countof(buffer), inifile.c_str()); RubiStyle = tchar_to_string(buffer, CP_UTF8); -#endif //#if defined(_WIN32) || defined(_WIN64) -} - -static const unsigned char utf8_bom[3] = { 0xEF, 0xBB, 0xBF }; - -static const char HiraTable[][3] = { - "ぁ", "あ", "ぃ", "い", "ぅ", "う", "ぇ", - "え", "ぉ", "お", "か", "が", "き", "ぎ", "く", - "ぐ", "け", "げ", "こ", "ご", "さ", "ざ", "し", - "じ", "す", "ず", "せ", "ぜ", "そ", "ぞ", "た", - "だ", "ち", "ぢ", "っ", "つ", "づ", "て", "で", - "と", "ど", "な", "に", "ぬ", "ね", "の", "は", - "ば", "ぱ", "ひ", "び", "ぴ", "ふ", "ぶ", "ぷ", - "へ", "べ", "ぺ", "ほ", "ぼ", "ぽ", "ま", "み", - "む", "め", "も", "ゃ", "や", "ゅ", "ゆ", "ょ", - "よ", "ら", "り", "る", "れ", "ろ", "ゎ", "わ", - "ゐ", "ゑ", "を", "ん", " ", " ", " ", "ゝ", - "ゞ", "ー", "。", "「", "」", "、", "・", - "!", "”", "#", "$", "%", "&", "’", - "(", ")", "*", "+", ",", "-", ".", "/", - "0", "1", "2", "3", "4", "5", "6", "7", - "8", "9", ":", ";", "<", "=", ">", "?", - "@", "A", "B", "C", "D", "E", "F", "G", - "H", "I", "J", "K", "L", "M", "N", "O", - "P", "Q", "R", "S", "T", "U", "V", "W", - "X", "Y", "Z", "[", "¥", "]", "^", "_", - "‘", "a", "b", "c", "d", "e", "f", "g", - "h", "i", "j", "k", "l", "m", "n", "o", - "p", "q", "r", "s", "t", "u", "v", "w", - "x", "y", "z", "{", "|", "}", " ̄" -}; - -static const char HalfHiraTable[][3] = { - "ぁ", "あ", "ぃ", "い", "ぅ", "う", "ぇ", - "え", "ぉ", "お", "か", "が", "き", "ぎ", "く", - "ぐ", "け", "げ", "こ", "ご", "さ", "ざ", "し", - "じ", "す", "ず", "せ", "ぜ", "そ", "ぞ", "た", - "だ", "ち", "ぢ", "っ", "つ", "づ", "て", "で", - "と", "ど", "な", "に", "ぬ", "ね", "の", "は", - "ば", "ぱ", "ひ", "び", "ぴ", "ふ", "ぶ", "ぷ", - "へ", "べ", "ぺ", "ほ", "ぼ", "ぽ", "ま", "み", - "む", "め", "も", "ゃ", "や", "ゅ", "ゆ", "ょ", - "よ", "ら", "り", "る", "れ", "ろ", "ゎ", "わ", - "ゐ", "ゑ", "を", "ん", " ", " ", " ", "ゝ", - "ゞ", "ー", "。", "「", "」", "、", "・", - "!", "\"", "#", "$", "%", "&", "'", - "(", ")", "*", "+", ", ", "-", ".", "/", - "0", "1", "2", "3", "4", "5", "6", "7", - "8", "9", ":", ";", "<", "=", ">", "?", - "@", "A", "B", "C", "D", "E", "F", "G", - "H", "I", "J", "K", "L", "M", "N", "O", - "P", "Q", "R", "S", "T", "U", "V", "W", - "X", "Y", "Z", "[", "¥", "]", "^", "_", - "`", "a", "b", "c", "d", "e", "f", "g", - "h", "i", "j", "k", "l", "m", "n", "o", - "p", "q", "r", "s", "t", "u", "v", "w", - "x", "y", "z", "{", "|", "}", " ̄" -}; - -static const char KanaTable[][3] = { - "ァ", "ア", "ィ", "イ", "ゥ", "ウ", "ェ", - "エ", "ォ", "オ", "カ", "ガ", "キ", "ギ", "ク", - "グ", "ケ", "ゲ", "コ", "ゴ", "サ", "ザ", "シ", - "ジ", "ス", "ズ", "セ", "ゼ", "ソ", "ゾ", "タ", - "ダ", "チ", "ヂ", "ッ", "ツ", "ヅ", "テ", "デ", - "ト", "ド", "ナ", "ニ", "ヌ", "ネ", "ノ", "ハ", - "バ", "パ", "ヒ", "ビ", "ピ", "フ", "ブ", "プ", - "ヘ", "ベ", "ペ", "ホ", "ボ", "ポ", "マ", "ミ", - "ム", "メ", "モ", "ャ", "ヤ", "ュ", "ユ", "ョ", - "ヨ", "ラ", "リ", "ル", "レ", "ロ", "ヮ", "ワ", - "ヰ", "ヱ", "ヲ", "ン", "ヴ", "ヵ", "ヶ", "ヽ", - "ヾ", "ー", "。", "「", "」", "、", "・" -}; - -static const char HalfKanaTable[][3] = { - "ァ", "ア", "ィ", "イ", "ゥ", "ウ", "ェ", - "エ", "ォ", "オ", "カ", "ガ", "キ", "ギ", "ク", - "グ", "ケ", "ゲ", "コ", "ゴ", "サ", "ザ", "シ", - "ジ", "ス", "ズ", "セ", "ゼ", "ソ", "ゾ", "タ", - "ダ", "チ", "ヂ", "ッ", "ツ", "ヅ", "テ", "デ", - "ト", "ド", "ナ", "ニ", "ヌ", "ネ", "ノ", "ハ", - "バ", "パ", "ヒ", "ビ", "ピ", "フ", "ブ", "プ", - "ヘ", "ベ", "ペ", "ホ", "ボ", "ポ", "マ", "ミ", - "ム", "メ", "モ", "ャ", "ヤ", "ュ", "ユ", "ョ", - "ヨ", "ラ", "リ", "ル", "レ", "ロ", "ヮ", "ワ", - "ヰ", "ヱ", "ヲ", "ン", "ヴ", "ヵ", "ヶ", "ヽ", - "ヾ", "ー", "。", "「", "」", "、", "・" -}; - -std::string GetHalfChar(std::string key) { - CHAR ret[STRING_BUFFER_SIZE] = { 0 }; - BOOL bMatch = FALSE; - - // マッチしない文字は、そのまま使用 - const char *_p = key.c_str(); - char *p = (char *)key.c_str(); - - while (p < _p + key.size()) { - for (int i = 0; i < sizeof(HiraTable) / sizeof(HiraTable[0]) && p < _p + key.size(); i++) { - bMatch = FALSE; - if (memcmp(p, HiraTable[i], 2) == 0) { - strcat_s( ret, STRING_BUFFER_SIZE, HalfHiraTable[i] ); - p += 2; - bMatch = TRUE; - i = -1; - } - } - - for (int i = 0; i < sizeof(KanaTable) / sizeof(KanaTable[0]) && p < _p + key.size(); i++) { - bMatch = FALSE; - if (memcmp(p, KanaTable[i], 2) == 0) { - strcat_s(ret, STRING_BUFFER_SIZE, HalfKanaTable[i]); - p += 2; - bMatch = TRUE; - i = -1; - } - } - - if (p < _p + key.size()) { - strncat_s(ret, STRING_BUFFER_SIZE, p, 2); - p += 2; - } - } - - return ret; -} - - -struct HALFCHAR_INFO { - int char_nums; - int point_nums; - int half_nums; -}; - -static int count_utf8_length(const unsigned char *string, HALFCHAR_INFO *hc) { - int len = 0; - int point_count = 0; - int half_count = 0; - - while (*string) { - if (string[0] == 0x00) - break; - - if (string[0] < 0x1f || string[0] == 0x7f) - // 制御コード - ; - else if (string[0] <= 0x7f) { - // 1バイト文字 - ++len; // 半角 - ++half_count; - } else if (string[0] <= 0xbf) - // 文字の続き - ; - else if (string[0] <= 0xdf) { - // 2バイト文字 - len += 2; - if (string[0] == 0xc2 && string[1] == 0xa5) { - --len; // 半角の¥ - ++half_count; - } - } else if (string[0] <= 0xef) { - // 3バイト文字 - len += 2; - if (string[0] == 0xe2 && string[1] == 0x80 && string[2] == 0xbe) { - --len; // 半角の ̄ - ++half_count; - } else if (string[0] == 0xef) { - if (string[1] == 0xbd) { - if (string[2] >= 0xa1 && string[2] <= 0xbf) { - --len; // 半角カナ 「。」~「ソ」 - ++half_count; - } - } else if (string[1] == 0xbe) { - if (string[2] >= 0x80 && string[2] <= 0x9f) { - --len; // 半角カナ 「タ」~「゜」 - ++half_count; - } - if (string[2] == 0x9e || string[2] == 0x9f) { - ++point_count; // 濁点・半濁点をカウント - --half_count; - } - } - } - } else if (string[0] <= 0xf7) - // 4バイト文字 - len += 2; - else if (string[0] <= 0xfb) - // 5バイト文字 - len += 2; - else if (string[0] <= 0xfd) - // 6バイト文字 - len += 2; - else - // 使われていない範囲 - ; - - ++string; - } - - if (hc) { - hc->char_nums = len; - hc->point_nums = point_count; - hc->half_nums = half_count; - } - return len; -} - -static int FindStartOffset(rgy_stream& st) { - const char *const start_ptr = (char *)st.data(); - const char * fin_ptr = start_ptr + st.size(); - for (const char *ptr = start_ptr; ptr < fin_ptr; ptr++) { - if (ptr[0] == 'G' && ptr[188] == 'G') { - st.add_offset(ptr - start_ptr); - return 0; - } - } - return 1; -} - -static int resync(void *pbPacket, rgy_stream& st) { - char *ptr = (char *)memchr(pbPacket, 'G', 188); - if (!ptr) { - for (int i = 0; i < 20; i++) { - if (st.size() < 188) { - return 1; - } - memcpy(pbPacket, st.data(), 188); - st.add_offset(188); - ptr = (char *)memchr(pbPacket, 'G', 188); - if (ptr != nullptr) { - break; - } - } - } - if (!ptr) { - return 1; - } - auto pos = ptr - (char *)pbPacket; - st.add_offset(-(188 - pos)); - return 0; -} - -static int64_t GetPTS(uint8_t *pbPacket) { - int64_t PTS = TIMESTAMP_INVALID_VALUE; - // Get PTS in PES Header(00 00 01 BD) - for (int i = 4; i < 188 - 10; i++) { - if ( pbPacket[i + 0] == 0x00 - && pbPacket[i + 1] == 0x00 - && pbPacket[i + 2] == 0x01 - && pbPacket[i + 3] == 0xBD) { - - uint8_t *pData = &pbPacket[i + 9]; - - PTS = (int64_t)(((uint32_t)(*pData) & 0xE) >> 1) << 30; - pData++; - - PTS += (uint32_t)(*pData) << 22; - pData++; - - PTS += (uint32_t)((uint32_t)(*pData) >> 1) << 15; - pData++; - - PTS += (uint32_t)(*pData) << 7; - pData++; - - PTS += (uint32_t)(*pData) >> 1; - - //PTS = PTS / 90; - - break; - } - } - return PTS; -} - -static void parse_PAT(uint8_t *pbPacket, USHORT *PMTPid) { - PAT_HEADER *pat = (PAT_HEADER *)(pbPacket + sizeof(_Packet_Header) + 1); - - for (int i = 0; i < (188 - 13) / 4; i++) { - uint16_t wProgramID = swap16(pat->PMT_Array[i].program_id); - uint16_t wPID = swap16(pat->PMT_Array[i].PID) & 0x1FFF; - if (wProgramID == 0xFFFF) - break; - - if (wProgramID != 0 && *PMTPid == 0) //the first PMTPid found - *PMTPid = wPID; - } -} - -static void parse_PMT(uint8_t *pbPacket, USHORT *PCRPid, USHORT *CaptionPid) { - PMT_HEADER *pmt = (PMT_HEADER *)(pbPacket + sizeof(_Packet_Header) + 1); - - if (*PCRPid == 0) - *PCRPid = swap16(pmt->pcrpid) & 0x1FFF; - - int length = swap16(pmt->program_info_length) & 0x0FFF; - uint8_t *pData = (uint8_t *)&pmt->program_info_length + 2; - pData += length; //read thrugh program_info - - while (pData < pbPacket + 184) { - PMT_PID_Desc *pmt_pid = (PMT_PID_Desc *)&pData[0]; - - if (pmt_pid->StreamTypeID == 0x6) { - bool bcomponent_tag = false; - int iDescLen = swap16(pmt_pid->DescLen) & 0x0FFF; - for (int i = 0; i < iDescLen -2; i++) { - if (pData[i + 5] == 0x52 && pData[i + 6] == 0x01 && pData[i + 7] == 0x30) { - bcomponent_tag = true; - break; - } - } - if (bcomponent_tag) { - *CaptionPid = (swap16(pmt_pid->EsPID) & 0x1FFF); - break; - } - } - pData += ((swap16(pmt_pid->DescLen) & 0x0FFF) + 5); - } -} - -static void parse_Packet_Header(Packet_Header *packet_header, uint8_t *pbPacket) { - _Packet_Header *packet = (_Packet_Header *)pbPacket; - - packet_header->Sync = packet->Sync; - packet_header->TsErr = (swap16(packet->PID) >> 15) & 0x01; - packet_header->PayloadStartFlag = (swap16(packet->PID) >> 14) & 0x01; - packet_header->Priority = (swap16(packet->PID) >> 13) & 0x01; - packet_header->PID = (swap16(packet->PID) & 0x1FFF); - packet_header->Scramble = (packet->Counter & 0xC0) >> 6; - packet_header->AdaptFlag = (packet->Counter & 0x20) >> 5; - packet_header->PayloadFlag = (packet->Counter & 0x10) >> 4; - packet_header->Counter = (packet->Counter & 0x0F); -} - -CaptionDLL::CaptionDLL() : - m_hModule(), - pfInitializeCP(nullptr), - pfInitializeUNICODECP(nullptr), - pfUnInitializeCP(nullptr), - pfAddTSPacketCP(nullptr), - pfClearCP(nullptr), - pfGetTagInfoCP(nullptr), - pfGetCaptionDataCP(nullptr), - unicode_(false) { - -} -CaptionDLL::~CaptionDLL() { - m_hModule.reset(); -} -RGY_ERR CaptionDLL::load() { - m_hModule = std::unique_ptr(LoadLibrary(_T("Caption.dll")), module_deleter()); - if (!m_hModule) { - return RGY_ERR_INVALID_CALL; - } -#define LOADADDR(x) (pf ## x = (x)GetProcAddress((HMODULE)m_hModule.get(), #x)) - - if ( LOADADDR(InitializeCP) == NULL - || LOADADDR(UnInitializeCP) == NULL - || LOADADDR(AddTSPacketCP) == NULL - || LOADADDR(ClearCP) == NULL - || LOADADDR(GetTagInfoCP) == NULL - || LOADADDR(GetCaptionDataCP) == NULL) { - return RGY_ERR_INVALID_CALL; - } - -#undef LOADADDR - return RGY_ERR_NONE; -} - -RGY_ERR CaptionDLL::init() { - pfInitializeUNICODECP = (InitializeUNICODECP)(GetProcAddress((HMODULE)m_hModule.get(), "InitializeUNICODE")); - if (pfInitializeUNICODECP) { - unicode_ = true; - return (pfInitializeUNICODECP() != NO_ERR) ? RGY_ERR_INVALID_CALL : RGY_ERR_NONE; - } else { - unicode_ = false; - return (pfInitializeCP() != NO_ERR) ? RGY_ERR_INVALID_CALL : RGY_ERR_NONE; - } -} - -c2a_ts::c2a_ts() : - startPCR(TIMESTAMP_INVALID_VALUE), - lastPCR(TIMESTAMP_INVALID_VALUE), - lastPTS(TIMESTAMP_INVALID_VALUE), - basePCR(0), - basePTS(0), - correctTS(0) { -} - -PidInfo::PidInfo() : - PMTPid(0), - CaptionPid(0), - PCRPid(0) { -} - -SrtOut::SrtOut() : - ornament(true), - index(0) { -} - -Caption2AssPrm::Caption2AssPrm() : - DelayTime(0), - keepInterval(true), - HLCmode(HLC_kigou), - norubi(false), - LangType(1), - ass_type(), - FileName() { -} - -Caption2Ass::Caption2Ass() : - m_dll(), - m_format(FORMAT_INVALID), - m_streamSync(false), - m_stream(), - m_timestamp(), - m_prm(), - m_pid(), - m_langTagList(), - m_ass(), - m_capList(), - m_pLog(), - m_vidFirstKeyPts(0), - m_sidebarSize(0), - m_srt() { - m_stream.init(); -} -Caption2Ass::~Caption2Ass() { - close(); -} - -void Caption2Ass::close() { - m_pLog.reset(); -} - -RGY_ERR Caption2Ass::init(std::shared_ptr pLog, C2AFormat format) { - m_pLog = pLog; - m_dll.reset(new CaptionDLL()); - auto ret = m_dll->load(); - if (ret != RGY_ERR_NONE) { - m_dll.reset(); - AddMessage(RGY_LOG_ERROR, _T("Failed to load Caption.dll.\n")); - return ret; - } - - ret = m_dll->init(); - if (ret != RGY_ERR_NONE) { - m_dll.reset(); - AddMessage(RGY_LOG_ERROR, _T("Failed to init Caption.dll.\n")); - return ret; - } - m_format = format; - if (m_format != FORMAT_ASS && m_format != FORMAT_SRT) { - AddMessage(RGY_LOG_ERROR, _T("Invalid format specified.\n")); - return RGY_ERR_INVALID_DATA_TYPE; - } - return RGY_ERR_NONE; -} - -std::vector Caption2Ass::getCaptionDataList(uint8_t ucLangTag) { - std::vector captionList; - CAPTION_DATA_DLL *pListDll = nullptr; - DWORD count = 0; - int ret = m_dll->f_GetCaptionDataCP()(ucLangTag, &pListDll, &count); - if (ret == TRUE) { - captionList.reserve(count); - for (DWORD i = 0; i < count; i++) { - CAPTION_DATA data; - data.bClear = !!pListDll[i].bClear; - data.wSWFMode = pListDll[i].wSWFMode; - data.wClientX = pListDll[i].wClientX; - data.wClientY = pListDll[i].wClientY; - data.wClientW = pListDll[i].wClientW; - data.wClientH = pListDll[i].wClientH; - data.wPosX = pListDll[i].wPosX; - data.wPosY = pListDll[i].wPosY; - data.dwWaitTime = pListDll[i].dwWaitTime; - - data.charList.reserve(pListDll[i].dwListCount); - for (DWORD j = 0; j < pListDll[i].dwListCount; j++) { - CAPTION_CHAR_DATA charData; - charData.strDecode = pListDll[i].pstCharList[j].pszDecode; - charData.wCharSizeMode = pListDll[i].pstCharList[j].wCharSizeMode; - charData.stCharColor = pListDll[i].pstCharList[j].stCharColor; - charData.stBackColor = pListDll[i].pstCharList[j].stBackColor; - charData.stRasterColor = pListDll[i].pstCharList[j].stRasterColor; - charData.bUnderLine = pListDll[i].pstCharList[j].bUnderLine; - charData.bShadow = pListDll[i].pstCharList[j].bShadow; - charData.bBold = pListDll[i].pstCharList[j].bBold; - charData.bItalic = pListDll[i].pstCharList[j].bItalic; - charData.bFlushMode = pListDll[i].pstCharList[j].bFlushMode; - charData.bHLC = pListDll[i].pstCharList[j].bHLC; - charData.wCharW = pListDll[i].pstCharList[j].wCharW; - charData.wCharH = pListDll[i].pstCharList[j].wCharH; - charData.wCharHInterval = pListDll[i].pstCharList[j].wCharHInterval; - charData.wCharVInterval = pListDll[i].pstCharList[j].wCharVInterval; - data.charList.push_back(charData); - } - captionList.push_back(data); - } - } - return std::move(captionList); -} - -//assのヘッダを返す -std::string Caption2Ass::assHeader() const { - std::stringstream ss; - ss << "[Script Info]" << std::endl; - ss << "; " << m_ass.Comment1 << std::endl; - ss << "; " << m_ass.Comment2 << std::endl; - ss << "; " << m_ass.Comment3 << std::endl; - ss << "Title: Default Aegisub file" << std::endl; - ss << "ScriptType: v4.00+" << std::endl; - ss << "WrapStyle: 0" << std::endl; - ss << "PlayResX: " << m_ass.PlayResX << std::endl; - ss << "PlayResY: " << m_ass.PlayResY << std::endl; - ss << "ScaledBorderAndShadow: yes" << std::endl; - ss << "Video Aspect Ratio: 0" << std::endl; - ss << "Video Zoom: 6" << std::endl; - ss << "Video Position: 0" << std::endl; - ss << std::endl; - ss << "[V4+ Styles]" << std::endl; - ss << "Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding" << std::endl; - ss << "Style: Default," << m_ass.DefaultFontname << "," << m_ass.DefaultFontsize << "," << m_ass.DefaultStyle << std::endl; - ss << "Style: Box," << m_ass.BoxFontname << "," << m_ass.BoxFontsize << "," << m_ass.BoxStyle << std::endl; - ss << "Style: Rubi," << m_ass.RubiFontname << "," << m_ass.RubiFontsize << "," << m_ass.RubiStyle << std::endl; - ss << "//" << std::endl; - return ss.str(); -} - -//内部データをリセット(seekが発生したときなどに使用する想定) -void Caption2Ass::reset() { - m_streamSync = false; - m_stream.clear(); - m_timestamp = c2a_ts(); - m_pid = PidInfo(); - m_langTagList.clear(); - m_capList.clear(); - m_dll->init(); -} - -//入力データがtsかどうかの判定 -bool Caption2Ass::isTS(const uint8_t *data, const size_t data_size) const { - rgy_stream st; - st.append(data, data_size); - return FindStartOffset(st) == 0; -} - -void Caption2Ass::setOutputResolution(int w, int h, int sar_x, int sar_y) { - m_ass.PlayResX = w; - m_ass.PlayResY = h; -#if defined(_WIN32) || defined(_WIN64) - TCHAR buf[1024] = { 0 }; - GetModuleFileName(NULL, buf, _countof(buf)); - auto exeDir = PathRemoveFileSpecFixed(buf); - auto list = get_file_list(_T("Caption2Ass*.ini"), exeDir.second); - if (list.size() > 0) { - AddMessage(RGY_LOG_INFO, _T("load ass settings from \"%s\""), list[0].c_str()); - m_ass.set(list[0], w, h); - } -#endif - if (sar_x > 0 && sar_y > 0) { - if (sar_x > sar_y) { - m_ass.PlayResX = m_ass.PlayResX * sar_x / sar_y; - } else { - m_ass.PlayResY = m_ass.PlayResY * sar_y / sar_x; - } - } - m_sidebarSize = 0; - AddMessage(RGY_LOG_DEBUG, _T("PlayResX: %d, PlayResY: %d, m_sidebarSize: %d.\n"), m_ass.PlayResX, m_ass.PlayResY, m_sidebarSize); -} - -void Caption2Ass::printParam(RGYLogLevel log_level) { - if (!m_pLog || log_level < m_pLog->getLogLevel(RGY_LOGT_CAPION2ASS)) { - return; - } - AddMessage(log_level, _T("caption2ass: %s\n"), get_chr_from_value(list_caption2ass, m_format)); - AddMessage(log_level, _T(" DelayTime: %d\n"), m_prm.DelayTime); - AddMessage(log_level, _T(" keepInterval: %s\n"), m_prm.keepInterval ? _T("yes") : _T("no")); - AddMessage(log_level, _T(" HLCmode: %d\n"), get_chr_from_value(list_caption2ass_hlc, m_prm.HLCmode)); - AddMessage(log_level, _T(" norubi: %s\n"), m_prm.norubi ? _T("yes") : _T("no")); - AddMessage(log_level, _T(" LangType: %d\n"), m_prm.LangType); - AddMessage(log_level, _T(" ass_type: %s\n"), m_prm.ass_type.c_str()); - AddMessage(log_level, _T(" sidebarSize: %d\n"), m_sidebarSize); - AddMessage(log_level, _T(" srt ornament: %s\n"), m_srt.ornament ? _T("yes") : _T("no")); -} - -RGY_ERR Caption2Ass::proc(const uint8_t *data, const size_t data_size, std::vector>& subList) { - m_stream.append(data, data_size); - - if (m_streamSync) { - if (!FindStartOffset(m_stream)) { - return RGY_ERR_UNKNOWN; - } - m_streamSync = true; - } - - bool bPrintPMT = true; - uint8_t pbPacket[188 * 2 + 4] = { 0 }; - uint32_t packetCount = 0; - - while (m_stream.size() >= 188) { - memcpy(pbPacket, m_stream.data(), 188); - m_stream.add_offset(188); - packetCount++; - - Packet_Header packet; - parse_Packet_Header(&packet, &pbPacket[0]); - - if (packet.Sync != 'G') { - if (!resync(pbPacket, m_stream)) { - return RGY_ERR_UNKNOWN; - } - continue; - } - - if (packet.TsErr) - continue; - - // PAT - if (packet.PID == 0 && (m_pid.PMTPid == 0 || bPrintPMT)) { - parse_PAT(&pbPacket[0], &(m_pid.PMTPid)); - bPrintPMT = false; - - continue; // next packet - } - - // PMT - if (m_pid.PMTPid != 0 && packet.PID == m_pid.PMTPid) { - if (pbPacket[5] != 0x02 || (pbPacket[6] & 0xf0) != 0xb0) - /*-------------------------------------------------- - * pbPacket[5] (8) table_id - * pbPacket[6] (1) section_syntax_indicator - * (1) '0' - * (2) reserved '11' - *------------------------------------------------*/ - continue; // next packet - - parse_PMT(&pbPacket[0], &(m_pid.PCRPid), &(m_pid.CaptionPid)); - - if (m_timestamp.lastPTS == TIMESTAMP_INVALID_VALUE) { - AddMessage(RGY_LOG_TRACE, _T("PMT, PCR, Caption : %04x, %04x, %04x\n"), m_pid.PMTPid, m_pid.PCRPid, m_pid.CaptionPid); - } - - continue; // next packet - } - - // PCR - if (m_pid.PCRPid != 0 && packet.PID == m_pid.PCRPid) { - uint32_t bADP = (((uint32_t)pbPacket[3] & 0x30) >> 4); - if (!(bADP & 0x2)) - continue; // next packet - - uint32_t bAF = (uint32_t)pbPacket[5]; - if (!(bAF & 0x10)) - continue; // next packet - - // Get PCR. - /* 90kHz 27MHz - * +--------+-------+-------+ - * | 33 bits| 6 bits| 9 bits| - * +--------+-------+-------+ - */ - int64_t PCR_base = - ((int64_t)pbPacket[ 6] << 25) - | ((int64_t)pbPacket[ 7] << 17) - | ((int64_t)pbPacket[ 8] << 9) - | ((int64_t)pbPacket[ 9] << 1) - | ((int64_t)pbPacket[10] >> 7); - int64_t PCR_ext = - ((int64_t)(pbPacket[10] & 0x01) << 8) - | (int64_t)pbPacket[11]; - int64_t PCR = PCR_base + PCR_ext / 300; - - if (m_timestamp.lastPTS == TIMESTAMP_INVALID_VALUE) { - AddMessage(RGY_LOG_TRACE, _T("PCR, startPCR, lastPCR, basePCR : %11lld, %11lld, %11lld, %11lld\n"), - PCR, m_timestamp.startPCR, m_timestamp.lastPCR, m_timestamp.basePCR); - } - - // Check startPCR. - if (m_timestamp.startPCR == TIMESTAMP_INVALID_VALUE) { - m_timestamp.startPCR = PCR; - m_timestamp.correctTS = m_prm.DelayTime; - } else { - int64_t checkTS = 0; - // Check wrap-around. - if (PCR < m_timestamp.lastPCR) { - AddMessage(RGY_LOG_DEBUG, _T("====== PCR less than lastPCR ======\n")); - AddMessage(RGY_LOG_DEBUG, _T("PCR, startPCR, lastPCR, basePCR : %11lld, %11lld, %11lld, %11lld\n"), - PCR, m_timestamp.startPCR, m_timestamp.lastPCR, m_timestamp.basePCR); - m_timestamp.basePCR += WRAP_AROUND_VALUE; - checkTS = WRAP_AROUND_VALUE; - } - // Check drop packet. (This is even if the CM cut.) - checkTS += PCR; - if (checkTS > m_timestamp.lastPCR) { - checkTS -= m_timestamp.lastPCR; - if (!(m_prm.keepInterval) && (checkTS > PCR_MAXIMUM_INTERVAL)) { - m_timestamp.correctTS -= checkTS - (PCR_MAXIMUM_INTERVAL >> 2); - } - } - } - - // Update lastPCR. - m_timestamp.lastPCR = PCR; - - continue; // next packet - } - - // Caption - if (m_pid.CaptionPid != 0 && packet.PID == m_pid.CaptionPid) { - - int64_t PTS = 0; - - if (packet.PayloadStartFlag) { -#if 0 - // FIXME: Check PTS flag in PES Header. - // [example] - //if (!(packet.pts_flag)) - // continue; -#endif - - // Get Caption PTS. - PTS = GetPTS(pbPacket); - AddMessage(RGY_LOG_TRACE, _T("PTS, lastPTS, basePTS, startPCR : %11lld, %11lld, %11lld, %11lld "), - PTS, m_timestamp.lastPTS, m_timestamp.basePTS, m_timestamp.startPCR); - - // Check skip. - if (PTS == TIMESTAMP_INVALID_VALUE || m_timestamp.startPCR == TIMESTAMP_INVALID_VALUE) { - //if (log->active) - // AddMessage(RGY_LOG_TRACE, "Skip 1st caption\n"); - continue; - } - - // Check wrap-around. - // [case] - // lastPCR: Detection on the 1st packet. [1st PCR >>> w-around >>> 1st PTS] - // lastPTS: Detection on the packet of 2nd or later. [prev PTS >>> w-around >>> now PTS] - int64_t checkTS = (m_timestamp.lastPTS == TIMESTAMP_INVALID_VALUE) ? m_timestamp.lastPCR : m_timestamp.lastPTS; - if ((PTS < checkTS) && ((checkTS - PTS) >(WRAP_AROUND_CHECK_VALUE))) { - m_timestamp.basePTS += WRAP_AROUND_VALUE; - } - - // Update lastPTS. - m_timestamp.lastPTS = PTS; - - } else { - AddMessage(RGY_LOG_TRACE, _T("PTS, lastPTS, basePTS, startPCR : %11lld, %11lld, %11lld, %11lld "), - PTS, m_timestamp.lastPTS, m_timestamp.basePTS, m_timestamp.startPCR); - - // Check skip. - if (m_timestamp.lastPTS == TIMESTAMP_INVALID_VALUE || m_timestamp.startPCR == TIMESTAMP_INVALID_VALUE) { - AddMessage(RGY_LOG_TRACE, _T("Skip 2nd caption\n")); - continue; - } - - // Get Caption PTS from 1st caption. - PTS = m_timestamp.lastPTS; - } - - // Correct PTS for output. - PTS += m_timestamp.basePTS + m_timestamp.correctTS; - - rgy_time time((PTS > m_timestamp.startPCR) ? (PTS - m_timestamp.startPCR) / 90 : 0); - if (packet.PayloadStartFlag) { - AddMessage(RGY_LOG_TRACE, _T("%s Caption Time: %01d:%02d:%02d.%03d\n"), - ((packet.PayloadStartFlag) ? _T("1st") : _T("2nd")), time.h, time.m, time.s, time.ms); - } - - auto ret = m_dll->f_AddTSPacketCP()((uint8_t *)pbPacket); - if (ret == CHANGE_VERSION) { - LANG_TAG_INFO_DLL *ptrListDll; - DWORD count; - if ((ret = m_dll->f_GetTagInfoCP()(&ptrListDll, &count)) == TRUE) { - m_langTagList.clear(); - for (DWORD i = 0; i < count; i++) { - m_langTagList.push_back(ptrListDll[i]); - } - } - } else if (ret == NO_ERR_CAPTION) { - vector_move(subList, std::move(genCaption(PTS))); - } - } - } - return RGY_ERR_NONE; -} - -std::vector> Caption2Ass::genCaption(int64_t PTS) { - std::vector> subList; - int workCharSizeMode = 0; - int workCharW = 0; - int workCharH = 0; - int workCharHInterval = 0; - int workCharVInterval = 0; - int workPosX = 0; - int workPosY = 0; - BYTE workHLC = HLC_kigou; //must ignore low 4bits - WORD wLastSWFMode = 999; - int offsetPosX = 0; - int offsetPosY = 0; - double ratioX = 1.0; - double ratioY = 1.0; - - // Get language tag. - uint32_t ucLangTag = m_prm.LangType - 1; // m_dll->f_GetLangTagCP()(m_prm.LangType); - - // Output - std::vector captionList = getCaptionDataList((ucLangTag < m_langTagList.size()) ? (unsigned char)ucLangTag : 0); - - int addSpaceNum = 0; - std::unique_ptr pCapLine; - for (auto itcap = captionList.begin(); itcap != captionList.end(); itcap++) { - if (itcap->bClear && !pCapLine) { - // 字幕のスキップをチェック - if ((PTS + itcap->dwWaitTime * 90) <= m_timestamp.startPCR) { - AddMessage(RGY_LOG_DEBUG, _T("%d Caption skip\n"), captionList.size()); - } else if (m_capList.size() > 0) { - //endTimeはstartTime同様、startPCRを基準とする - int64_t endTime = (PTS + itcap->dwWaitTime * 90) - m_timestamp.startPCR; - std::vector> pkts; - switch (m_format) { - case FORMAT_ASS: pkts = genAss(endTime); break; - case FORMAT_SRT: pkts = genSrt(endTime); break; - default: break; - } - vector_move(subList, std::move(pkts)); - } - m_capList.clear(); - continue; - } - - AddMessage(RGY_LOG_TRACE, - _T(" SWFMode : %4d\n") - _T(" Client X:Y:W:H : %4d\t%4d\n") - _T(" Pos X:Y : %4d\t%4d\n"), - itcap->wSWFMode, - itcap->wClientX, itcap->wClientY, itcap->wClientW, itcap->wClientH, - itcap->wPosX, itcap->wPosY); - - int wPosX = itcap->wPosX; - int wPosY = itcap->wPosY; - - if (itcap->wSWFMode != wLastSWFMode) { - wLastSWFMode = itcap->wSWFMode; - static const auto resolution = make_array>( - std::make_pair(1920, 1080), - std::make_pair( 720, 480), - std::make_pair(1280, 720), - std::make_pair( 960, 540) - ); - const int index = (wLastSWFMode == 5) ? 0 - : (wLastSWFMode == 9) ? 1 - : (wLastSWFMode == 11) ? 2 - : 3; - ratioX = (double)(m_ass.PlayResX) / (double)(resolution[index].first); - ratioY = (double)(m_ass.PlayResY) / (double)(resolution[index].second); - } - if (m_dll->unicode()) { - if ((wPosX < 2000) || (wPosY < 2000)) { - offsetPosX = itcap->wClientX; - offsetPosY = itcap->wClientY; - } else { - offsetPosX = 0; - offsetPosY = 0; - wPosX -= 2000; - wPosY -= 2000; - } - } - - auto it2 = itcap->charList.begin(); - - if (itcap->charList.size() > 0 && !pCapLine) { - workCharSizeMode = it2->wCharSizeMode; - workCharW = it2->wCharW; - workCharH = it2->wCharH; - workCharHInterval = it2->wCharHInterval; - workCharVInterval = it2->wCharVInterval; - // Calculate offsetPos[X/Y]. - if (!(m_dll->unicode())) { - int amariPosX = 0; - int amariPosY = 0; - if (wLastSWFMode == 9) { - amariPosX = wPosX % 18; - amariPosY = wPosY % 15; - } else { - amariPosX = wPosX % ((workCharW + workCharHInterval) / 2); - amariPosY = wPosY % ((workCharH + workCharVInterval) / 2); - } - if ((amariPosX == 0) || (amariPosY == 0)) { - offsetPosX = itcap->wClientX; - offsetPosY = itcap->wClientY +10; - } else { - offsetPosX = 0; - offsetPosY = 0; - } - } - // Calculate workPos[X/Y]. - int y_swf_offset = 0; - double x_ratio = ratioX; - double y_ratio = ratioY; - switch (wLastSWFMode) { - case 0: - y_swf_offset = m_ass.SWF0offset; - break; - case 5: - y_swf_offset = m_ass.SWF5offset /* - 0 */; - break; - case 7: - y_swf_offset = m_ass.SWF7offset /* + 0 */; - break; - case 9: - y_swf_offset = m_ass.SWF9offset + ((m_dll->unicode()) ? 0 : -50); - break; - case 11: - y_swf_offset = m_ass.SWF11offset /* - 0 */; - break; - default: - x_ratio = y_ratio = 1.0; - break; - } - workPosX = (int)((wPosX + offsetPosX) * x_ratio); - workPosY = (int)((wPosY + offsetPosY + y_swf_offset) * y_ratio); - // Correction for workPosX. - workPosX = (workPosX > m_sidebarSize) ? workPosX - m_sidebarSize : 0; - - if (!(m_dll->unicode()) && (it2->wCharSizeMode == STR_SMALL)) - workPosY += (int)(10 * ratioY); - } - - if (!pCapLine) { - pCapLine.reset(new CAPTION_LINE()); - } - - int outStrW = 0; - for (; it2 != itcap->charList.end(); it2++) { - LINE_STR lineStr; - - int strCount = 0; - unsigned char workucR = it2->stCharColor.ucR; - unsigned char workucG = it2->stCharColor.ucG; - unsigned char workucB = it2->stCharColor.ucB; - BOOL workUnderLine = it2->bUnderLine; - BOOL workShadow = it2->bShadow; - BOOL workBold = it2->bBold; - BOOL workItalic = it2->bItalic; - BYTE workFlushMode = it2->bFlushMode; - workHLC = (it2->bHLC != 0) ? m_prm.HLCmode : it2->bHLC; - - if (!(m_dll->unicode()) && (it2->wCharSizeMode == STR_MEDIUM)) - // 全角 -> 半角 - it2->strDecode = GetHalfChar(it2->strDecode); - - const auto loglevel = RGY_LOG_TRACE; - if (loglevel >= m_pLog->getLogLevel(RGY_LOGT_CAPION2ASS)) { - AddMessage(loglevel, _T("pts: %11lld\n"), PTS); - if (it2->bUnderLine) - AddMessage(loglevel, _T(" UnderLine : on\n")); - if (it2->bBold) - AddMessage(loglevel, _T(" Bold : on\n")); - if (it2->bItalic) - AddMessage(loglevel, _T(" Italic : on\n")); - if (it2->bHLC != 0) - AddMessage(loglevel, _T(" HLC : on\n")); - AddMessage(loglevel, _T(" Color : %#.X "), it2->stCharColor); - AddMessage(loglevel, _T(" Char M,W,H,HI,VI : %4d, %4d, %4d, %4d, %4d "), - it2->wCharSizeMode, it2->wCharW, it2->wCharH, it2->wCharHInterval, it2->wCharVInterval); - AddMessage(loglevel, _T(" %s\n"), char_to_tstring(it2->strDecode, (m_dll->unicode()) ? CP_UTF8 : 932).c_str()); - } - - std::string str_utf8; - for (int i = 0; i < addSpaceNum; i++) { - str_utf8 += " "; - } - addSpaceNum = 0; - if (/*(m_prm.format == FORMAT_TAW) || */ (m_dll->unicode())) { - str_utf8 += it2->strDecode; - } else { - auto wstr = char_to_wstring(it2->strDecode, 932); - str_utf8 += wstring_to_string(wstr, CP_UTF8); - } - if (it2->wCharSizeMode != STR_SMALL) { - HALFCHAR_INFO hc = { 0 }; - strCount = count_utf8_length((unsigned char *)str_utf8.c_str(), &hc); - int char_nums = it2->wCharSizeMode == STR_MEDIUM ? hc.char_nums - (hc.char_nums - hc.half_nums) / 2 : hc.char_nums; - outStrW += (char_nums - hc.point_nums) * (workCharW + workCharHInterval) / 2; - } - - // Push back the caption strings. - lineStr.outHLC = workHLC; - lineStr.outCharColor.a = 0x00; - lineStr.outCharColor.r = workucR; - lineStr.outCharColor.g = workucG; - lineStr.outCharColor.b = workucB; - lineStr.outUnderLine = workUnderLine; - lineStr.outShadow = workShadow; - lineStr.outBold = workBold; - lineStr.outItalic = workItalic; - lineStr.outFlushMode = workFlushMode; - lineStr.outStrCount = strCount; - lineStr.str = str_utf8; - - pCapLine->outStrings.push_back(lineStr); - } - - if (pCapLine->outStrings.empty()) { - pCapLine.reset(); - continue; - } - - // Push back the caption lines. - bool bPushBack = true; - if (workCharSizeMode != STR_SMALL) { - auto next = itcap + 1; - for (; next != captionList.end(); next++) { - if (next->bClear) { - continue; - } - if (itcap->wPosY == next->wPosY && itcap->dwWaitTime == next->dwWaitTime) { - auto it3 = next->charList.begin(); - int diffPosX = next->wPosX - (itcap->wPosX + outStrW); - if (it3->wCharSizeMode != STR_SMALL && diffPosX >= 0) { - bPushBack = false; - if (diffPosX > 0) { - addSpaceNum = diffPosX * 2 / (workCharW + workCharHInterval); - } - } - } - break; - } - } - if (bPushBack) { - pCapLine->index = 0; //useless - pCapLine->pts = PTS; - //startTimeはstartPCRを基準とし、デバッグ用に用いる - pCapLine->startTime = (PTS > m_timestamp.startPCR) ? (DWORD)(PTS - m_timestamp.startPCR) : 0; - //endTimeは後で設定する - pCapLine->endTime = 0; - pCapLine->outCharSizeMode = (BYTE)workCharSizeMode; - pCapLine->outCharW = (WORD)(workCharW * ratioX); - pCapLine->outCharH = (WORD)(workCharH * ratioY); - pCapLine->outCharHInterval = (WORD)(workCharHInterval * ratioX); - pCapLine->outCharVInterval = (WORD)(workCharVInterval * ratioY); - pCapLine->outPosX = (WORD)workPosX; - pCapLine->outPosY = (WORD)workPosY; - - m_capList.push_back(std::move(pCapLine)); - } - } - return subList; -} - -std::vector> Caption2Ass::genAss(int64_t endTime) { - std::vector> assLines; - auto it = m_capList.begin(); - for (int i = 0; it != m_capList.end(); it++, i++) { - (*it)->endTime = endTime; - - rgy_time ts((uint32_t)((*it)->startTime / 90)); - rgy_time te((uint32_t)((*it)->endTime / 90)); - - unique_ptr_custom pkt(av_packet_alloc(), [this](AVPacket *pkt) { av_packet_free(&pkt); }); - //muxerには生のptsを伝達する - pkt->pts = (*it)->pts; - pkt->dts = (*it)->pts; - //startTime, endTimeは、startPCRを基準としているのでその差分は有効 - pkt->duration = (*it)->endTime - (*it)->startTime; - - auto it2 = (*it)->outStrings.begin(); - UINT outCharColor = it2->outCharColor.b << 16 - | it2->outCharColor.g << 8 - | it2->outCharColor.r; - - if (((*it)->outCharSizeMode != STR_SMALL) && ((it2->outHLC == HLC_box) || (it2->outHLC == HLC_draw))) { - BYTE outHLC = it2->outHLC; - int iHankaku = it2->outStrCount; - for (auto it3 = it2 + 1; it3 != (*it)->outStrings.end(); it3++) { - if (outHLC != it3->outHLC) - break; - iHankaku += it3->outStrCount; - } - // Output HLC. - if (outHLC == HLC_box) { - int iBoxPosX = (*it)->outPosX + (iHankaku * (((*it)->outCharW + (*it)->outCharHInterval) / 4)) - ((*it)->outCharHInterval / 4); - int iBoxPosY = (*it)->outPosY + ((*it)->outCharVInterval / 2); - int iBoxScaleX = (iHankaku + 1) * 50; - int iBoxScaleY = 100 * ((*it)->outCharH + (*it)->outCharVInterval) / (*it)->outCharH; - //std::string str = strsprintf("0,%01d:%02d:%02d.%02d,%01d:%02d:%02d.%02d,Box,,0000,0000,0000,,{\\pos(%d,%d)\\fscx%d\\fscy%d\\3c&H%06x&}", - // ts.h, ts.m, ts.s, ts.ms / 10, te.h, te.m, te.s, te.ms / 10, iBoxPosX, iBoxPosY, iBoxScaleX, iBoxScaleY, outCharColor); - std::string str = strsprintf("0,0,Box,,0000,0000,0000,,{\\pos(%d,%d)\\fscx%d\\fscy%d\\3c&H%06x&}", - iBoxPosX, iBoxPosY, iBoxScaleX, iBoxScaleY, outCharColor); - static uint8_t utf8box[] = { 0xE2, 0x96, 0xA0 }; - unique_ptr_custom pkt2(av_packet_alloc(), [this](AVPacket *pkt) { av_packet_free(&pkt); }); - av_packet_copy_props(pkt2.get(), pkt.get()); - uint8_t *ptr = (uint8_t *)av_strdup(str.c_str()); - av_packet_from_data(pkt2.get(), ptr, (int)str.length()); - AddMessage(RGY_LOG_DEBUG, _T("pts: %11lld, dur: %6lld, %01d:%02d:%02d.%02d,%01d:%02d:%02d.%02d, %s\n"), - pkt2->pts, pkt2->duration, - ts.h, ts.m, ts.s, ts.ms / 10, te.h, te.m, te.s, te.ms / 10, - char_to_tstring(str, CP_UTF8).c_str()); - assLines.push_back(std::move(pkt2)); - } else { /* outHLC == HLC_draw */ - int iBoxPosX = (*it)->outPosX + (iHankaku * (((*it)->outCharW + (*it)->outCharHInterval) / 4)); - int iBoxPosY = (*it)->outPosY + ((*it)->outCharVInterval / 4); - int iBoxScaleX = iHankaku * 55; - int iBoxScaleY = 100; //*((*it)->outCharH + (*it)->outCharVInterval) / (*it)->outCharH; - //auto str = strsprintf("0,%01d:%02d:%02d.%02d,%01d:%02d:%02d.%02d,Box,,0000,0000,0000,,{\\pos(%d,%d)\\3c&H%06x&\\p1}m 0 0 l %d 0 %d %d 0 %d{\\p0}", - // ts.h, ts.m, ts.s, ts.ms / 10, te.h, te.m, te.s, te.ms / 10, iBoxPosX, iBoxPosY, outCharColor, iBoxScaleX, iBoxScaleX, iBoxScaleY, iBoxScaleY); - auto str = strsprintf("0,0,Box,,0000,0000,0000,,{\\pos(%d,%d)\\3c&H%06x&\\p1}m 0 0 l %d 0 %d %d 0 %d{\\p0}", - iBoxPosX, iBoxPosY, outCharColor, iBoxScaleX, iBoxScaleX, iBoxScaleY, iBoxScaleY); - unique_ptr_custom pkt2(av_packet_alloc(), [this](AVPacket *pkt) { av_packet_free(&pkt); }); - av_packet_copy_props(pkt2.get(), pkt.get()); - uint8_t *ptr = (uint8_t *)av_strdup(str.c_str()); - av_packet_from_data(pkt2.get(), ptr, (int)str.length()); - AddMessage(RGY_LOG_DEBUG, _T("pts: %11lld, dur: %6lld, %01d:%02d:%02d.%02d,%01d:%02d:%02d.%02d, %s\n"), - pkt2->pts, pkt2->duration, - ts.h, ts.m, ts.s, ts.ms / 10, te.h, te.m, te.s, te.ms / 10, - char_to_tstring(str, CP_UTF8).c_str()); - assLines.push_back(std::move(pkt2)); - } - } - //std::string str = strsprintf("0,%01d:%02d:%02d.%02d,%01d:%02d:%02d.%02d,%s,,0000,0000,0000,,{\\pos(%d,%d)", - // ts.h, ts.m, ts.s, ts.ms / 10, te.h, te.m, te.s, te.ms / 10, - // ((*it)->outCharSizeMode == STR_SMALL) ? "Rubi" : "Default", - // (*it)->outPosX, (*it)->outPosY); - std::string str = strsprintf("0,0,%s,,0000,0000,0000,,{\\pos(%d,%d)", - ((*it)->outCharSizeMode == STR_SMALL) ? "Rubi" : "Default", - (*it)->outPosX, (*it)->outPosY); - - if (outCharColor != 0x00ffffff) - str += strsprintf("\\c&H%06x&", outCharColor); - if (it2->outUnderLine) - str += "\\u1"; - if (it2->outBold) - str += "\\b1"; - if (it2->outItalic) - str += "\\i1"; - str += "}"; - - if (((*it)->outCharSizeMode == STR_SMALL) && (m_prm.norubi)) { - str += "\\N"; - } else { - BOOL bHLC = FALSE; - // Output strings. - while (1) { - if (!bHLC && ((*it)->outCharSizeMode != STR_SMALL) && (it2->outHLC == HLC_kigou)) { - str += "["; - bHLC = TRUE; - } - - str += it2->str; - - auto prev = it2; - ++it2; - if (it2 == (*it)->outStrings.end()) - break; - - if (bHLC && (((*it)->outCharSizeMode == STR_SMALL) || (it2->outHLC != HLC_kigou))) { - str += "]"; - bHLC = FALSE; - } - - UINT prevCharColor = outCharColor; - outCharColor = it2->outCharColor.b << 16 - | it2->outCharColor.g << 8 - | it2->outCharColor.r; - - if (prevCharColor != outCharColor - /* || prev->outCharColor.ucAlpha != it2->outCharColor.ucAlpha */ - || prev->outUnderLine != it2->outUnderLine - || prev->outBold != it2->outBold - || prev->outItalic != it2->outItalic) { - str += strsprintf("{"); - if (prevCharColor != outCharColor - /* || prev->outCharColor.ucAlpha != it2->outCharColor.ucAlpha */) - str += strsprintf("\\c&H%06x&", outCharColor); - if (prev->outUnderLine != it2->outUnderLine) - str += strsprintf("\\u%d", it2->outUnderLine ? 1 : 0); - if (prev->outBold != it2->outBold) - str += strsprintf("\\b%d", it2->outBold ? 1 : 0); - if (prev->outItalic != it2->outItalic) - str += strsprintf("\\i%d", it2->outItalic ? 1 : 0); - str += strsprintf("}"); - } - } - if (bHLC) - str += "]"; - str += "\\N"; - } - uint8_t *ptr = (uint8_t *)av_strdup(str.c_str()); - av_packet_from_data(pkt.get(), ptr, (int)str.length()); - AddMessage(RGY_LOG_DEBUG, _T("pts: %11lld, dur: %6lld, %01d:%02d:%02d.%02d,%01d:%02d:%02d.%02d, %s\n"), - pkt->pts, pkt->duration, - ts.h, ts.m, ts.s, ts.ms / 10, te.h, te.m, te.s, te.ms / 10, - char_to_tstring(str, CP_UTF8).c_str()); - assLines.push_back(std::move(pkt)); - } - return assLines; -} - -std::vector> Caption2Ass::genSrt(int64_t endTime) { - unique_ptr_custom pkt(av_packet_alloc(), [this](AVPacket *pkt) { av_packet_free(&pkt); }); - rgy_time ts, te; - std::string str; - bool bNoSRT = true; - auto it = m_capList.begin(); - for (int i = 0; it != m_capList.end(); it++, i++) { - (*it)->endTime = endTime; - - if (i == 0) { - (*it)->endTime = endTime; - pkt->pts = (*it)->pts; - pkt->dts = (*it)->pts; - pkt->duration = (*it)->endTime - (*it)->startTime; - - ts = rgy_time((uint32_t)((*it)->startTime / 90)); - te = rgy_time((uint32_t)((*it)->endTime / 90)); - //str += strsprintf("%d\r\n%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d\r\n", - // m_srt.index, ts.h, ts.m, ts.s, ts.ms, te.h, te.m, te.s, te.ms); - } - - // ふりがな Skip - if ((*it)->outCharSizeMode == STR_SMALL) - continue; - bNoSRT = false; - - auto it2 = (*it)->outStrings.begin(); - bool italic = false, bold = false, underLine = false, charColor = false; - auto ornament_start = [&](vector::iterator& s) { - italic = (s)->outItalic != FALSE; - bold = (s)->outBold != FALSE; - underLine = (s)->outUnderLine != FALSE; - charColor = ((s)->outCharColor.r != 0xff - || (s)->outCharColor.g != 0xff - || (s)->outCharColor.b != 0xff); - - if ((s)->outItalic) str += ""; - if ((s)->outBold) str += ""; - if ((s)->outUnderLine) str += ""; - if (charColor) { - str += strsprintf("", - (s)->outCharColor.r, (s)->outCharColor.g, (s)->outCharColor.b); - } - }; - auto ornament_end = [&]() { - if (italic) str += ""; - if (bold) str += ""; - if (underLine) str += ""; - if (charColor) str += ""; - }; - if (m_srt.ornament) { - ornament_start(it2); - } - - BOOL bHLC = FALSE; - // Output strings. - while (true) { - if (!bHLC && (it2->outHLC != 0)) { - str += strsprintf("["); - bHLC = TRUE; - } - - str += it2->str; - - ++it2; - if (it2 == (*it)->outStrings.end()) - break; - - if (bHLC && (it2->outHLC == 0)) { - str += "]"; - bHLC = FALSE; - } - - if (m_srt.ornament) { - ornament_end(); - // Next ornament. - ornament_start(it2); - } - } - if (bHLC) - str += "]"; - if (m_srt.ornament) { - ornament_end(); - } - //str += "\r\n"; - } - - //if (m_capList.size() > 0) { - // if (bNoSRT) - // str += "\r\n"; - // str += "\r\n"; - // m_srt.index++; - //} - AddMessage(RGY_LOG_DEBUG, _T("pts: %11lld, dur: %6lld, %01d:%02d:%02d.%02d,%01d:%02d:%02d.%02d, %s\n"), - pkt->pts, pkt->duration, - ts.h, ts.m, ts.s, ts.ms / 10, te.h, te.m, te.s, te.ms / 10, - char_to_tstring(str, CP_UTF8).c_str()); - uint8_t *ptr = (uint8_t *)av_strdup(str.c_str()); - av_packet_from_data(pkt.get(), ptr, (int)str.length()); - - std::vector> assLines; - assLines.push_back(std::move(pkt)); - return assLines; -} - -#endif //#if ENABLE_AVSW_READER && (defined(_WIN32) || defined(_WIN64)) diff --git a/VCECore/rgy_caption.h b/VCECore/rgy_caption.h deleted file mode 100644 index befc4832..00000000 --- a/VCECore/rgy_caption.h +++ /dev/null @@ -1,322 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// NVEnc by rigaya -// ----------------------------------------------------------------------------------------- -// The MIT License -// -// Copyright (c) 2014-2016 rigaya -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -// -------------------------------------------------------------------------------------------- - -#ifndef __RGY_CAPTION_H__ -#define __RGY_CAPTION_H__ - -#include "rgy_osdep.h" -#include "rgy_version.h" -#if !CLFILTERS_AUF -#include "rgy_avutil.h" -#include "rgy_stream.h" -#endif -#include "rgy_err.h" -#include "rgy_log.h" -#include "rgy_def.h" - -enum C2AFormat { - FORMAT_INVALID = 0, - FORMAT_SRT = 1, - FORMAT_ASS = 2, - FORMAT_MAX -}; - -static const CX_DESC list_caption2ass[] = { - { _T("invalid"), FORMAT_INVALID }, - { _T("srt"), FORMAT_SRT }, - { _T("ass"), FORMAT_ASS }, - { NULL, 0 } -}; - -enum { - HLC_INVALID = 0, - HLC_kigou = 1, - HLC_box = 2, - HLC_draw = 3 -}; - -static const CX_DESC list_caption2ass_hlc[] ={ - { _T("invalid"), HLC_INVALID }, - { _T("kigou"), HLC_kigou }, - { _T("box"), HLC_box }, - { _T("draw"), HLC_draw }, - { NULL, 0 } -}; - -#if ENABLE_AVSW_READER && (defined(_WIN32) || defined(_WIN64)) - -#pragma warning(push) -#pragma warning(disable: 4010) //C4010: single-line comment contains line-continuation character -#include "Caption.h" -#pragma warning(pop) - -#define CAPTIONF(x) \ - private: \ - x pf ## x; \ - public: \ - const x f_ ## x() { return pf ## x; } - -class CaptionDLL { -public: - CaptionDLL(); - virtual ~CaptionDLL(); - RGY_ERR load(); - RGY_ERR init(); - bool unicode() const { - return unicode_; - } -private: - std::unique_ptr m_hModule; - - CAPTIONF(InitializeCP); - CAPTIONF(InitializeUNICODECP); - CAPTIONF(UnInitializeCP); - CAPTIONF(AddTSPacketCP); - CAPTIONF(ClearCP); - CAPTIONF(GetTagInfoCP); - CAPTIONF(GetCaptionDataCP); - - bool unicode_; -}; - -#undef CAPTIONF - -enum STRING_SIZE { - STR_SMALL = 0, //SSZ - STR_MEDIUM, //MSZ - STR_NORMAL, //NSZ - STR_MICRO, //SZX 0x60 - STR_HIGH_W, //SZX 0x41 - STR_WIDTH_W, //SZX 0x44 - STR_W, //SZX 0x45 - STR_SPECIAL_1, //SZX 0x6B - STR_SPECIAL_2, //SZX 0x64 -}; - -struct CAPTION_CHAR_DATA { - std::string strDecode; - DWORD wCharSizeMode; - - CLUT_DAT_DLL stCharColor; - CLUT_DAT_DLL stBackColor; - CLUT_DAT_DLL stRasterColor; - - BOOL bUnderLine; - BOOL bShadow; - BOOL bBold; - BOOL bItalic; - BYTE bFlushMode; - BYTE bHLC; //must ignore low 4bits - - WORD wCharW; - WORD wCharH; - WORD wCharHInterval; - WORD wCharVInterval; -}; - -struct CAPTION_DATA { - bool bClear; - WORD wSWFMode; - WORD wClientX; - WORD wClientY; - WORD wClientW; - WORD wClientH; - WORD wPosX; - WORD wPosY; - std::vector charList; - DWORD dwWaitTime; -}; - -struct ASS_COLOR { - uint8_t r, g, b, a; -}; - -struct LINE_STR { - BYTE outHLC; //must ignore low 4bits - ASS_COLOR outCharColor; - BOOL outUnderLine; - BOOL outShadow; - BOOL outBold; - BOOL outItalic; - BYTE outFlushMode; - int outStrCount; - std::string str; -}; - -struct CAPTION_LINE { - UINT index; - int64_t pts; - int64_t startTime; - int64_t endTime; - BYTE outCharSizeMode; - WORD outCharW; - WORD outCharH; - WORD outCharHInterval; - WORD outCharVInterval; - WORD outPosX; - WORD outPosY; - std::vector outStrings; -}; - -struct ass_setting_t { - int SWF0offset; - int SWF5offset; - int SWF7offset; - int SWF9offset; - int SWF11offset; - std::string Comment1; - std::string Comment2; - std::string Comment3; - int PlayResX; - int PlayResY; - std::string DefaultFontname; - int DefaultFontsize; - std::string DefaultStyle; - std::string BoxFontname; - int BoxFontsize; - std::string BoxStyle; - std::string RubiFontname; - int RubiFontsize; - std::string RubiStyle; - - ass_setting_t(); - void set(const tstring& inifile, int width, int height); -}; - -struct c2a_ts { - int64_t startPCR; - int64_t lastPCR; - int64_t lastPTS; - int64_t basePCR; - int64_t basePTS; - int64_t correctTS; - c2a_ts(); -}; - -struct Caption2AssPrm { - int DelayTime; - bool keepInterval; - BYTE HLCmode; - bool norubi; - int LangType; - tstring ass_type; - tstring FileName; - Caption2AssPrm(); -}; - -struct PidInfo { - uint16_t PMTPid; - uint16_t CaptionPid; - uint16_t PCRPid; - PidInfo(); -}; - -struct SrtOut { - bool ornament; - int index; - - SrtOut(); -}; - -class Caption2Ass { -public: - Caption2Ass(); - virtual ~Caption2Ass(); - RGY_ERR init(std::shared_ptr pLog, C2AFormat format); - RGY_ERR proc(const uint8_t *data, const size_t data_size, std::vector>& subList); - void close(); - bool enabled() const { return !!m_dll; }; - void setVidFirstKeyPts(int64_t pts) { - m_vidFirstKeyPts = pts; - } - - //assのヘッダを返す - std::string assHeader() const; - - C2AFormat format() const { return m_format; } - - //入力データがtsかどうかの判定 - bool isTS(const uint8_t *data, const size_t data_size) const; - - //出力解像度の設定 - void setOutputResolution(int w, int h, int sar_x, int sar_y); - - //現在の設定を表示 - void printParam(RGYLogLevel log_level); - - //内部データをリセット(seekが発生したときなどに使用する想定) - void reset(); -private: - void AddMessage(RGYLogLevel log_level, const tstring& str) { - if (!m_pLog || log_level < m_pLog->getLogLevel(RGY_LOGT_CAPION2ASS)) { - return; - } - auto lines = split(str, _T("\n")); - for (const auto& line : lines) { - if (line[0] != _T('\0')) { - m_pLog->write(log_level, RGY_LOGT_CAPION2ASS, (_T("cap: ") + line + _T("\n")).c_str()); - } - } - } - void AddMessage(RGYLogLevel log_level, const TCHAR *format, ...) { - if (!m_pLog || log_level < m_pLog->getLogLevel(RGY_LOGT_CAPION2ASS)) { - return; - } - - va_list args; - va_start(args, format); - int len = _vsctprintf(format, args) + 1; // _vscprintf doesn't count terminating '\0' - tstring buffer; - buffer.resize(len, _T('\0')); - _vstprintf_s(&buffer[0], len, format, args); - va_end(args); - AddMessage(log_level, buffer); - } - std::vector getCaptionDataList(uint8_t ucLangTag); - std::vector> genCaption(int64_t pts); - std::vector> genAss(int64_t endTime); - std::vector> genSrt(int64_t endTime); - - std::unique_ptr m_dll; - C2AFormat m_format; - bool m_streamSync; - rgy_stream m_stream; - c2a_ts m_timestamp; - Caption2AssPrm m_prm; - PidInfo m_pid; - std::list m_langTagList; - ass_setting_t m_ass; - std::vector> m_capList; - std::shared_ptr m_pLog; - int64_t m_vidFirstKeyPts; - int m_sidebarSize; - SrtOut m_srt; -}; - -#endif //#if ENABLE_AVSW_READER && (defined(_WIN32) || defined(_WIN64)) - -#endif //__RGY_CAPTION_H__ diff --git a/VCECore/rgy_cmd.cpp b/VCECore/rgy_cmd.cpp index dbe75b14..717e1eb9 100644 --- a/VCECore/rgy_cmd.cpp +++ b/VCECore/rgy_cmd.cpp @@ -4504,27 +4504,6 @@ int parse_one_common_option(const TCHAR *option_name, const TCHAR *strInput[], i } return 0; } -#if ENABLE_CAPTION2ASS - if (IS_OPTION("caption2ass")) { - if (i+1 < nArgNum && strInput[i+1][0] != _T('-')) { - i++; - C2AFormat format = FORMAT_INVALID; - if (PARSE_ERROR_FLAG != (format = (C2AFormat)get_value_from_chr(list_caption2ass, strInput[i]))) { - common->caption2ass = format; - } else { - print_cmd_error_invalid_value(option_name, strInput[i], list_caption2ass); - return 1; - } - } else { - common->caption2ass = FORMAT_SRT; - } - return 0; - } - if (IS_OPTION("no-caption2ass")) { - common->caption2ass = FORMAT_INVALID; - return 0; - } -#endif //#if ENABLE_CAPTION2ASS if (IS_OPTION("data-copy")) { common->AVMuxTarget |= (RGY_MUX_VIDEO | RGY_MUX_SUBTITLE); using trackID_Lang = std::pair; @@ -6521,7 +6500,6 @@ tstring gen_cmd(const RGYParamCommon *param, const RGYParamCommon *defaultPrm, b cmd << _T(" --sub-bsf ") << printTrack(param->ppSubtitleSelectList[i]) << _T("?") << param->ppSubtitleSelectList[i]->bsf; } } - OPT_LST(_T("--caption2ass"), caption2ass, list_caption2ass); tmp.str(tstring()); for (int i = 0; i < param->nDataSelectCount; i++) { @@ -6967,11 +6945,6 @@ tstring gen_cmd_help_common() { _T(" - copy ... copy metadata from input (default)\n") _T(" - clear ... do not set metadata\n") _T(" --sub-bsf [?] set bitstream filter to subtitle track.\n") -#if ENABLE_CAPTION2ASS - _T(" --caption2ass [] enable caption2ass during encode.\n") - _T(" !! This feature requires Caption.dll !!\n") - _T(" supported formats ... srt (default), ass\n") -#endif //#if ENABLE_CAPTION2ASS _T(" --data-copy [[,...]] copy data stream to output file.\n") _T(" --attachment-copy [[,...]] copy attachment stream to output file.\n") _T(" --attachment-source add file as attachment stream.\n") diff --git a/VCECore/rgy_filter_decimate.cpp b/VCECore/rgy_filter_decimate.cpp index e65567eb..1a55b3b1 100644 --- a/VCECore/rgy_filter_decimate.cpp +++ b/VCECore/rgy_filter_decimate.cpp @@ -36,6 +36,7 @@ #define _USE_MATH_DEFINES #include #include "convert_csp.h" +#include "rgy_avutil.h" #include "rgy_filter_decimate.h" #define DECIMATE_BLOCK_MAX (32) diff --git a/VCECore/rgy_input.cpp b/VCECore/rgy_input.cpp index eb7ade6f..6bf7307c 100644 --- a/VCECore/rgy_input.cpp +++ b/VCECore/rgy_input.cpp @@ -624,7 +624,6 @@ RGY_ERR initReaders( inputInfoAVCuvid.queueInfo = (perfMonitor) ? perfMonitor->GetQueueInfoPtr() : nullptr; inputInfoAVCuvid.HWDecCodecCsp = &HWDecCodecCsp; inputInfoAVCuvid.videoDetectPulldown = !vpp_rff && !vpp_afs && common->AVSyncMode == RGY_AVSYNC_ASSUME_CFR; - inputInfoAVCuvid.caption2ass = common->caption2ass; inputInfoAVCuvid.hdr10plusMetadataCopy = common->hdr10plusMetadataCopy; inputInfoAVCuvid.parseHDRmetadata = common->maxCll == maxCLLSource || common->masterDisplay == masterDisplaySource; inputInfoAVCuvid.interlaceAutoFrame = input->picstruct == RGY_PICSTRUCT_AUTO; diff --git a/VCECore/rgy_input.h b/VCECore/rgy_input.h index e019921e..91fc9f44 100644 --- a/VCECore/rgy_input.h +++ b/VCECore/rgy_input.h @@ -80,7 +80,6 @@ struct AVDemuxStream { AVRational timebase; //streamのtimebase [stream = nullptrの場合でも使えるように] void *subtitleHeader; //stream = nullptrの場合 caption2assのヘッダー情報 (srt形式でもass用のヘッダーが入っている) int subtitleHeaderSize; //stream = nullptrの場合 caption2assのヘッダー情報のサイズ - C2AFormat caption2ass; //stream = nullptrの場合 caption2assのformat char lang[4]; //trackの言語情報(3文字) AVDemuxStream() : @@ -101,7 +100,6 @@ struct AVDemuxStream { timebase({ 0, 0 }), subtitleHeader(nullptr), subtitleHeaderSize(0), - caption2ass(), lang() { }; }; diff --git a/VCECore/rgy_input_avcodec.cpp b/VCECore/rgy_input_avcodec.cpp index dd8750b7..6a1e8269 100644 --- a/VCECore/rgy_input_avcodec.cpp +++ b/VCECore/rgy_input_avcodec.cpp @@ -45,20 +45,6 @@ #if ENABLE_AVSW_READER -#if USE_CUSTOM_INPUT -static int funcReadPacket(void *opaque, uint8_t *buf, int buf_size) { - RGYInputAvcodec *reader = reinterpret_cast(opaque); - return reader->readPacket(buf, buf_size); -} -static int funcWritePacket(void *opaque, uint8_t *buf, int buf_size) { - RGYInputAvcodec *reader = reinterpret_cast(opaque); - return reader->writePacket(buf, buf_size); -} -static int64_t funcSeek(void *opaque, int64_t offset, int whence) { - RGYInputAvcodec *reader = reinterpret_cast(opaque); - return reader->seek(offset, whence); -} -#endif //USE_CUSTOM_INPUT static inline void extend_array_size(VideoFrameData *dataset) { static int default_capacity = 8 * 1024; @@ -107,7 +93,6 @@ RGYInputAvcodecPrm::RGYInputAvcodecPrm(RGYInputPrm base) : queueInfo(nullptr), HWDecCodecCsp(nullptr), videoDetectPulldown(false), - caption2ass(FORMAT_INVALID), parseHDRmetadata(false), hdr10plusMetadataCopy(false), interlaceAutoFrame(false), @@ -123,8 +108,7 @@ RGYInputAvcodec::RGYInputAvcodec() : m_Demux(), m_logFramePosList(), m_fpPacketList(), - m_hevcMp42AnnexbBuffer(), - m_cap2ass() { + m_hevcMp42AnnexbBuffer() { memset(&m_Demux.format, 0, sizeof(m_Demux.format)); memset(&m_Demux.video, 0, sizeof(m_Demux.video)); m_readerName = _T("av" DECODER_NAME "/avsw"); @@ -273,9 +257,6 @@ void RGYInputAvcodec::Close() { m_Demux.qStreamPktL2.close([](AVPacket **pkt) { av_packet_free(pkt); }); AddMessage(RGY_LOG_DEBUG, _T("Closed Stream Packet Buffer.\n")); - m_cap2ass.close(); - AddMessage(RGY_LOG_DEBUG, _T("Closed caption handler.\n")); - CloseFormat(&m_Demux.format); AddMessage(RGY_LOG_DEBUG, _T("Closed format.\n")); CloseVideo(&m_Demux.video); AddMessage(RGY_LOG_DEBUG, _T("Closed video.\n")); @@ -1348,42 +1329,6 @@ RGY_ERR RGYInputAvcodec::initFormatCtx(const TCHAR *strFileName, const RGYInputA return RGY_ERR_INVALID_FORMAT; } } - - if (m_cap2ass.enabled()) { -#if USE_CUSTOM_INPUT - if (m_Demux.format.isPipe || (!usingAVProtocols(filename_char, 0) && input_prm->inputOpt.size() == 0 && (inFormat == nullptr || !(inFormat->flags & (AVFMT_NEEDNUMBER | AVFMT_NOFILE))))) { - if (0 == _tcscmp(strFileName, _T("-"))) { - m_Demux.format.fpInput = stdin; - } else { - m_Demux.format.fpInput = _tfsopen(strFileName, _T("rb"), _SH_DENYWR); - if (m_Demux.format.fpInput == NULL) { - errno_t error = errno; - AddMessage(RGY_LOG_ERROR, _T("failed to open input file \"%s\": %s.\n"), strFileName, _tcserror(error)); - return RGY_ERR_FILE_OPEN; // Couldn't open file - } - if (!m_Demux.format.isPipe) { - if (rgy_get_filesize(strFileName, &m_Demux.format.inputFilesize) && m_Demux.format.inputFilesize == 0) { - AddMessage(RGY_LOG_ERROR, _T("size of input file \"%s\" is 0\n"), strFileName); - return RGY_ERR_FILE_OPEN; - } - } - } - m_Demux.format.inputBufferSize = 4 * 1024; - m_Demux.format.inputBuffer = (char *)av_malloc(m_Demux.format.inputBufferSize); - if (NULL == (m_Demux.format.formatCtx->pb = avio_alloc_context((unsigned char *)m_Demux.format.inputBuffer, m_Demux.format.inputBufferSize, 0, this, funcReadPacket, funcWritePacket, (m_Demux.format.isPipe) ? nullptr : funcSeek))) { - AddMessage(RGY_LOG_ERROR, _T("failed to alloc avio context.\n")); - return RGY_ERR_NULL_PTR; - } - } else -#endif - { - AddMessage(RGY_LOG_ERROR, - (USE_CUSTOM_INPUT == 0) ? (_T("--caption2ass cannot be used in this build.\n")) : - ((input_prm->inputOpt.size() > 0) ? _T("--caption2ass cannot be used with --input-option.\n") - : _T("--caption2ass only supported when input is file or pipe.\n"))); - m_cap2ass.disable(); - } - } //ファイルのオープン if ((ret = avformat_open_input(&(m_Demux.format.formatCtx), filename_char.c_str(), inFormat, &m_Demux.format.formatOptions)) != 0) { AddMessage(RGY_LOG_ERROR, _T("error opening file \"%s\": %s\n"), char_to_tstring(filename_char, CP_UTF8).c_str(), qsv_av_err2str(ret).c_str()); @@ -1462,12 +1407,6 @@ RGY_ERR RGYInputAvcodec::Init(const TCHAR *strFileName, VideoInfo *inputInfo, co av_log_set_level((m_printMes->getLogLevel(RGY_LOGT_IN) == RGY_LOG_DEBUG) ? AV_LOG_DEBUG : RGY_AV_LOG_LEVEL); av_qsv_log_set(m_printMes); - if (input_prm->caption2ass != FORMAT_INVALID) { - auto err = m_cap2ass.init(m_printMes, input_prm->caption2ass); - if (err != RGY_ERR_NONE) { - return err; - } - } if (input_prm->logPackets.length() > 0) { m_fpPacketList.reset(_tfopen(input_prm->logPackets.c_str(), _T("w"))); fprintf(m_fpPacketList.get(), " stream id, codec, pts, dts, duration, flags, pos\n"); @@ -1566,7 +1505,7 @@ RGY_ERR RGYInputAvcodec::Init(const TCHAR *strFileName, VideoInfo *inputInfo, co } if (input_prm->readSubtitle) { auto subStreams = getStreamIndex(AVMEDIA_TYPE_SUBTITLE); - if (subStreams.size() == 0 && !m_cap2ass.enabled()) { + if (subStreams.size() == 0) { AddMessage(RGY_LOG_WARN, _T("--sub-copy%s is set, but no subtitle stream found.\n"), (ENCODER_NVENC) ? _T("/--vpp-subburn") : _T("")); } else { m_Demux.format.subtitleTracks = (int)subStreams.size(); @@ -1705,15 +1644,6 @@ RGY_ERR RGYInputAvcodec::Init(const TCHAR *strFileName, VideoInfo *inputInfo, co } } - if (m_cap2ass.enabled()) { - const int maxSubTrackId = std::accumulate(m_Demux.stream.begin(), m_Demux.stream.end(), 0, [](int a, const AVDemuxStream& b) { - return trackMediaType(b.trackId) == AVMEDIA_TYPE_SUBTITLE ? std::max(a, trackID(b.trackId)) : a; - }); - m_cap2ass.setIndex(m_Demux.format.formatCtx->nb_streams, trackFullID(AVMEDIA_TYPE_SUBTITLE, maxSubTrackId+1)); - m_Demux.stream.push_back(m_cap2ass.stream()); - m_Demux.format.subtitleTracks++; - } - if (input_prm->readChapter) { m_Demux.chapter = make_vector((const AVChapter **)m_Demux.format.formatCtx->chapters, m_Demux.format.formatCtx->nb_chapters); } @@ -1915,9 +1845,6 @@ RGY_ERR RGYInputAvcodec::Init(const TCHAR *strFileName, VideoInfo *inputInfo, co AddMessage(RGY_LOG_ERROR, _T("failed to get first frame position.\n")); return sts; } - if (m_cap2ass.enabled()) { - m_cap2ass.setVidFirstKeyPts(m_Demux.video.streamFirstKeyPts); - } if (m_inputVideoInfo.frames > 0) { // avsw/avhwでは、--framesは--trimに置き換えて実現する @@ -3096,20 +3023,6 @@ HANDLE RGYInputAvcodec::getThreadHandleInput() { #endif //#if defined(WIN32) || defined(WIN64) } -//出力する動画の情報をセット -void RGYInputAvcodec::setOutputVideoInfo(int w, int h, int sar_x, int sar_y, bool mux) { - if (m_cap2ass.enabled()) { - if (mux) { - m_cap2ass.setOutputResolution(w, h, sar_x, sar_y); - m_cap2ass.printParam(RGY_LOG_DEBUG); - } else { - //muxしないなら処理する必要はない - AddMessage(RGY_LOG_WARN, _T("caption2ass will be disabled as muxer is disabled.\n")); - m_cap2ass.disable(); - } - } -} - RGY_ERR RGYInputAvcodec::ThreadFuncRead(RGYParamThread threadParam) { threadParam.apply(GetCurrentThread()); AddMessage(RGY_LOG_DEBUG, _T("Set input thread param: %s.\n"), threadParam.desc().c_str()); @@ -3130,34 +3043,5 @@ const AVContentLightMetadata *RGYInputAvcodec::getContentLight() const { return m_Demux.video.contentLight; }; -#if USE_CUSTOM_INPUT -int RGYInputAvcodec::readPacket(uint8_t *buf, int buf_size) { - auto ret = (int)_fread_nolock(buf, 1, buf_size, m_Demux.format.fpInput); - if (m_cap2ass.enabled()) { - if (m_cap2ass.proc(buf, ret, m_Demux.qStreamPktL1) != RGY_ERR_NONE) { - AddMessage(RGY_LOG_ERROR, _T("failed to process ts caption.\n")); - return AVERROR_INVALIDDATA; - } - } - return (ret == 0) ? AVERROR_EOF : ret; -} -int RGYInputAvcodec::writePacket(uint8_t *buf, int buf_size) { - return (int)fwrite(buf, 1, buf_size, m_Demux.format.fpInput); -} -int64_t RGYInputAvcodec::seek(int64_t offset, int whence) { - if (whence == AVSEEK_SIZE) { - //たまにwhence=65536(AVSEEK_SIZE)とかいう要求が来ることがある - return (m_Demux.format.inputFilesize) ? m_Demux.format.inputFilesize : -1; - } - if (whence != SEEK_SET && whence != SEEK_CUR && whence != SEEK_END) { - return -1; - } - if (m_cap2ass.enabled() && whence == SEEK_SET && offset == 0) { - m_cap2ass.reset(); - } - return _fseeki64(m_Demux.format.fpInput, offset, whence); -} -#endif //USE_CUSTOM_INPUT - #endif //ENABLE_AVSW_READER diff --git a/VCECore/rgy_input_avcodec.h b/VCECore/rgy_input_avcodec.h index 1d518b56..404b2d2d 100644 --- a/VCECore/rgy_input_avcodec.h +++ b/VCECore/rgy_input_avcodec.h @@ -43,13 +43,6 @@ #include #include -#if (defined(_WIN32) || defined(_WIN64)) -#define USE_CUSTOM_INPUT 1 -#include "rgy_caption.h" -#else -#define USE_CUSTOM_INPUT 0 -#endif - using std::vector; using std::pair; using std::deque; @@ -771,177 +764,6 @@ typedef struct AVDemuxer { RGYQueueMPMP qStreamPktL2; } AVDemuxer; -enum AVCAPTION_STATE { - //エラー - AVCAPTION_ERROR = -3, - AVCAPTION_DISABLED = -2, - AVCAPTION_NOT_TS = -1, - //初期状態 - AVCAPTION_UNKNOWN = 0, - //ts処理中 - AVCAPTION_IS_TS = 1, -}; - - -#if ENABLE_CAPTION2ASS -class AVCaption2Ass { -public: - AVCaption2Ass() : m_cap2ass(), m_pLog(), m_subList(), m_buffer(), - m_index(-1), m_trackId(0), - m_state(AVCAPTION_UNKNOWN), m_resolutionDetermined(false) { - }; - ~AVCaption2Ass() { close(); }; - bool enabled() const { - return m_cap2ass.enabled() && m_state >= AVCAPTION_UNKNOWN; - } - void close() { - m_state = AVCAPTION_UNKNOWN; - m_cap2ass.close(); - m_subList.clear(); - m_pLog.reset(); - } - RGY_ERR init(std::shared_ptr pLog, C2AFormat format) { - m_pLog = pLog; - return m_cap2ass.init(pLog, format); - } - C2AFormat format() const { - return m_cap2ass.format(); - } - AVCAPTION_STATE state() const { - return m_state; - } - void disable() { - m_state = AVCAPTION_DISABLED; - } - void reset() { - //m_resolutionDeterminedはリセットしない - m_state = AVCAPTION_UNKNOWN; - m_cap2ass.reset(); - m_buffer.clear(); - } - void setIndex(int streamIndex, int trackId) { - m_index = streamIndex; - m_trackId = trackId; - } - void setOutputResolution(int w, int h, int sar_x, int sar_y) { - m_cap2ass.setOutputResolution(w, h, sar_x, sar_y); - m_resolutionDetermined = true; - } - void printParam(RGYLogLevel log_level) { - m_cap2ass.printParam(log_level); - } - void setVidFirstKeyPts(int64_t pts) { - m_cap2ass.setVidFirstKeyPts(pts); - } - AVDemuxStream stream() const { - std::string header = m_cap2ass.assHeader(); - AVDemuxStream stream; - memset(&stream, 0, sizeof(AVDemuxStream)); - stream.index = m_index; - stream.trackId = m_trackId; - stream.subtitleHeader = av_strdup(header.c_str()); - stream.subtitleHeaderSize = (int)header.length(); - stream.timebase = av_make_q(1, 90000); - stream.caption2ass = m_cap2ass.format(); - return stream; - } - RGY_ERR proc(uint8_t *buf, size_t buf_size, decltype(AVDemuxer::qStreamPktL1)& qStreamPkt) { - auto ret = RGY_ERR_NONE; - if (buf_size == 0) { - return ret; - } - if (m_state == AVCAPTION_UNKNOWN) { - m_state = m_cap2ass.isTS(buf, buf_size) ? AVCAPTION_IS_TS : AVCAPTION_NOT_TS; - } - if (m_state == AVCAPTION_IS_TS) { - if (!m_resolutionDetermined) { - //出力解像度が決まるまでデータを蓄積 - vector_cat(m_buffer, buf, buf_size); - } else { - if (m_buffer.size() > 0) { - ret = m_cap2ass.proc(m_buffer.data(), m_buffer.size(), m_subList); - m_buffer.clear(); - m_buffer.shrink_to_fit(); - } - if (ret == RGY_ERR_NONE) { - ret = m_cap2ass.proc(buf, buf_size, m_subList); - } - if (ret != RGY_ERR_NONE) { - m_state = AVCAPTION_ERROR; - } else if (m_index >= 0) { //インデックスが決まるまでは、クラス内にためておく - for (auto it = m_subList.begin(); it != m_subList.end(); it++) { - (*it)->stream_index = m_index; - qStreamPkt.push_back(it->release()); - } - m_subList.clear(); - } - } - } - return ret; - } -protected: - Caption2Ass m_cap2ass; //Caption2Ass処理 - std::shared_ptr m_pLog; - std::vector> m_subList; - - //解像度が決まるまでデータを取っておくバッファ - std::vector m_buffer; - - int m_index; - int m_trackId; - - //現在の処理状態 - AVCAPTION_STATE m_state; - - //出力解像度が決まったら処理を開始するので、 - //出力解像度が決まったかどうかを示すフラグ - bool m_resolutionDetermined; -}; -#else -#pragma warning(push) -#pragma warning(disable: 4100) -class AVCaption2Ass { -public: - AVCaption2Ass() {}; - ~AVCaption2Ass() { }; - bool enabled() const { - return false; - } - void close() { - } - RGY_ERR init(std::shared_ptr pLog, C2AFormat format) { - return RGY_ERR_NONE; - } - C2AFormat format() const { - return FORMAT_INVALID; - } - AVCAPTION_STATE state() const { - return AVCAPTION_DISABLED; - } - void disable() { - } - void reset() { - } - void setIndex(int streamIndex, int trackId) { - } - void setOutputResolution(int w, int h, int sar_x, int sar_y) { - } - void printParam(int log_level) { - } - void setVidFirstKeyPts(int64_t pts) { - } - AVDemuxStream stream() const { - AVDemuxStream stream; - return stream; - } - RGY_ERR proc(uint8_t *buf, int buf_size, decltype(AVDemuxer::qStreamPktL1)& qStreamPkt) { - return RGY_ERR_NONE; - } -protected: -}; -#pragma warning(pop) -#endif //#if ENABLE_CAPTION2ASS - class RGYInputAvcodecPrm : public RGYInputPrm { public: int inputRetry; //ファイルオープンを再試行する回数 @@ -984,7 +806,6 @@ class RGYInputAvcodecPrm : public RGYInputPrm { PerfQueueInfo *queueInfo; //キューの情報を格納する構造体 DeviceCodecCsp *HWDecCodecCsp; //HWデコーダのサポートするコーデックと色空間 bool videoDetectPulldown; //pulldownの検出を試みるかどうか - C2AFormat caption2ass; //caption2assの処理の有効化 bool parseHDRmetadata; //HDR関連のmeta情報を取得する bool hdr10plusMetadataCopy; //HDR10plus関連のmeta情報を取得する bool interlaceAutoFrame; //フレームごとにインタレの検出を行う @@ -1061,9 +882,6 @@ class RGYInputAvcodec : public RGYInput //入力スレッドのハンドルを取得する HANDLE getThreadHandleInput(); - //出力する動画の情報をセット - void setOutputVideoInfo(int w, int h, int sar_x, int sar_y, bool mux); - //HDRのmetadataへのポインタを返す const AVMasteringDisplayMetadata *getMasteringDisplay() const; const AVContentLightMetadata *getContentLight() const; @@ -1170,7 +988,6 @@ class RGYInputAvcodec : public RGYInput tstring m_logFramePosList; //FramePosListの内容を入力終了時に出力する (デバッグ用) std::unique_ptr m_fpPacketList; // 読み取ったパケット情報を出力するファイル vector m_hevcMp42AnnexbBuffer; //HEVCのmp4->AnnexB簡易変換用バッファ - AVCaption2Ass m_cap2ass; }; #endif //ENABLE_AVSW_READER diff --git a/VCECore/rgy_output.cpp b/VCECore/rgy_output.cpp index ea5a9fdb..71b20326 100644 --- a/VCECore/rgy_output.cpp +++ b/VCECore/rgy_output.cpp @@ -1000,18 +1000,10 @@ RGY_ERR initWriters( common->AVMuxTarget |= RGY_MUX_VIDEO; } - double inputFileDuration = 0.0; - { auto pAVCodecReader = std::dynamic_pointer_cast(pFileReader); - if (pAVCodecReader != nullptr) { - //caption2ass用の解像度情報の提供 - //これをしないと入力ファイルのデータをずっとバッファし続けるので注意 - pAVCodecReader->setOutputVideoInfo(outputVideoInfo.dstWidth, outputVideoInfo.dstHeight, - outputVideoInfo.sar[0], outputVideoInfo.sar[1], - (common->AVMuxTarget & RGY_MUX_VIDEO) != 0); + if (auto pAVCodecReader = std::dynamic_pointer_cast(pFileReader); pAVCodecReader != nullptr) { inputFileDuration = pAVCodecReader->GetInputVideoDuration(); } - } bool isAfs = false; #if ENABLE_SM_READER { auto pReaderSM = std::dynamic_pointer_cast(pFileReader); @@ -1156,10 +1148,7 @@ RGY_ERR initWriters( if (pAudioSelect != nullptr || audioCopyAll || streamMediaType != AVMEDIA_TYPE_AUDIO) { streamTrackUsed.push_back(stream.trackId); if (pSubtitleSelect == nullptr && streamMediaType == AVMEDIA_TYPE_SUBTITLE) { - if (common->caption2ass == FORMAT_INVALID) { //caption2assの字幕の場合はそのまま処理する - continue; - } - //caption2assの字幕の場合、AVOutputStreamPrmのパラメータはデフォルト(copy)でよい + continue; } AVOutputStreamPrm prm; prm.src = stream; diff --git a/VCECore/rgy_output_avcodec.cpp b/VCECore/rgy_output_avcodec.cpp index 75c23830..1687c2d0 100644 --- a/VCECore/rgy_output_avcodec.cpp +++ b/VCECore/rgy_output_avcodec.cpp @@ -1803,9 +1803,7 @@ RGY_ERR RGYOutputAvcodec::InitOther(AVMuxOther *muxSub, AVOutputStreamPrm *input const auto mediaTypeStr = char_to_tstring(av_get_media_type_string(mediaType)); AddMessage(RGY_LOG_DEBUG, _T("start initializing %s ouput...\n"), mediaTypeStr.c_str()); - AVCodecID codecId = (inputStream->src.stream) - ? inputStream->src.stream->codecpar->codec_id - : (inputStream->src.caption2ass == FORMAT_ASS) ? AV_CODEC_ID_ASS : AV_CODEC_ID_SUBRIP; + AVCodecID codecId = inputStream->src.stream->codecpar->codec_id; if (avcodecIsCopy(inputStream->encodeCodec) && inputStream->bsf.length() == 0 @@ -1862,34 +1860,14 @@ RGY_ERR RGYOutputAvcodec::InitOther(AVMuxOther *muxSub, AVOutputStreamPrm *input auto srcCodecParam = unique_ptr>( avcodec_parameters_alloc(), RGYAVDeleter(avcodec_parameters_free)); - if (inputStream->src.stream == nullptr) { - //caption2assで生成した字幕を受け取る - const auto src_codec_id = (inputStream->src.caption2ass == FORMAT_ASS) ? AV_CODEC_ID_ASS : AV_CODEC_ID_SUBRIP; - const auto codec = avcodec_find_decoder(src_codec_id); - if (nullptr == (muxSub->streamOut = avformat_new_stream(m_Mux.format.formatCtx, codec))) { - AddMessage(RGY_LOG_ERROR, _T("failed to create new stream for subtitle.\n")); - return RGY_ERR_NULL_PTR; - } - if (src_codec_id == AV_CODEC_ID_ASS) { - if (inputStream->src.subtitleHeader == nullptr || inputStream->src.subtitleHeaderSize == 0) { - AddMessage(RGY_LOG_ERROR, _T("subtitle header unknown for track %d.\n"), trackID(inputStream->src.trackId)); - return RGY_ERR_NULL_PTR; - } - srcCodecParam->extradata_size = inputStream->src.subtitleHeaderSize; - srcCodecParam->extradata = (uint8_t *)av_strdup((char *)inputStream->src.subtitleHeader); - } - srcCodecParam->codec_type = codec->type; - srcCodecParam->codec_id = codec->id; - } else { - avcodec_parameters_copy(srcCodecParam.get(), inputStream->src.stream->codecpar); + avcodec_parameters_copy(srcCodecParam.get(), inputStream->src.stream->codecpar); - if (nullptr == (muxSub->streamOut = avformat_new_stream(m_Mux.format.formatCtx, avcodec_find_decoder(codecId)))) { - AddMessage(RGY_LOG_ERROR, _T("failed to create new stream for subtitle.\n")); - return RGY_ERR_NULL_PTR; - } - AddMessage(RGY_LOG_DEBUG, _T("output stream index %d, pkt_timebase %d/%d, trackId %d\n"), - inputStream->src.index, inputStream->src.stream->time_base.num, inputStream->src.stream->time_base.den, trackID(inputStream->src.trackId)); + if (nullptr == (muxSub->streamOut = avformat_new_stream(m_Mux.format.formatCtx, avcodec_find_decoder(codecId)))) { + AddMessage(RGY_LOG_ERROR, _T("failed to create new stream for subtitle.\n")); + return RGY_ERR_NULL_PTR; } + AddMessage(RGY_LOG_DEBUG, _T("output stream index %d, pkt_timebase %d/%d, trackId %d\n"), + inputStream->src.index, inputStream->src.stream->time_base.num, inputStream->src.stream->time_base.den, trackID(inputStream->src.trackId)); if (inputStream->asdata) { srcCodecParam->codec_type = AVMEDIA_TYPE_UNKNOWN; } else if (mediaType == AVMEDIA_TYPE_DATA) { diff --git a/VCECore/rgy_prm.cpp b/VCECore/rgy_prm.cpp index d61e5578..bec93ed9 100644 --- a/VCECore/rgy_prm.cpp +++ b/VCECore/rgy_prm.cpp @@ -1538,7 +1538,6 @@ RGYParamCommon::RGYParamCommon() : copyChapter(false), keyOnChapter(false), chapterNoTrim(false), - caption2ass(FORMAT_INVALID), audioIgnoreDecodeError(DEFAULT_IGNORE_DECODE_ERROR), videoIgnoreTimestampError(DEFAULT_VIDEO_IGNORE_TIMESTAMP_ERROR), muxOpt(), diff --git a/VCECore/rgy_prm.h b/VCECore/rgy_prm.h index f7bc215f..c6502432 100644 --- a/VCECore/rgy_prm.h +++ b/VCECore/rgy_prm.h @@ -31,7 +31,6 @@ #include "rgy_def.h" #include "rgy_log.h" -#include "rgy_caption.h" #include "rgy_hdr10plus.h" #include "rgy_thread_affinity.h" #include "rgy_simd.h" @@ -1514,7 +1513,6 @@ struct RGYParamCommon { bool copyChapter; bool keyOnChapter; bool chapterNoTrim; - C2AFormat caption2ass; int audioIgnoreDecodeError; int videoIgnoreTimestampError; RGYOptList muxOpt; diff --git a/VCECore/rgy_version.h b/VCECore/rgy_version.h index 05ad28a8..06c7ece6 100644 --- a/VCECore/rgy_version.h +++ b/VCECore/rgy_version.h @@ -29,9 +29,9 @@ #ifndef __RGY_VERSION_H__ #define __RGY_VERSION_H__ -#define VER_FILEVERSION 0,8,20,0 -#define VER_STR_FILEVERSION "8.20" -#define VER_STR_FILEVERSION_TCHAR _T("8.20") +#define VER_FILEVERSION 0,8,21,0 +#define VER_STR_FILEVERSION "8.21" +#define VER_STR_FILEVERSION_TCHAR _T("8.21") #ifdef _M_IX86 diff --git a/VCECore/vce_cmd.cpp b/VCECore/vce_cmd.cpp index 316e1020..73653f41 100644 --- a/VCECore/vce_cmd.cpp +++ b/VCECore/vce_cmd.cpp @@ -33,7 +33,6 @@ #include "rgy_osdep.h" #include "rgy_version.h" #include "rgy_perf_monitor.h" -#include "rgy_caption.h" #include "vce_param.h" #include "core/Version.h" #include "rgy_cmd.h" diff --git a/VCECore/vce_device.cpp b/VCECore/vce_device.cpp index 829eeebe..b2c834bf 100644 --- a/VCECore/vce_device.cpp +++ b/VCECore/vce_device.cpp @@ -28,6 +28,7 @@ #include "vce_device.h" #include "vce_util.h" #include "VideoDecoderUVD.h" +#include "rgy_avutil.h" const wchar_t *VCEDevice::CAP_10BITDEPTH = L"CAP_10BITDEPTH"; diff --git a/VCECore/vce_param.h b/VCECore/vce_param.h index 0ea2e468..e94ab126 100644 --- a/VCECore/vce_param.h +++ b/VCECore/vce_param.h @@ -41,7 +41,6 @@ RGY_DISABLE_WARNING_STR("-Wclass-memaccess") #include "VQEnhancer.h" #include "VideoConverter.h" RGY_DISABLE_WARNING_POP -#include "rgy_caption.h" #include "rgy_prm.h" static const wchar_t* VCE_PARAM_KEY_INPUT = L"INPUT"; diff --git a/VCEEnc/VCEEnc.vcxproj b/VCEEnc/VCEEnc.vcxproj index e5f572ae..4565dfcd 100644 --- a/VCEEnc/VCEEnc.vcxproj +++ b/VCEEnc/VCEEnc.vcxproj @@ -178,7 +178,7 @@ Disabled - .\;.\encode;.\prm;.\frm;..\VCECore;..\tinyxml2;$(AMDAPPSDKROOT)\include;..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(CAPTION2ASS_SRC)\common;$(OPENCL_HEADERS);%(AdditionalIncludeDirectories) + .\;.\encode;.\prm;.\frm;..\VCECore;..\tinyxml2;$(AMDAPPSDKROOT)\include;..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(OPENCL_HEADERS);%(AdditionalIncludeDirectories) WIN32;_CRT_SECURE_NO_WARNINGS;VCE_AUO;_DEBUG;_WINDOWS;_USRDLL;VCE_AUO;%(PreprocessorDefinitions) false Default @@ -224,7 +224,7 @@ exit /B 0 Disabled - .\;.\encode;.\prm;.\frm;..\VCECore;..\tinyxml2;$(AMDAPPSDKROOT)\include;..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(CAPTION2ASS_SRC)\common;$(OPENCL_HEADERS);%(AdditionalIncludeDirectories) + .\;.\encode;.\prm;.\frm;..\VCECore;..\tinyxml2;$(AMDAPPSDKROOT)\include;..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(OPENCL_HEADERS);%(AdditionalIncludeDirectories) WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) false Default @@ -272,7 +272,7 @@ exit /B 0 Disabled - .\;.\encode;.\prm;.\frm;..\VCECore;..\tinyxml2;$(AMDAPPSDKROOT)\include;..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(CAPTION2ASS_SRC)\common;$(OPENCL_HEADERS);%(AdditionalIncludeDirectories) + .\;.\encode;.\prm;.\frm;..\VCECore;..\tinyxml2;$(AMDAPPSDKROOT)\include;..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(OPENCL_HEADERS);%(AdditionalIncludeDirectories) WIN32;_CRT_SECURE_NO_WARNINGS;VCE_AUO;_DEBUG;_WINDOWS;_USRDLL;VCE_AUO;%(PreprocessorDefinitions) Default MultiThreadedDebugDLL @@ -318,7 +318,7 @@ exit /B 0 Disabled - .\;.\encode;.\prm;.\frm;..\VCECore;..\tinyxml2;$(AMDAPPSDKROOT)\include;..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(CAPTION2ASS_SRC)\common;$(OPENCL_HEADERS);%(AdditionalIncludeDirectories) + .\;.\encode;.\prm;.\frm;..\VCECore;..\tinyxml2;$(AMDAPPSDKROOT)\include;..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(OPENCL_HEADERS);%(AdditionalIncludeDirectories) WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) Default MultiThreadedDebug @@ -370,7 +370,7 @@ exit /B 0 Size true true - .\;.\encode;.\prm;.\frm;..\VCECore;..\tinyxml2;$(AMDAPPSDKROOT)\include;..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(CAPTION2ASS_SRC)\common;$(OPENCL_HEADERS);%(AdditionalIncludeDirectories) + .\;.\encode;.\prm;.\frm;..\VCECore;..\tinyxml2;$(AMDAPPSDKROOT)\include;..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(OPENCL_HEADERS);%(AdditionalIncludeDirectories) WIN32;_CRT_SECURE_NO_WARNINGS;VCE_AUO;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true MultiThreadedDLL @@ -422,7 +422,7 @@ exit /B 0 Size true true - .\;.\encode;.\prm;.\frm;..\VCECore;..\tinyxml2;$(AMDAPPSDKROOT)\include;..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(CAPTION2ASS_SRC)\common;$(OPENCL_HEADERS);%(AdditionalIncludeDirectories) + .\;.\encode;.\prm;.\frm;..\VCECore;..\tinyxml2;$(AMDAPPSDKROOT)\include;..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(OPENCL_HEADERS);%(AdditionalIncludeDirectories) WIN32;_CRT_SECURE_NO_WARNINGS;VCE_AUO;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true MultiThreadedDLL @@ -474,7 +474,7 @@ exit /B 0 Size true true - .\;.\encode;.\prm;.\frm;..\VCECore;..\tinyxml2;$(AMDAPPSDKROOT)\include;..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(CAPTION2ASS_SRC)\common;$(OPENCL_HEADERS);%(AdditionalIncludeDirectories) + .\;.\encode;.\prm;.\frm;..\VCECore;..\tinyxml2;$(AMDAPPSDKROOT)\include;..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(OPENCL_HEADERS);%(AdditionalIncludeDirectories) WIN32;_CRT_SECURE_NO_WARNINGS;VCE_AUO;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true MultiThreadedDLL @@ -527,7 +527,7 @@ exit /B 0 Size true true - .\;.\encode;.\prm;.\frm;..\VCECore;..\tinyxml2;$(AMDAPPSDKROOT)\include;..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(CAPTION2ASS_SRC)\common;$(OPENCL_HEADERS);%(AdditionalIncludeDirectories) + .\;.\encode;.\prm;.\frm;..\VCECore;..\tinyxml2;$(AMDAPPSDKROOT)\include;..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(OPENCL_HEADERS);%(AdditionalIncludeDirectories) WIN32;_CRT_SECURE_NO_WARNINGS;VCE_AUO;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true MultiThreaded diff --git a/VCEEnc/VCEEnc_readme.txt b/VCEEnc/VCEEnc_readme.txt index 367eb7d2..3dde6a19 100644 --- a/VCEEnc/VCEEnc_readme.txt +++ b/VCEEnc/VCEEnc_readme.txt @@ -181,6 +181,24 @@ Radeon RX550 今後の更新で設定ファイルの互換性がなくなるかもしれません。 【どうでもいいメモ】 +2023.12.10 (8.21) +- ffmpeg 6.1に更新。(Windows版) + - ffmpeg 5.1 -> 6.1 + - libpng 1.3.9 -> 1.4.0 + - opus 1.3.1 -> 1.4 + - libsndfile 1.2.0 -> 1.2.2 + - libxml2 2.10.3 -> 2.12.0 + - dav1d 1.0.0 -> 1.3.0 + - libaribcaption 1.1.1 (new!) + +- --caption2assを廃止。 + --sub-codec ass#sub_type=ass,ass_single_rect=true で同等の処理が可能。 +- --audio-delayを小数点で渡せるように変更。 +- VCEEnc 8.17からAVX2に対応しない環境で動作しないのを回避。 +- --option-fileが空のファイルの時に異常終了してしまう問題を修正。 +- --seek使用時の進捗表示を改善。 +- ts出力時にaacをコピーする時の処理を改善。 + 2023.11.18 (8.20) [VCEEncC] - --vpp-yadif/--vpp-nnediでbob化する際、--vpp-rffなしでrffな動画を処理するとtimestamp周りの計算がおかしくなりエラー終了する問題を修正。 diff --git a/VCEEncC/VCEEncC.vcxproj b/VCEEncC/VCEEncC.vcxproj index c67bbec5..255bcd92 100644 --- a/VCEEncC/VCEEncC.vcxproj +++ b/VCEEncC/VCEEncC.vcxproj @@ -165,7 +165,7 @@ Disabled - ..\VCECore;$(AMDAPPSDKROOT)\include;..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;..\ffmpeg_lgpl\include;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(CAPTION2ASS_SRC)\common;$(OPENCL_HEADERS) + ..\VCECore;$(AMDAPPSDKROOT)\include;..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;..\ffmpeg_lgpl\include;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(OPENCL_HEADERS) WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) false EnableFastChecks @@ -209,7 +209,7 @@ copy /y "$(SolutionDir)ffmpeg_lgpl\lib\$(PlatformName)\libass-*.dll" "$(OutDir)" Disabled - ..\VCECore;$(AMDAPPSDKROOT)\include;..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;..\ffmpeg_lgpl\include;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(CAPTION2ASS_SRC)\common;$(OPENCL_HEADERS) + ..\VCECore;$(AMDAPPSDKROOT)\include;..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;..\ffmpeg_lgpl\include;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(OPENCL_HEADERS) WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) false EnableFastChecks @@ -254,7 +254,7 @@ copy /y "$(SolutionDir)ffmpeg_lgpl\lib\$(PlatformName)\libass-*.dll" "$(OutDir)" Disabled - ..\VCECore;$(AMDAPPSDKROOT)\include;..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;..\ffmpeg_lgpl\include;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(CAPTION2ASS_SRC)\common;$(OPENCL_HEADERS) + ..\VCECore;$(AMDAPPSDKROOT)\include;..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;..\ffmpeg_lgpl\include;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(OPENCL_HEADERS) WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebugDLL @@ -296,7 +296,7 @@ copy /y "$(SolutionDir)ffmpeg_lgpl\lib\$(PlatformName)\libass-*.dll" "$(OutDir)" Disabled - ..\VCECore;$(AMDAPPSDKROOT)\include;..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;..\ffmpeg_lgpl\include;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(CAPTION2ASS_SRC)\common;$(OPENCL_HEADERS) + ..\VCECore;$(AMDAPPSDKROOT)\include;..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;..\ffmpeg_lgpl\include;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(OPENCL_HEADERS) WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebug @@ -340,7 +340,7 @@ copy /y "$(SolutionDir)ffmpeg_lgpl\lib\$(PlatformName)\libass-*.dll" "$(OutDir)" /execution-charset:shift_jis MaxSpeed true - ..\VCECore;$(AMDAPPSDKROOT)\include;..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;..\ffmpeg_lgpl\include;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(CAPTION2ASS_SRC)\common;$(OPENCL_HEADERS) + ..\VCECore;$(AMDAPPSDKROOT)\include;..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;..\ffmpeg_lgpl\include;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(OPENCL_HEADERS) WIN32;_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) MultiThreadedDLL true @@ -386,7 +386,7 @@ copy /y "$(SolutionDir)ffmpeg_lgpl\lib\$(PlatformName)\libass-*.dll" "$(OutDir)" /execution-charset:shift_jis MinSpace true - ..\VCECore;$(AMDAPPSDKROOT)\include;..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;..\ffmpeg_lgpl\include;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(CAPTION2ASS_SRC)\common;$(OPENCL_HEADERS) + ..\VCECore;$(AMDAPPSDKROOT)\include;..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;..\ffmpeg_lgpl\include;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(OPENCL_HEADERS) WIN32;_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) MultiThreadedDLL true @@ -436,7 +436,7 @@ copy /y "$(SolutionDir)ffmpeg_lgpl\lib\$(PlatformName)\libass-*.dll" "$(OutDir)" /execution-charset:shift_jis MinSpace true - ..\VCECore;$(AMDAPPSDKROOT)\include;..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;..\ffmpeg_lgpl\include;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(CAPTION2ASS_SRC)\common;$(OPENCL_HEADERS) + ..\VCECore;$(AMDAPPSDKROOT)\include;..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;..\ffmpeg_lgpl\include;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(OPENCL_HEADERS) WIN32;_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) MultiThreaded true @@ -488,7 +488,7 @@ copy /y "$(SolutionDir)ffmpeg_lgpl\lib\$(PlatformName)\libass-*.dll" "$(OutDir)" /execution-charset:shift_jis MinSpace true - ..\VCECore;$(AMDAPPSDKROOT)\include;..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;..\ffmpeg_lgpl\include;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(CAPTION2ASS_SRC)\common;$(OPENCL_HEADERS) + ..\VCECore;$(AMDAPPSDKROOT)\include;..\AMF\amf\public\include;..\AMF\amf\public\include\core;..\AMF\amf\public\include\components;..\ffmpeg_lgpl\include;$(AVISYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include;$(VAPOURSYNTH_SDK)\include\vapoursynth;$(OPENCL_HEADERS) WIN32;_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) MultiThreaded true diff --git a/VCEEncC_Options.en.md b/VCEEncC_Options.en.md index 997e03d4..7bd3e204 100644 --- a/VCEEncC_Options.en.md +++ b/VCEEncC_Options.en.md @@ -144,7 +144,6 @@ - [--sub-disposition \[\?\]\](#--sub-disposition-intstringstring) - [--sub-metadata \[\?\]\ or \[\?\]\=\](#--sub-metadata-intstringstring-or-intstringstringstring) - [--sub-bsf \[\?\]\](#--sub-bsf-intstringstring) - - [--caption2ass \[\\]](#--caption2ass-string) - [--data-copy \[\\[,\\]...\]](#--data-copy-intint) - [--attachment-copy \[\\[,\\]...\]](#--attachment-copy-intint) - [--attachment-source \\[:{\?}\[;\=\\]...\]...](#--attachment-source-stringintparam1value1) @@ -1312,13 +1311,6 @@ Set metadata for subtitle track. ### --sub-bsf [<int/string>?]<string> Apply [bitstream filter](https://ffmpeg.org/ffmpeg-bitstream-filters.html) to subtitle track. -### --caption2ass [<string>] -Enable internal caption2ass process. This feature requires Caption.dll. - -**Note:** Pelase always select srt format when muxing to mp4. - -supported formats ... srt (default), ass - ### --data-copy [<int>[,<int>]...] Copy data stream from input file. Available only when avhw / avsw reader is used. @@ -2297,7 +2289,7 @@ Select the level of log output. - **Target** Target category of logs. Will be handled as ```all``` when omitted. - all ... Set all targets. - - app ... Set all targets, except libav, libass, perfmonitor, caption2ass, amf. + - app ... Set all targets, except libav, libass, perfmonitor, amf. - device ... Device initialization. - core ... Application core logs, including core_progress and core_result - core_progress ... Progress indicator @@ -2311,7 +2303,6 @@ Select the level of log output. - libav ... internal logs of libav library - libass ... logs of ass library - perfmonitor ... logs of perf monitoring - - caption2ass ... logs of caption2ass - Examples ``` diff --git a/VCEEncC_Options.ja.md b/VCEEncC_Options.ja.md index 4be37600..cb5c5e9f 100644 --- a/VCEEncC_Options.ja.md +++ b/VCEEncC_Options.ja.md @@ -142,7 +142,6 @@ - [--sub-disposition \[\?\]\\[,\\]\[\]...](#--sub-disposition-intstringstringstring) - [--sub-metadata \[\?\]\ or \[\?\]\=\](#--sub-metadata-intstringstring-or-intstringstringstring) - [--sub-bsf \[\?\]\](#--sub-bsf-intstringstring) - - [--caption2ass \[\\]](#--caption2ass-string) - [--data-copy \[\\[,\\]...\]](#--data-copy-intint) - [--attachment-copy \[\\[,\\]...\]](#--attachment-copy-intint) - [--attachment-source \\[:{\?}\[;\=\\]...\]...](#--attachment-source-stringintparam1value1) @@ -1250,15 +1249,6 @@ nero形式、apple形式、matroska形式に対応する。--chapter-copyとは ### --sub-bsf [<int/string>?]<string> 字幕トラックにbitstream filterを適用する。使用可能なフィルタは、[こちら](https://ffmpeg.org/ffmpeg-bitstream-filters.html)の中から選択可能。 -### --caption2ass [<string>] -caption2assによる字幕抽出処理を行い、動画にmuxして出力する。別途 "Caption.dll" が必要。 - -出力フォーマットがassかsrtのみなので、mkvなどで出力してください。 - -- **出力フォーマット** - - srt (デフォルト) - - ass - ### --data-copy [<int>[,<int>]...] データストリームをコピーする。avhw/avswリーダー使用時のみ有効。 @@ -2288,7 +2278,7 @@ file以外のプロトコルを使用する場合には、この出力バッフ - **対象** ログ出力レベルの設定対象の指定。省略した場合は、```all```として扱う。 - all ... すべて - - app ... libav, libass, perfmonitor, caption2ass, amf を除いたすべて + - app ... libav, libass, perfmonitor, amf を除いたすべて - device ... デバイス初期化関連 - core ... アプリケーションのコア部分 (core_progress, core_result含む) - core_progress ... 進捗表示 @@ -2302,7 +2292,6 @@ file以外のプロトコルを使用する場合には、この出力バッフ - libav ... libavライブラリ内部のログ出力 - libass ... assライブラリ関連 - perfmonitor ... パフォーマンスモニタ関連 - - caption2ass ... caption2ass関連 - 使用例 ``` diff --git a/configure b/configure index 97fd54d3..b91fecf8 100755 --- a/configure +++ b/configure @@ -598,7 +598,7 @@ convert_csp_avx2.cpp convert_csp_sse2.cpp convert_csp_sse41.cpp cpu_info.cpp gpu_info.cpp gpuz_info.cpp logo.cpp \ rgy_aspect_ratio.cpp rgy_avlog.cpp \ rgy_avutil.cpp rgy_bitstream.cpp rgy_bitstream_avx2.cpp rgy_bitstream_avx512bw.cpp \ -rgy_caption.cpp rgy_chapter.cpp \ +rgy_chapter.cpp \ rgy_cmd.cpp rgy_codepage.cpp rgy_def.cpp rgy_device.cpp \ rgy_env.cpp rgy_err.cpp rgy_event.cpp \ rgy_faw.cpp rgy_faw_avx2.cpp rgy_faw_avx512bw.cpp \