ATOM_KERNEL_API void ATOM_CALL ATOM_RemoveStandardOutputCallback (ATOM_StdOutputCallback *stdoutCallback, ATOM_StdOutputCallback *stderrCallback) { if (!_PipeInitialized && !InitPipes ()) { ATOM_LOGGER::error ("Init output pipes failed.\n"); return; } { ATOM_Mutex::ScopeMutex sm(_StdoutCallbackLock); ATOM_VECTOR<ATOM_StdOutputCallback *>::iterator it = std::find(_Stdout_Callbacks.begin(), _Stdout_Callbacks.end(), stdoutCallback); if (it != _Stdout_Callbacks.end ()) { _Stdout_Callbacks.erase (it); if (_Stdout_Callbacks.empty ()) { ::SuspendThread (_StdoutThreadHandle); *stdout = _OldStdout; } } } { ATOM_Mutex::ScopeMutex sm(_StderrCallbackLock); ATOM_VECTOR<ATOM_StdOutputCallback *>::iterator it = std::find(_Stderr_Callbacks.begin(), _Stderr_Callbacks.end(), stderrCallback); if (it != _Stderr_Callbacks.end ()) { _Stderr_Callbacks.erase (it); if (_Stderr_Callbacks.empty ()) { ::SuspendThread (_StderrThreadHandle); *stderr = _OldStderr; } } } }
ATOM_KERNEL_API void ATOM_CALL ATOM_AddStandardOutputCallback (ATOM_StdOutputCallback *stdoutCallback, ATOM_StdOutputCallback *stderrCallback) { if (!_PipeInitialized && !InitPipes ()) { ATOM_LOGGER::error ("Init output pipes failed.\n"); return; } { ATOM_Mutex::ScopeMutex sm(_StdoutCallbackLock); if (stdoutCallback && std::find(_Stdout_Callbacks.begin(), _Stdout_Callbacks.end(), stdoutCallback) == _Stdout_Callbacks.end()) { _Stdout_Callbacks.push_back (stdoutCallback); if (_Stdout_Callbacks.size() == 1) { *stdout = *_StdoutPipeFp; setvbuf (stdout, 0, _IONBF, 0); ::ResumeThread (_StdoutThreadHandle); } } } { ATOM_Mutex::ScopeMutex sm(_StderrCallbackLock); if (stderrCallback && std::find(_Stderr_Callbacks.begin(), _Stderr_Callbacks.end(), stderrCallback) == _Stderr_Callbacks.end()) { _Stderr_Callbacks.push_back (stderrCallback); if (!_Stderr_Callbacks.size() == 1) { *stderr = *_StderrPipeFp; setvbuf (stderr, 0, _IONBF, 0); ::ResumeThread (_StderrThreadHandle); } } } }
BOOL check_x264_mp4_output(const char *exe_path, const char *temp_filename) { BOOL ret = FALSE; std::string exe_message; PROCESS_INFORMATION pi = { 0 }; const int TEST_WIDTH = 160; const int TEST_HEIGHT = 120; std::vector<char> test_buffer(TEST_WIDTH * TEST_HEIGHT * 3 / 2, 0); PIPE_SET pipes = { 0 }; InitPipes(&pipes); pipes.stdIn.mode = AUO_PIPE_ENABLE; pipes.stdOut.mode = AUO_PIPE_DISABLE; pipes.stdErr.mode = AUO_PIPE_ENABLE; pipes.stdIn.bufferSize = test_buffer.size(); char test_path[1024] = { 0 }; for (int i = 0; !i || PathFileExists(test_path); i++) { char test_filename[32] = { 0 }; sprintf_s(test_filename, _countof(test_filename), "_test_%d.mp4", i); PathCombineLong(test_path, _countof(test_path), temp_filename, test_filename); } char exe_dir[1024] = { 0 }; strcpy_s(exe_dir, _countof(exe_dir), exe_path); PathRemoveFileSpecFixed(exe_dir); char fullargs[8192] = { 0 }; sprintf_s(fullargs, _countof(fullargs), "\"%s\" --fps 1 --frames 1 --input-depth 8 --input-res %dx%d -o \"%s\" --input-csp nv12 -", exe_path, TEST_WIDTH, TEST_HEIGHT, test_path); if ((ret = RunProcess(fullargs, exe_dir, &pi, &pipes, NORMAL_PRIORITY_CLASS, TRUE, FALSE)) == RP_SUCCESS) { while (WAIT_TIMEOUT == WaitForInputIdle(pi.hProcess, LOG_UPDATE_INTERVAL)) log_process_events(); _fwrite_nolock(&test_buffer[0], 1, test_buffer.size(), pipes.f_stdin); auto read_stderr = [](PIPE_SET *pipes) { DWORD pipe_read = 0; if (!PeekNamedPipe(pipes->stdErr.h_read, NULL, 0, NULL, &pipe_read, NULL)) return -1; if (pipe_read) { ReadFile(pipes->stdErr.h_read, pipes->read_buf + pipes->buf_len, sizeof(pipes->read_buf) - pipes->buf_len - 1, &pipe_read, NULL); pipes->buf_len += pipe_read; pipes->read_buf[pipes->buf_len] = '\0'; } return (int)pipe_read; }; while (WAIT_TIMEOUT == WaitForSingleObject(pi.hProcess, 10)) { if (read_stderr(&pipes)) { exe_message += pipes.read_buf; pipes.buf_len = 0; } else { log_process_events(); } } CloseStdIn(&pipes); while (read_stderr(&pipes) > 0) { exe_message += pipes.read_buf; pipes.buf_len = 0; } log_process_events(); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); if (std::string::npos == exe_message.find("not compiled with MP4 output")) ret = TRUE; } if (pipes.stdIn.mode) CloseHandle(pipes.stdIn.h_read); if (pipes.stdOut.mode) CloseHandle(pipes.stdOut.h_read); if (pipes.stdErr.mode) CloseHandle(pipes.stdErr.h_read); if (PathFileExists(test_path)) remove(test_path); return ret; }