From 11db9df511bc2a60603e7c48a109f49015f3d890 Mon Sep 17 00:00:00 2001 From: amate Date: Sat, 7 Mar 2020 11:57:21 +0900 Subject: [PATCH] =?UTF-8?q?=E3=83=BB[fix]=20IPC=E6=9C=89=E5=8A=B9=E6=99=82?= =?UTF-8?q?=E3=80=81=E3=83=97=E3=83=A9=E3=82=B0=E3=82=A4=E3=83=B3=E3=81=AE?= =?UTF-8?q?=E7=B5=82=E4=BA=86=E6=99=82=E3=81=ABInputPipeMain.exe=E3=82=92?= =?UTF-8?q?=E3=81=BE=E3=81=A8=E3=82=82=E3=81=AB=E7=B5=82=E4=BA=86=E3=81=95?= =?UTF-8?q?=E3=81=9B=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=E3=81=97=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ・[change] lwinput.auiの各種関数呼び出しにラッパーを噛ませた (例外も握り潰すようにしたので多少落ちなくなったはず) ・[add] 設定の保存に失敗した場合、メッセージボックスを表示するようにした (AviUtlフォルダを [Program Files]や[Program Files (x86)]フォルダ内に置かないでください) ・[fix] IPC有効時、名前付きパイプの準備やInputPipeMain.exeの起動に失敗した場合、IPCを無効化して動作させるようにした ・[fix] ConnectNamedPipeの呼び出しが、タイミングによって失敗することがあるのを修正 ・[fix] 音声が存在しない動画ファイル読み込み時、iip->audio_formatが無効なアドレスを指していたのを修正 ・[misc] 使用していないソースコードの削除や INPUT_INFO周りの処理を共通化 ・[change] 名前付きパイプのバッファサイズを増加させた (512->4096) --- InputPipeMain/InputPipeMain.cpp | 50 ++--- InputPipeMain/InputPipeMain.vcxproj | 6 +- InputPipeMain/InputPipeMain.vcxproj.filters | 6 + InputPipeMain/MainDlg.cpp | 10 +- InputPipePlugin/InputPipePlugin.vcxproj | 5 + .../InputPipePlugin.vcxproj.filters | 6 + InputPipePlugin/input.cpp | 184 ++++++------------ Readme.md | 176 +++++++++++++++++ Readme.txt | 154 --------------- Share/Common.cpp | 74 +++++++ Share/Common.h | 14 +- Share/IPC.cpp | 31 +-- Share/IPC.h | 2 +- Share/PluginWrapper.cpp | 100 ++++++++++ Share/PluginWrapper.h | 14 ++ 15 files changed, 486 insertions(+), 346 deletions(-) create mode 100644 Readme.md delete mode 120000 Readme.txt create mode 100644 Share/PluginWrapper.cpp create mode 100644 Share/PluginWrapper.h diff --git a/InputPipeMain/InputPipeMain.cpp b/InputPipeMain/InputPipeMain.cpp index 83204a2..6d7d5e2 100644 --- a/InputPipeMain/InputPipeMain.cpp +++ b/InputPipeMain/InputPipeMain.cpp @@ -10,6 +10,7 @@ #include "..\Share\IPC.h" //#include "..\Share\Logger.h" #include "..\Share\Common.h" +#include "..\Share\PluginWrapper.h" #include "..\InputPipePlugin\input.h" #include "MainDlg.h" @@ -158,7 +159,8 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, // for Debug CallFunc lastCallFunc; - for (;;) { + bool activeLoop = true; + while (activeLoop) { std::vector readData = namedPipe.Read(kToWindDataHeaderSize); if (readData.size() == 0) { assert(false); @@ -172,7 +174,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, case CallFunc::kOpen: { LPSTR file = (LPSTR)dataBody.data(); - INPUT_HANDLE ih = g_winputPluginTable->func_open(file); + INPUT_HANDLE ih = Plugin_func_open(file); //INFO_LOG << L"kOpen: " << ih; auto fromData = GenerateFromInputData(CallFunc::kOpen, ih, 0); @@ -184,7 +186,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, case CallFunc::kClose: { StandardParamPack* spp = (StandardParamPack*)dataBody.data(); - BOOL b = g_winputPluginTable->func_close(spp->ih); + BOOL b = Plugin_func_close(spp->ih); //INFO_LOG << L"kClose: " << spp->ih; auto fromData = GenerateFromInputData(CallFunc::kClose, b, 0); @@ -198,21 +200,14 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, StandardParamPack* spp = (StandardParamPack*)dataBody.data(); INPUT_INFO inputInfo = {}; - BOOL b = g_winputPluginTable->func_info_get(spp->ih, &inputInfo); + BOOL b = Plugin_func_info_get(spp->ih, &inputInfo); assert(b); //INFO_LOG << L"kInfoGet: " << spp->ih; if (b) { - int totalInputInfoSize = sizeof(INPUT_INFO) + inputInfo.format_size + inputInfo.audio_format_size; - std::vector entireInputInfo(totalInputInfoSize); - errno_t e = ::memcpy_s(entireInputInfo.data(), totalInputInfoSize, &inputInfo, sizeof(INPUT_INFO)); - e = ::memcpy_s(entireInputInfo.data() + sizeof(INPUT_INFO), - inputInfo.format_size, - inputInfo.format, inputInfo.format_size); - e = ::memcpy_s(entireInputInfo.data() + sizeof(INPUT_INFO) + inputInfo.format_size, - inputInfo.audio_format_size, - inputInfo.audio_format, inputInfo.audio_format_size); - - auto fromData = GenerateFromInputData(CallFunc::kInfoGet, b, entireInputInfo.data(), totalInputInfoSize); + const int totalInputInfoSize = CalcTotalInputInfoSize(&inputInfo); + auto infoGetData = SerializeInputInfo(&inputInfo); + + auto fromData = GenerateFromInputData(CallFunc::kInfoGet, b, infoGetData.get(), totalInputInfoSize); namedPipe.Write((const BYTE*)fromData.get(), FromWinputDataTotalSize(*fromData)); //INFO_LOG << L"Write: " << FromWinputDataTotalSize(*fromData) << L" bytes"; @@ -249,26 +244,8 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, } buf = g_readVideoBuffer.data(); } - INPUT_INFO inputInfo = {}; const int frame = spp->param1; - int readBytes = g_winputPluginTable->func_read_video(spp->ih, spp->param1, buf); - if (readBytes == 0) { - // 画像の取得に失敗したので、前のフレームを取得して目的のフレームの生成を促す - int prevFrame = frame - 1; - if (prevFrame < 0) { - prevFrame = frame + 1; - } - int prevReadBytes = g_winputPluginTable->func_read_video(spp->ih, prevFrame, g_readVideoBuffer.data()); - if (prevReadBytes == 0) { - assert(false); - //ERROR_LOG << L"prevReadBytes == 0"; - } - readBytes = g_winputPluginTable->func_read_video(spp->ih, frame, g_readVideoBuffer.data()); - if (readBytes == 0) { - assert(false); - //ERROR_LOG << L"readBytes == 0 : retry func_read_video failed"; - } - } + int readBytes = Plugin_func_read_video(spp->ih, spp->param1, buf); //INFO_LOG << L"kReadVideo: " << spp->ih; namedPipe.Write((const BYTE*)&toData->header.callFunc, sizeof(toData->header.callFunc)); @@ -314,8 +291,8 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, buf = g_readAudioBuffer.data(); } - int readSample = g_winputPluginTable->func_read_audio(spp->ih, spp->param1, spp->param2, buf); - assert(readSample > 0); + int readSample = Plugin_func_read_audio(spp->ih, spp->param1, spp->param2, buf); + //assert(readSample > 0); //INFO_LOG << L"kReadAudio: " << spp->ih << L" readSample: " << readSample; const int readBufferSize = PerAudioSampleBufferSize * readSample; @@ -350,6 +327,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, { //INFO_LOG << L"kExit"; namedPipe.Disconnect(); + activeLoop = false; } break; diff --git a/InputPipeMain/InputPipeMain.vcxproj b/InputPipeMain/InputPipeMain.vcxproj index 03b35ca..cbc2a09 100644 --- a/InputPipeMain/InputPipeMain.vcxproj +++ b/InputPipeMain/InputPipeMain.vcxproj @@ -91,7 +91,7 @@ Level3 Disabled true - WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + WIN32;INPUT_PIPE_MAIN;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) true MultiThreadedDebug @@ -124,7 +124,7 @@ true true true - WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + WIN32;INPUT_PIPE_MAIN;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) true Speed MultiThreaded @@ -160,6 +160,7 @@ + @@ -174,6 +175,7 @@ true true + diff --git a/InputPipeMain/InputPipeMain.vcxproj.filters b/InputPipeMain/InputPipeMain.vcxproj.filters index a6ddc7e..b27d7f3 100644 --- a/InputPipeMain/InputPipeMain.vcxproj.filters +++ b/InputPipeMain/InputPipeMain.vcxproj.filters @@ -45,6 +45,9 @@ ソース ファイル + + ソース ファイル\Share + @@ -62,6 +65,9 @@ ソース ファイル\Share + + ソース ファイル\Share + diff --git a/InputPipeMain/MainDlg.cpp b/InputPipeMain/MainDlg.cpp index e6be62c..34533b9 100644 --- a/InputPipeMain/MainDlg.cpp +++ b/InputPipeMain/MainDlg.cpp @@ -48,7 +48,15 @@ LRESULT CMainDlg::OnOK(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& / } m_config.bUseSharedMemory = m_radioNamedPipeOrSharedMemory == 1 ? true : false; - m_config.SaveConfig(); + if (!m_config.SaveConfig()) { + CString errorMsg = L"ݒ̕ۑɎs܂B"; + CString exeFolderPath = GetExeDirectory().wstring().c_str(); + exeFolderPath.MakeLower(); + if (exeFolderPath.Find(LR"(\program files (x86)\)") != -1 || exeFolderPath.Find(LR"(\program files\)") != -1) { + errorMsg += L"\nAviUtltH_ [Program Files][Program Files (x86)]tH_ɒuȂł"; + } + MessageBox(errorMsg, L"InputPipeMain - G[", MB_ICONERROR); + } CloseDialog(0); return 0; diff --git a/InputPipePlugin/InputPipePlugin.vcxproj b/InputPipePlugin/InputPipePlugin.vcxproj index 053074d..0b9edd8 100644 --- a/InputPipePlugin/InputPipePlugin.vcxproj +++ b/InputPipePlugin/InputPipePlugin.vcxproj @@ -165,6 +165,7 @@ + @@ -186,6 +187,10 @@ NotUsing NotUsing + + NotUsing + NotUsing + diff --git a/InputPipePlugin/InputPipePlugin.vcxproj.filters b/InputPipePlugin/InputPipePlugin.vcxproj.filters index 66c1bb0..19e0948 100644 --- a/InputPipePlugin/InputPipePlugin.vcxproj.filters +++ b/InputPipePlugin/InputPipePlugin.vcxproj.filters @@ -39,6 +39,9 @@ ソース ファイル\Share + + ソース ファイル\Share + @@ -62,6 +65,9 @@ ソース ファイル\Share + + ソース ファイル\Share + diff --git a/InputPipePlugin/input.cpp b/InputPipePlugin/input.cpp index 47084f9..c209529 100644 --- a/InputPipePlugin/input.cpp +++ b/InputPipePlugin/input.cpp @@ -24,6 +24,7 @@ #include "..\Share\IPC.h" #include "..\Share\Common.h" #include "..\Share\CodeConvert.h" +#include "..\Share\PluginWrapper.h" extern HMODULE g_hModule; HMODULE g_hWinputDll = NULL; @@ -63,9 +64,17 @@ std::string LogFileName() } -//#define NO_REMOTE //#define DEBUG_PROCESSINGTIME +void DisconnectPipeAndStopProcess() +{ + StandardParamPack spp = {}; + auto toData = GenerateToInputData(CallFunc::kExit, spp); + g_namedPipe.Write((const BYTE*)toData.get(), ToWinputDataTotalSize(*toData)); + + g_namedPipe.Disconnect(); + g_bindProcess.StopProcess(); +} //--------------------------------------------------------------------- // 入力プラグイン構造体定義 @@ -160,7 +169,13 @@ BOOL func_init( void ) randamString += L"_"; std::wstring pipeName = std::wstring(kPipeName) + randamString; bool ret = g_namedPipe.CreateNamedPipe(pipeName); - // INFO_LOG << L"CreateNamedPipe: " << pipeName << L" ret: " << ret; + INFO_LOG << L"CreateNamedPipe: " << pipeName << L" ret: " << ret; + if (!ret) { + ERROR_LOG << L"CreateNamedPipe failed - GetLastError: " << GetLastErrorString(); + WARN_LOG << L"エラーが発生したのでIPCを無効化します"; + m_config.bEnableIPC = false; + return TRUE; + } auto InputPipeMainPath = GetExeDirectory() / L"InputPipeMain.exe"; @@ -171,16 +186,22 @@ BOOL func_init( void ) } bool startRet = g_bindProcess.StartProcess(InputPipeMainPath.native(), commandLine); // INFO_LOG << L"StartProcess: " << L" ret: " << startRet; + if (!startRet) { + ERROR_LOG << L"g_bindProcess.StartProcess(InputPipeMainPath failed - GetLastError: " << GetLastErrorString(); + WARN_LOG << L"エラーが発生したのでIPCを無効化します"; + DisconnectPipeAndStopProcess(); + m_config.bEnableIPC = false; + return TRUE; + } if (!g_namedPipe.ConnectNamedPipe()) { - ERROR_LOG << L"ConnectNamedPipe failed"; - MessageBox(NULL, L"名前付きパイプへの接続が失敗しました", L"InputPipePluginエラー", MB_ICONERROR); - return FALSE; + ERROR_LOG << L"ConnectNamedPipe failed - GetLastError: " << GetLastErrorString(); + WARN_LOG << L"エラーが発生したのでIPCを無効化します"; + DisconnectPipeAndStopProcess(); + m_config.bEnableIPC = false; + return TRUE; } } - //BOOL b = g_winputPluginTable->func_init(); - //return b; - return TRUE; } @@ -200,12 +221,8 @@ BOOL func_exit( void ) g_videoSharedMemory.CloseHandle(); g_audioSharedMemory.CloseHandle(); - g_namedPipe.Disconnect(); - g_bindProcess.StopProcess(); + DisconnectPipeAndStopProcess(); } - //BOOL b = g_winputPluginTable->func_exit(); - //return b; - return TRUE; } @@ -223,7 +240,6 @@ INPUT_HANDLE func_open( LPSTR file ) std::lock_guard lock(g_mtxIPC); -#ifndef NO_REMOTE if (m_config.bEnableHandleCache) { std::string fileName = file; auto itfound = std::find_if(g_vecHandleCache.begin(), g_vecHandleCache.end(), @@ -232,7 +248,7 @@ INPUT_HANDLE func_open( LPSTR file ) }); if (itfound != g_vecHandleCache.end()) { int& refCount = std::get(*itfound); - INFO_LOG << L"Cache found : " << refCount << L" -> " << (refCount + 1); + INFO_LOG << L" Cache found : " << refCount << L" -> " << (refCount + 1); ++refCount; return std::get(*itfound); } @@ -261,16 +277,13 @@ INPUT_HANDLE func_open( LPSTR file ) } return ih2; } else { - INPUT_HANDLE ih = g_winputPluginTable->func_open(file); + + INPUT_HANDLE ih = Plugin_func_open(file); if (m_config.bEnableHandleCache) { g_vecHandleCache.emplace_back(std::string(file), ih, 1); } return ih; } -#else - INPUT_HANDLE ih = g_winputPluginTable->func_open(file); - return ih; -#endif } @@ -281,7 +294,7 @@ BOOL func_close( INPUT_HANDLE ih ) { INFO_LOG << L"func_close: " << ih; std::lock_guard lock(g_mtxIPC); -#ifndef NO_REMOTE + if (m_config.bEnableHandleCache) { auto itfound = std::find_if(g_vecHandleCache.begin(), g_vecHandleCache.end(), [ih](const HandleCache& handleCache) { @@ -289,16 +302,16 @@ BOOL func_close( INPUT_HANDLE ih ) }); assert(itfound != g_vecHandleCache.end()); if (itfound == g_vecHandleCache.end()) { - ERROR_LOG << L"func_close g_vecFileInputHandle.erase failed: " << ih; + ERROR_LOG << L" func_close g_vecFileInputHandle.erase failed: " << ih; } else { int& refCount = std::get(*itfound); - INFO_LOG << L"Cache refCount : " << refCount << L" -> " << (refCount - 1); + INFO_LOG << L" Cache refCount : " << refCount << L" -> " << (refCount - 1); --refCount; if (refCount > 0) { return TRUE; // まだ消さない! } else { - INFO_LOG << L"Cache delete: " << ih; + INFO_LOG << L" Cache delete: " << ih; g_vecHandleCache.erase(itfound); } } @@ -323,13 +336,9 @@ BOOL func_close( INPUT_HANDLE ih ) g_mapFrameBufferSize.erase(ih); return retData.first; } else { - BOOL b = g_winputPluginTable->func_close(ih); + BOOL b = Plugin_func_close(ih); return b; } -#else - BOOL b = g_winputPluginTable->func_close(ih); - return b; -#endif } @@ -340,11 +349,10 @@ BOOL func_info_get( INPUT_HANDLE ih,INPUT_INFO *iip ) { INFO_LOG << L"func_info_get"; std::lock_guard lock(g_mtxIPC); -#ifndef NO_REMOTE auto itfound = g_mapInputHandleInfoGetData.find(ih); if (itfound != g_mapInputHandleInfoGetData.end()) { - INFO_LOG << L"InfoGetData cache found!"; + INFO_LOG << L" InfoGetData cache found!"; *iip = *reinterpret_cast(itfound->second.get()); return TRUE; } @@ -355,57 +363,39 @@ BOOL func_info_get( INPUT_HANDLE ih,INPUT_INFO *iip ) std::vector headerData = g_namedPipe.Read(kFromWinputDataHeaderSize); FromWinputData* fromData = (FromWinputData*)headerData.data(); - INFO_LOG << L"Read: " << fromData->returnSize << L" bytes"; + //INFO_LOG << L"Read: " << fromData->returnSize << L" bytes"; assert(fromData->callFunc == CallFunc::kInfoGet); std::vector readBody = g_namedPipe.Read(fromData->returnSize); auto retData = ParseFromInputData(readBody); if (retData.first) { - auto tempInputInfo = (INPUT_INFO*)retData.second; - const int infoGetDataSize = sizeof(INPUT_INFO) + tempInputInfo->format_size + tempInputInfo->audio_format_size; - auto infoGetData = std::make_unique(infoGetDataSize); - memcpy_s(infoGetData.get(), infoGetDataSize, tempInputInfo, infoGetDataSize); - - auto igData = reinterpret_cast(infoGetData.get()); - igData->format = (BITMAPINFOHEADER*)(infoGetData.get() + sizeof(INPUT_INFO)); - igData->audio_format = (WAVEFORMATEX*)(infoGetData.get() + sizeof(INPUT_INFO) + igData->format_size); - *iip = *igData; + auto infoGetData = DeserializeInputInfo(retData.second, iip); g_mapInputHandleInfoGetData.emplace(ih, std::move(infoGetData)); - const int OneFrameBufferSize = iip->format->biWidth * iip->format->biHeight * (iip->format->biBitCount / 8); - const int PerAudioSampleBufferSize = iip->audio_format->nChannels * (iip->audio_format->wBitsPerSample / 8); + int OneFrameBufferSize = 0; + if (iip->format_size > 0) { + OneFrameBufferSize = iip->format->biWidth* iip->format->biHeight* (iip->format->biBitCount / 8); + } + int PerAudioSampleBufferSize = 0; + if (iip->audio_format_size > 0) { + PerAudioSampleBufferSize = iip->audio_format->nChannels* (iip->audio_format->wBitsPerSample / 8); + } g_mapFrameBufferSize.emplace(ih, FrameAudioVideoBufferSize{ OneFrameBufferSize , PerAudioSampleBufferSize }); - INFO_LOG << L"OneFrameBufferSize: " << OneFrameBufferSize << L" PerAudioSampleBufferSize: " << PerAudioSampleBufferSize; + INFO_LOG << L" OneFrameBufferSize: " << OneFrameBufferSize << L" PerAudioSampleBufferSize: " << PerAudioSampleBufferSize; } else { - ERROR_LOG << L"func_info_get failed, ih: " << ih; + ERROR_LOG << L" func_info_get failed, ih: " << ih; } return retData.first; } else { - BOOL b = g_winputPluginTable->func_info_get(ih, iip); + BOOL b = Plugin_func_info_get(ih, iip); if (b) { - const int infoGetDataSize = sizeof(INPUT_INFO) + iip->format_size + iip->audio_format_size; - auto infoGetData = std::make_unique(infoGetDataSize); - memcpy_s(infoGetData.get(), infoGetDataSize, iip, sizeof(INPUT_INFO)); - - auto igData = reinterpret_cast(infoGetData.get()); - ::memcpy_s(infoGetData.get() + sizeof(INPUT_INFO), - igData->format_size, - igData->format, igData->format_size); - ::memcpy_s(infoGetData.get() + sizeof(INPUT_INFO) + igData->format_size, - igData->audio_format_size, - igData->audio_format, igData->audio_format_size); - igData->format = (BITMAPINFOHEADER*)(infoGetData.get() + sizeof(INPUT_INFO)); - igData->audio_format = (WAVEFORMATEX*)(infoGetData.get() + sizeof(INPUT_INFO) + igData->format_size); + auto infoGetData = SerializeInputInfo(iip); g_mapInputHandleInfoGetData.emplace(ih, std::move(infoGetData)); } return b; } -#else - BOOL b = g_winputPluginTable->func_info_get(ih, iip); - return b; -#endif } //--------------------------------------------------------------------- @@ -420,7 +410,6 @@ int func_read_video( INPUT_HANDLE ih,int frame,void *buf ) auto startTime = std::chrono::high_resolution_clock::now(); #endif -#ifndef NO_REMOTE if (m_config.bEnableIPC) { const int OneFrameBufferSize = g_mapFrameBufferSize[ih].OneFrameBufferSize; @@ -486,24 +475,8 @@ int func_read_video( INPUT_HANDLE ih,int frame,void *buf ) return readBytes; } else { - int readBytes = g_winputPluginTable->func_read_video(ih, frame, buf); - if (readBytes == 0) { - // 画像の取得に失敗したので、前のフレームを取得して目的のフレームの生成を促す - int prevFrame = frame - 1; - if (prevFrame < 0) { - prevFrame = frame + 1; - } - int prevReadBytes = g_winputPluginTable->func_read_video(ih, prevFrame, buf); - if (prevReadBytes == 0) { - assert(false); - //ERROR_LOG << L"prevReadBytes == 0"; - } - readBytes = g_winputPluginTable->func_read_video(ih, frame, buf); - if (readBytes == 0) { - assert(false); - ERROR_LOG << L"readBytes == 0 : retry func_read_video failed"; - } - } + + int readBytes = Plugin_func_read_video(ih, frame, buf); #ifdef DEBUG_PROCESSINGTIME // 処理時間計測 auto processingTime = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - startTime).count(); @@ -529,10 +502,7 @@ int func_read_video( INPUT_HANDLE ih,int frame,void *buf ) #endif return readBytes; } -#else - int n = g_winputPluginTable->func_read_video(ih, frame, buf); - return n; -#endif + } #undef DEBUG_PROCESSINGTIME @@ -549,7 +519,6 @@ int func_read_audio(INPUT_HANDLE ih, int start, int length, void* buf) auto startTime = std::chrono::high_resolution_clock::now(); #endif -#ifndef NO_REMOTE if (m_config.bEnableIPC) { const int PerAudioSampleBufferSize = g_mapFrameBufferSize[ih].PerAudioSampleBufferSize; @@ -614,7 +583,7 @@ int func_read_audio(INPUT_HANDLE ih, int start, int length, void* buf) #endif return readSample; } else { - int n = g_winputPluginTable->func_read_audio(ih, start, length, buf); + int n = Plugin_func_read_audio(ih, start, length, buf); #ifdef DEBUG_PROCESSINGTIME // 処理時間計測 auto processingTime = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - startTime).count(); static bool firstSkip = true; @@ -639,28 +608,6 @@ int func_read_audio(INPUT_HANDLE ih, int start, int length, void* buf) #endif return n; } -#if 0 - std::vector readBody = g_namedPipe.Read(fromData->returnSize); - auto retData = ParseFromInputData(readBody); - const int requestReadBytes = PerAudioSampleBufferSize * length; - ::memcpy_s(buf, requestReadBytes, retData.second, requestReadBytes); - - return retData.first; -#endif -#else - - int n = g_winputPluginTable->func_read_audio(ih, start, length, buf); - return n; -#endif -#if 0 - FILE_HANDLE * fp = (FILE_HANDLE*)ih; - LONG size; - int samplesize; - - samplesize = ((WAVEFORMATEX*)fp->audioformat)->nBlockAlign; - if (AVIStreamRead(fp->paudio, start, length, buf, samplesize * length, NULL, &size)) return 0; - return size; -#endif } @@ -672,7 +619,6 @@ BOOL func_is_keyframe(INPUT_HANDLE ih, int frame) // INFO_LOG << L"func_is_keyframe" << L" frame:" << frame; std::lock_guard lock(g_mtxIPC); -#ifndef NO_REMOTE if (m_config.bEnableIPC) { StandardParamPack spp = { ih, frame }; auto toData = GenerateToInputData(CallFunc::kIsKeyframe, spp); @@ -688,15 +634,6 @@ BOOL func_is_keyframe(INPUT_HANDLE ih, int frame) BOOL b = g_winputPluginTable->func_is_keyframe(ih, frame); return b; } -#else - BOOL b = g_winputPluginTable->func_is_keyframe(ih, frame); - return b; -#endif -#if 0 - FILE_HANDLE *fp = (FILE_HANDLE *)ih; - - return AVIStreamIsKeyFrame(fp->pvideo,frame); -#endif } @@ -715,13 +652,6 @@ BOOL func_config( HWND hwnd, HINSTANCE dll_hinst ) BOOL b = g_winputPluginTable->func_config(hwnd, dll_hinst); return b; #endif -#if 0 - MessageBoxA(hwnd,"サンプルダイアログ","入力設定",MB_OK); - - // DLLを開放されても設定が残るように保存しておいてください。 - - return TRUE; -#endif } diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..9baa613 --- /dev/null +++ b/Readme.md @@ -0,0 +1,176 @@ +# InputPipePlugin             + +## ■はじめに +このソフトは、L-SMASH_Works File Reader(lwinput.aui)を別プロセスで実行してあげることによって +aviutlのメモリ使用量削減を目論む、aviutlの入力プラグインです + +## ■動作環境 +・Windows 10 home 64bit バージョン 1903 +・AviUtl 1.00 or 1.10 +・拡張編集 0.92 +※ 拡張編集 0.93rc1 はシーン周りに不具合があるので推奨しません +・L-SMASH Works r935 release2 +上記の環境で動作を確認しています +XPではたぶん動きません(コンパイラが対応していないため) + +## ■導入方法 +lwinput.aui が置いてあるフォルダ(aviutl.exeがあるフォルダ、もしくは "aviutl.exeがあるフォルダ\plugins\"に存在するはず)に、 +InputPipePlugin.aui と InputPipeMain.exe をコピーするだけです + +その後、aviutlのメインメニューから、[ファイル]->[環境設定]->[入力プラグイン優先度の設定]を選択し、 +"InputPipePlugin"を"L-SMASH Works File Reader"より上にドラッグして移動してあげれば完了です + +## ■導入の確認 +拡張編集のウィンドウに適当に動画ファイルを放り込んで、"InputPipeMain.exe"のプロセスが立ち上がっていれば成功です + +- 導入が確認できない +入力プラグイン優先度で、"DirectShow File Reader"がInputPipePluginより上に存在すると動作しないので、InputPipePluginをそれより上に移動させてください + +- aviutlが落ちる +"InputPipePlugin.aui"と"InputPipeMain.exe"が"lwinput.aui"と同じフォルダに存在するか確認してください +"InputPipeMain.exe"を起動してみて、"lwinput.aui が同じフォルダに存在しています!"と表示されれば大丈夫です +もしくは、[InputPipePluginの設定]から[プロセス間通信を有効にする]のチェックを外してください + +## ■設定 +[ファイル]->[環境設定]->[入力プラグインの設定]->[InputPipePluginの設定]で +プラグインの設定ができます + +- 〇ハンドルキャッシュを有効 +動画では説明しませんでしたが、編集で同じ動画ファイルのカットを多用するなどの場合、 +拡張編集プラグインが同じ動画に対して毎回ファイルオープンのリクエストを送ってくるので、 +いちいちL-SMASH Worksプラグインへ ファイルオープンのリクエストを送らずに、 +一度開いたファイルのハンドルを使いまわすようにする設定です + +ぶっちゃけ外部プロセスなんて使わずに、これにチェック入れるだけでいいんじゃないかなって +実装した後に気づきました +でも、無駄にはなってないはずです… + +- 〇プロセス間通信を有効にする +デフォルトではオンになってます +外部プロセスを立ち上げて、その中でlwinput.auiを実行するようにします + +外部プロセスとの通信はコストがかかるので、重いと感じたらチェック外してください + +- 内部のデータ交換方式 + * 名前付きパイプ + v1.4以前の方式です + + * 共有メモリ + v1.5から実装された方式です + 予めデータ用のメモリを確保しておくので、こちらの方が少し高速です + +設定の保存に失敗するので、AviUtlのフォルダを [C:\Program Files]や[C:\Program Files (x86)]フォルダ内に置かないでください + +## ■プラグインを入れて不安定になった場合 +- 拡張編集の環境設定から、動画ファイルのハンドル数を8から16程度に増やしてみてください +- InputPipePluginの設定から[プロセス間通信を有効にする]のチェックを外してみてください +- 入力プラグインの優先度設定で、"Wave File Reader"を"InputPipePlugin"より上に移動させてみてください +- 動画ファイルがmp4の場合、コンテナをmkvに変更してみるとか(※実験的なもので効果は出ないかも…) + +## ■アンインストールの方法 +AviUtlのフォルダにコピーした +InputPipePlugin.aui と +InputPipeMain.exe と +InputPipePluginConfig.ini を削除してください + +## ■免責 +作者(原著者&改変者)は、このソフトによって生じた如何なる損害にも、 +修正や更新も、責任を負わないこととします。 +使用にあたっては、自己責任でお願いします。 + +何かあれば下記のURLにあるメールフォームにお願いします。 +https://ws.formzu.net/fgen/S37403840/ + +## ■著作権表示 +Copyright (C) 2019-2020 amate + +私が書いた部分のソースコードは、MIT License とします。 + +## ■謝辞 +aviutlの作者様、L-SMASH Worksの作者様 +あなた方の活躍のおかげで、素晴らしい動画がたくさん生まれていることに感謝いたします +ありがとう! + +## ■誰かの役に立つかもしれない情報 + +- 〇GeForce Experience(ShadowPlay)で録画したファイルを編集しようとしたら音ズレしてる! +動画プレイヤーで再生したときは音ズレしていないのに、aviutlで編集しようとしたらなぜか音ズレしてしまっている場合、 +→Avidemuxを使ってコンテナをmkvに変更する +AvidemuxのVideo OutputとAudio OutputをCopyに、Output FormatをMkv Muxerに変更して +ファイルを読み込んだ後、Saveで出力する +出来上がったmkvファイルを読み込むとなぜか音ズレしていない + +- 〇OBS Studioで録画したファイルのシークが死ぬほど遅い! +→Avidemuxを使ってコンテナをmkvに変更する +上記の手順を実行 +なぜかシークが軽くなっている + +- 〇Detected CTS duplication at frame XXX ってダイアログが出る! +→Avidemuxを使ってコンテナをmkvに変更する +以下略 + +コンテナを変更するだけでなぜ直るのかは謎 + +## ■ビルドについて +Visual Studio 2019 が必要です +ビルドには boost(1.70~)とWTL(10_9163) が必要なのでそれぞれ用意してください。 + +Boost::Logを使用しているので、事前にライブラリのビルドが必要になります + +Boostライブラリのビルド方法 +https://boostjp.github.io/howtobuild.html +//コマンドライン +b2.exe install -j 16 --prefix=lib toolset=msvc-14.2 runtime-link=static --with-log --with-filesystem + +◆boost +http://www.boost.org/ + +◆WTL +http://sourceforge.net/projects/wtl/ + + +## ■更新履歴 +
+v1.7
+・[fix] IPC有効時、プラグインの終了時にInputPipeMain.exeをまともに終了させるようにした
+・[change] lwinput.auiの各種関数呼び出しにラッパーを噛ませた (例外も握り潰すようにしたので多少落ちなくなったはず)
+・[add] 設定の保存に失敗した場合、メッセージボックスを表示するようにした (AviUtlフォルダを [Program Files]や[Program Files (x86)]フォルダ内に置かないでください)
+・[fix] IPC有効時、名前付きパイプの準備やInputPipeMain.exeの起動に失敗した場合、IPCを無効化して動作させるようにした
+・[fix] ConnectNamedPipeの呼び出しが、タイミングによって失敗することがあるのを修正 
+・[fix] 音声が存在しない動画ファイル読み込み時、iip->audio_formatが無効なアドレスを指していたのを修正
+・[misc] 使用していないソースコードの削除や INPUT_INFO周りの処理を共通化
+・[change] 名前付きパイプのバッファサイズを増加させた (512->4096)
+
+v1.6
+・[change]設定で内部データの交換方式を選択できるようにした(デフォルトを名前付きパイプへ変更)
+共有メモリだと落ちる場合があるらしいが、再現しないのでエラーが起こりそうな場所にメッセージボックスを埋め込んどいた
+・[fix]InputPipeMain.exeがboost::logに依存しないようにした
+アンチウィルスがうるさいらしいのでその対策
+
+v1.5
+・[fix] aviutl起動時に、InputPipePlugin.auiと同じフォルダに lwinput.aui が存在しない場合プロセスが強制終了するのを修正
+・[add] aviutl起動時に、InputPipePlugin.auiと同じフォルダに lwinput.aui が存在しない場合メッセージボックスを表示するようにした
+・[change] プロセス間通信有効時、画像と音声の転送に共有メモリを使用するようにした (6割ほど高速化した)
+・[change] boostを1.72.0へ更新
+・[chagen] std::filesystemからboost::filesystemへ使用ライブラリを変更
+
+v1.4
+・[change]プロセス間通信有効、func_read_videoで画像の取得に失敗した場合の処理をInputPipePlugin.auiではなく、InputPipeMain.exeで実行するようにした
+・[add]プロセス間通信無効時でも、func_info_getでキャッシュ情報を返すようにした
+
+v1.3
+・[fix] func_read_videoで画像の取得に失敗した場合、一度前のフレームを取得してから目的のフレームを取得するようにした [緑の画面が出る対策](ワークアラウンドっぽいがとりあえず動く)
+
+v1.2
+・[fix] CreateNamedPipeでPIPE_TYPE_MESSAGEのままだったのを修正
+・[add] NamedPipe::Read failed 時に、GetLastErrorの内容を書き込むようにした(上の修正でもう書き込まれないはず…)
+
+v1.1
+・[fix] IPC有効時、外部プロセスとの通信にコケるのを修正(マルチスレッドで各種関数が実行されることがあるようなので、排他制御を入れた)
+・[change] 名前付きパイプの設定を、バイトストリームモードへ変更(上のバグのせいで変なことしてた)
+・[fix] 外部プロセスにて、func_info_getが失敗することを考慮に入れてなかったのを修正
+・[change] 名前付きパイプの名前をランダムに変更するようにした
+
+v1.0
+・完成
+
\ No newline at end of file diff --git a/Readme.txt b/Readme.txt deleted file mode 120000 index eb9cdaa..0000000 --- a/Readme.txt +++ /dev/null @@ -1,154 +0,0 @@ -/* =================================== -       InputPipePlugin             - ==================================== */ - -■はじめに -このソフトは、L-SMASH_Works File Reader(lwinput.aui)を別プロセスで実行してあげることによって -aviutlのメモリ使用量削減を目論む、aviutlの入力プラグインです - -■動作環境 -・Windows 10 home 64bit バージョン 1903 -・AviUtl 1.00 or 1.10 -・拡張編集 0.92 -※ 拡張編集 0.93rc1 はシーン周りに不具合があるので推奨しません -・L-SMASH Works r935 release2 -上記の環境で動作を確認しています -XPではたぶん動きません(コンパイラが対応していないため) - -■導入方法 -lwinput.aui が置いてあるフォルダ(aviutl.exeがあるフォルダ、もしくは "aviutl.exeがあるフォルダ\plugins\"に存在するはず)に、 -InputPipePlugin.aui と InputPipeMain.exe をコピーするだけです - -その後、aviutlのメインメニューから、[ファイル]->[環境設定]->[入力プラグイン優先度の設定]を選択し、 -"InputPipePlugin"を"L-SMASH Works File Reader"より上にドラッグして移動してあげれば完了です - -■導入の確認 -拡張編集のウィンドウに適当に動画ファイルを放り込んで、"InputPipeMain.exe"のプロセスが立ち上がっていれば成功です - -・導入が確認できない -入力プラグイン優先度で、"DirectShow File Reader"がInputPipePluginより上に存在すると動作しないので、InputPipePluginをそれより上に移動させてください - -・aviutlが落ちる -"InputPipePlugin.aui"と"InputPipeMain.exe"が"lwinput.aui"と同じフォルダに存在するか確認してください -"InputPipeMain.exe"を起動してみて、"lwinput.aui が同じフォルダに存在しています!"と表示されれば大丈夫です - -■設定 -[ファイル]->[環境設定]->[入力プラグインの設定]->[InputPipePluginの設定]で -プラグインの設定ができます - -〇ハンドルキャッシュを有効 -動画では説明しませんでしたが、編集で同じ動画ファイルのカットを多用するなどの場合、 -拡張編集プラグインが同じ動画に対して毎回ファイルオープンのリクエストを送ってくるので、 -いちいちL-SMASH Worksプラグインへ ファイルオープンのリクエストを送らずに、 -一度開いたファイルのハンドルを使いまわすようにする設定です - -ぶっちゃけ外部プロセスなんて使わずに、これにチェック入れるだけでいいんじゃないかなって -実装した後に気づきました -でも、無駄にはなってないはずです… - -〇プロセス間通信を有効にする -デフォルトではオンになってます -外部プロセスを立ち上げて、その中でlwinput.auiを実行するようにします - -外部プロセスとの通信はコストがかかるので、重いと感じたらチェック外してください - -■プラグインを入れて不安定になった場合 -・拡張編集の環境設定から、動画ファイルのハンドル数を8から16程度に増やしてみてください -・InputPipePluginの設定から[プロセス間通信を有効にする]のチェックを外してみてください -・入力プラグインの優先度設定で、"Wave File Reader"を"InputPipePlugin"より上に移動させてみてください -・動画ファイルがmp4の場合、コンテナをmkvに変更してみるとか(※実験的なもので効果は出ないかも…) - -■アンインストールの方法 -InputPipePlugin.aui と -InputPipeMain.exe と -InputPipePluginConfig.ini を削除してください - -■免責 -作者(原著者&改変者)は、このソフトによって生じた如何なる損害にも、 -修正や更新も、責任を負わないこととします。 -使用にあたっては、自己責任でお願いします。 - -何かあれば下記のURLにあるメールフォームにお願いします。 -https://ws.formzu.net/fgen/S37403840/ - -■著作権表示 -Copyright (C) 2019-2020 amate - -私が書いた部分のソースコードは、MIT License とします。 - -■謝辞 -aviutlの作者様、L-SMASH Worksの作者様 -あなた方の活躍のおかげで、素晴らしい動画がたくさん生まれていることに感謝いたします -ありがとう! - -■誰かの役に立つかもしれない情報 - -〇GeForce Experience(ShadowPlay)で録画したファイルを編集しようとしたら音ズレしてる! -動画プレイヤーで再生したときは音ズレしていないのに、aviutlで編集しようとしたらなぜか音ズレしてしまっている場合、 -→Avidemuxを使ってコンテナをmkvに変更する -AvidemuxのVideo OutputとAudio OutputをCopyに、Output FormatをMkv Muxerに変更して -ファイルを読み込んだ後、Saveで出力する -出来上がったmkvファイルを読み込むとなぜか音ズレしていない - -〇OBS Studioで録画したファイルのシークが死ぬほど遅い! -→Avidemuxを使ってコンテナをmkvに変更する -上記の手順を実行 -なぜかシークが軽くなっている - -〇Detected CTS duplication at frame XXX ってダイアログが出る! -→Avidemuxを使ってコンテナをmkvに変更する -以下略 - -コンテナを変更するだけでなぜ直るのかは謎 - -■ビルドについて -Visual Studio 2019 が必要です -ビルドには boost(1.70~)とWTL(10_9163) が必要なのでそれぞれ用意してください。 - -Boost::Logを使用しているので、事前にライブラリのビルドが必要になります - -Boostライブラリのビルド方法 -https://boostjp.github.io/howtobuild.html -//コマンドライン -b2.exe install -j 16 --prefix=lib toolset=msvc-14.2 runtime-link=static --with-log --with-filesystem - -◆boost -http://www.boost.org/ - -◆WTL -http://sourceforge.net/projects/wtl/ - - -■更新履歴 -v1.6 -・[change]設定で内部データの交換方式を選択できるようにした(デフォルトを名前付きパイプへ変更) -共有メモリだと落ちる場合があるらしいが、再現しないのでエラーが起こりそうな場所にメッセージボックスを埋め込んどいた -・[fix]InputPipeMain.exeがboost::logに依存しないようにした -アンチウィルスがうるさいらしいのでその対策 - -v1.5 -・[fix] aviutl起動時に、InputPipePlugin.auiと同じフォルダに lwinput.aui が存在しない場合プロセスが強制終了するのを修正 -・[add] aviutl起動時に、InputPipePlugin.auiと同じフォルダに lwinput.aui が存在しない場合メッセージボックスを表示するようにした -・[change] プロセス間通信有効時、画像と音声の転送に共有メモリを使用するようにした (6割ほど高速化した) -・[change] boostを1.72.0へ更新 -・[chagen] std::filesystemからboost::filesystemへ使用ライブラリを変更 - -v1.4 -・[change]プロセス間通信有効、func_read_videoで画像の取得に失敗した場合の処理をInputPipePlugin.auiではなく、InputPipeMain.exeで実行するようにした -・[add]プロセス間通信無効時でも、func_info_getでキャッシュ情報を返すようにした - -v1.3 -・[fix] func_read_videoで画像の取得に失敗した場合、一度前のフレームを取得してから目的のフレームを取得するようにした [緑の画面が出る対策](ワークアラウンドっぽいがとりあえず動く) - -v1.2 -・[fix] CreateNamedPipeでPIPE_TYPE_MESSAGEのままだったのを修正 -・[add] NamedPipe::Read failed 時に、GetLastErrorの内容を書き込むようにした(上の修正でもう書き込まれないはず…) - -v1.1 -・[fix] IPC有効時、外部プロセスとの通信にコケるのを修正(マルチスレッドで各種関数が実行されることがあるようなので、排他制御を入れた) -・[change] 名前付きパイプの設定を、バイトストリームモードへ変更(上のバグのせいで変なことしてた) -・[fix] 外部プロセスにて、func_info_getが失敗することを考慮に入れてなかったのを修正 -・[change] 名前付きパイプの名前をランダムに変更するようにした - -v1.0 -・完成 diff --git a/Share/Common.cpp b/Share/Common.cpp index e39cb48..4d97a44 100644 --- a/Share/Common.cpp +++ b/Share/Common.cpp @@ -10,6 +10,80 @@ fs::path GetExeDirectory() return exeFolder.parent_path(); } +std::wstring GetLastErrorString(DWORD errorcode) +{ + LPVOID lpMsgBuf; + DWORD ret = ::FormatMessageW( + FORMAT_MESSAGE_ALLOCATE_BUFFER // eLXg̃蓖Ăv + | FORMAT_MESSAGE_FROM_SYSTEM // G[bZ[WWindowspӂĂ̂gp + | FORMAT_MESSAGE_IGNORE_INSERTS,// ̈𖳎ăG[R[hɑ΂G[bZ[W쐬 + NULL, errorcode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),// w + (LPTSTR)&lpMsgBuf, // bZ[WeLXgۑobt@ւ̃|C^ + 0, + NULL); + if (ret == 0) { + return L""; + } + + std::wstring errorMsg = (LPCWSTR)lpMsgBuf; + ::LocalFree(lpMsgBuf); + return errorMsg; +} + +//////////////////////////////////////////////////////////////// + + +std::unique_ptr SerializeInputInfo(INPUT_INFO* iip) +{ + const int infoGetDataSize = CalcTotalInputInfoSize(iip); + auto infoGetData = std::make_unique(infoGetDataSize); + // INPUT_INFO Rs[ + memcpy_s(infoGetData.get(), infoGetDataSize, iip, sizeof(INPUT_INFO)); + auto igData = reinterpret_cast(infoGetData.get()); + + // formataudio_formatꂼ mۂ̌ɃRs[ + ::memcpy_s(infoGetData.get() + sizeof(INPUT_INFO), + iip->format_size, + iip->format, iip->format_size); + ::memcpy_s(infoGetData.get() + sizeof(INPUT_INFO) + iip->format_size, + iip->audio_format_size, + iip->audio_format, iip->audio_format_size); + + // ꂼ̃tH[}bg̎wAmۂݒ + if (igData->format_size > 0) { + igData->format = (BITMAPINFOHEADER*)(infoGetData.get() + sizeof(INPUT_INFO)); + } else { + igData->format = nullptr; + } + if (igData->audio_format_size > 0) { + igData->audio_format = (WAVEFORMATEX*)(infoGetData.get() + sizeof(INPUT_INFO) + igData->format_size); + } else { + igData->audio_format = nullptr; + } + return infoGetData; +} + +std::unique_ptr DeserializeInputInfo(const BYTE* serializedData, INPUT_INFO* iip) +{ + auto tempInputInfo = (INPUT_INFO*)serializedData; + if (tempInputInfo->format_size > 0) { + tempInputInfo->format = (BITMAPINFOHEADER*)(reinterpret_cast(tempInputInfo) + sizeof(INPUT_INFO)); + } else { + tempInputInfo->format = nullptr; + } + if (tempInputInfo->audio_format_size > 0) { + tempInputInfo->audio_format = (WAVEFORMATEX*)(reinterpret_cast(tempInputInfo) + sizeof(INPUT_INFO) + tempInputInfo->format_size); + } else { + tempInputInfo->audio_format = nullptr; + } + + auto infoGetData = SerializeInputInfo(tempInputInfo); + INPUT_INFO* igData = reinterpret_cast(infoGetData.get()); + *iip = *igData; + return infoGetData; +} + +//////////////////////////////////////////////////////////////// bool Config::LoadConfig() { diff --git a/Share/Common.h b/Share/Common.h index a49d7e2..f9efee5 100644 --- a/Share/Common.h +++ b/Share/Common.h @@ -24,7 +24,7 @@ BOOL func_config(HWND hwnd, HINSTANCE dll_hinst); //////////////////////////////////////////////////////////////// -#define PLUGIN_VERSION "1.6" +#define PLUGIN_VERSION "1.7" constexpr int kVideoBufferSurplusBytes = 0x3FF; @@ -40,6 +40,8 @@ extern HMODULE g_hModule; /// ݎs exêtH_̃pXԂ fs::path GetExeDirectory(); +std::wstring GetLastErrorString(DWORD errorcode = GetLastError()); + //////////////////////////////////////////////////////////////// constexpr LPCSTR kConfigFileName = "InputPipePluginConfig.ini"; @@ -56,6 +58,16 @@ struct Config //////////////////////////////////////////////////////////////// +inline int CalcTotalInputInfoSize(INPUT_INFO* iip) { + return sizeof(INPUT_INFO) + iip->format_size + iip->audio_format_size; +} + +std::unique_ptr SerializeInputInfo(INPUT_INFO* iip); + +std::unique_ptr DeserializeInputInfo(const BYTE* serializedData, INPUT_INFO* iip); + +//////////////////////////////////////////////////////////////// + enum class CallFunc : std::int32_t { kOpen = 1, diff --git a/Share/IPC.cpp b/Share/IPC.cpp index 3fa24f6..da31e30 100644 --- a/Share/IPC.cpp +++ b/Share/IPC.cpp @@ -4,24 +4,9 @@ #include #include //#include "Logger.h" +#include "Common.h" -std::wstring GetLastErrorMessage(DWORD error) -{ - LPVOID pMsg = nullptr; - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER // eLXg̃蓖Ăv - | FORMAT_MESSAGE_FROM_SYSTEM // G[bZ[WWindowspӂĂ̂gp - | FORMAT_MESSAGE_IGNORE_INSERTS,// ̈𖳎ăG[R[hɑ΂G[bZ[W쐬 - NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),// w - (LPTSTR)&pMsg, // bZ[WeLXgۑobt@ւ̃|C^ - 0, - NULL); - std::wstring errorMsg = (LPCWSTR)pMsg; - LocalFree(pMsg); - return errorMsg; -} - //////////////////////////////////////////////////////////////////////////////////// // BindProcess @@ -121,15 +106,13 @@ bool NamedPipe::OpenNamedPipe(const std::wstring& pipeName) bool NamedPipe::ConnectNamedPipe() { - BOOL b = FALSE; - for (int i = 0; i < 10; ++i) { - b = ::ConnectNamedPipe(m_hPipe, nullptr); - if (b != 0) { - break; - } - ::Sleep(100); + BOOL b = ::ConnectNamedPipe(m_hPipe, nullptr); + DWORD error = GetLastError(); + if (b != 0 || error == ERROR_PIPE_CONNECTED) { + return true; + } else { + return false; } - return b != 0; } void NamedPipe::Disconnect() diff --git a/Share/IPC.h b/Share/IPC.h index 87cd55f..30440d1 100644 --- a/Share/IPC.h +++ b/Share/IPC.h @@ -21,7 +21,7 @@ class BindProcess class NamedPipe { - enum { kBuffSize = 512, kMaxInstance = 1 }; + enum { kBuffSize = 4096, kMaxInstance = 1 }; public: ~NamedPipe(); diff --git a/Share/PluginWrapper.cpp b/Share/PluginWrapper.cpp new file mode 100644 index 0000000..439e013 --- /dev/null +++ b/Share/PluginWrapper.cpp @@ -0,0 +1,100 @@ + +#include "PluginWrapper.h" + +#include "CodeConvert.h" + +#ifndef INPUT_PIPE_MAIN +#include "Logger.h" +#endif + +extern INPUT_PLUGIN_TABLE* g_winputPluginTable; + + +INPUT_HANDLE Plugin_func_open(LPSTR file) +{ + try { + INPUT_HANDLE ih = g_winputPluginTable->func_open(file); + return ih; + } + catch (...) { +#ifndef INPUT_PIPE_MAIN + ERROR_LOG << L"Plugin_func_open failed\nfile: " << CodeConvert::UTF16fromShiftJIS(file); +#endif + } + return nullptr; +} + +BOOL Plugin_func_close(INPUT_HANDLE ih) +{ + try { + BOOL b = g_winputPluginTable->func_close(ih); + return b; + } + catch (...) { +#ifndef INPUT_PIPE_MAIN + ERROR_LOG << L"Plugin_func_close failed - ih: " << ih; +#endif + } + return FALSE; +} + +BOOL Plugin_func_info_get(INPUT_HANDLE ih, INPUT_INFO* iip) +{ + try { + BOOL b = g_winputPluginTable->func_info_get(ih, iip); + return b; + } + catch (...) { +#ifndef INPUT_PIPE_MAIN + ERROR_LOG << L"Plugin_func_info_get failed - ih: " << ih; +#endif + } + return FALSE; +} + +int Plugin_func_read_video(INPUT_HANDLE ih, int frame, void* buf) +{ + try { + int readBytes = g_winputPluginTable->func_read_video(ih, frame, buf); + if (readBytes == 0) { + // 摜̎擾ɎŝŁAÕt[擾ĖړĨt[̐𑣂 + int prevFrame = frame - 1; + if (prevFrame < 0) { + prevFrame = frame + 1; + } + int prevReadBytes = g_winputPluginTable->func_read_video(ih, prevFrame, buf); + if (prevReadBytes == 0) { + //assert(false); + //ERROR_LOG << L"prevReadBytes == 0"; + } + readBytes = g_winputPluginTable->func_read_video(ih, frame, buf); + if (readBytes == 0) { + //assert(false); +#ifndef INPUT_PIPE_MAIN + ERROR_LOG << L"retry func_read_video failed : readBytes == 0 - frame: " << frame; +#endif + } + } + return readBytes; + } + catch (...) { +#ifndef INPUT_PIPE_MAIN + ERROR_LOG << L"Plugin_func_read_video failed - ih: " << ih << L" frame: " << frame; +#endif + } + return 0; +} + +int Plugin_func_read_audio(INPUT_HANDLE ih, int start, int length, void* buf) +{ + try { + int n = g_winputPluginTable->func_read_audio(ih, start, length, buf); + return n; + } + catch (...) { +#ifndef INPUT_PIPE_MAIN + ERROR_LOG << L"Plugin_func_read_audio failed - ih: " << ih << " start: " << start; +#endif + } + return 0; +} \ No newline at end of file diff --git a/Share/PluginWrapper.h b/Share/PluginWrapper.h new file mode 100644 index 0000000..33700eb --- /dev/null +++ b/Share/PluginWrapper.h @@ -0,0 +1,14 @@ +/** +* @brief MFVideoDecoderAviUtl̃t@C[_[vOCn֐Ƃĕݍ +*/ + +#pragma once + +#include "..\InputPipePlugin\input.h" + +INPUT_HANDLE Plugin_func_open(LPSTR file); +BOOL Plugin_func_close(INPUT_HANDLE ih); +BOOL Plugin_func_info_get(INPUT_HANDLE ih, INPUT_INFO* iip); +int Plugin_func_read_video(INPUT_HANDLE ih, int frame, void* buf); +int Plugin_func_read_audio(INPUT_HANDLE ih, int start, int length, void* buf); +