完成图片序列到视频的工作流程

pull/1/head
ink-soul 2024-03-27 17:29:32 +08:00
parent 6e791134d7
commit fe9c837110
8 changed files with 136 additions and 26 deletions

View File

@ -3,7 +3,6 @@ cmake_policy(VERSION 3.5)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
set(NAME PlumageRender)
project(${NAME})
include_directories(external)
@ -49,6 +48,7 @@ ELSEIF(LINUX)
MESSAGE("Using bundled Vulkan library version")
ENDIF()
ENDIF()
find_package(Threads REQUIRED)
IF(USE_D2D_WSI)
MESSAGE("Using direct to display extension...")
@ -82,10 +82,11 @@ ELSEIF(LINUX)
include_directories(${CMAKE_BINARY_DIR})
ELSEIF(USE_HEADLESS)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVK_USE_PLATFORM_HEADLESS_EXT")
ELSE(USE_D2D_WSI)
find_package(XCB REQUIRED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVK_USE_PLATFORM_XCB_KHR")
#ELSE(USE_D2D_WSI)
# find_package(XCB REQUIRED)
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVK_USE_PLATFORM_XCB_KHR")
ENDIF(USE_D2D_WSI)
ELSEIF(APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVK_USE_PLATFORM_MACOS_MVK -DVK_EXAMPLE_XCODE_GENERATED")
# Todo : android?

View File

@ -42,8 +42,45 @@
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": "",
"inheritEnvironments": [ "msvc_x64_x64" ],
"variables": []
"inheritEnvironments": [ "msvc_x64_x64" ]
},
{
"name": "Linux-Clang-Debug",
"generator": "Ninja",
"configurationType": "Debug",
"cmakeExecutable": "cmake",
"remoteCopySourcesExclusionList": [ ".vs", ".git", "out" ],
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": "",
"inheritEnvironments": [ "linux_clang_x64" ],
"remoteMachineName": "${defaultRemoteMachineName}",
"remoteCMakeListsRoot": "$HOME/.vs/${projectDirName}/${workspaceHash}/src",
"remoteBuildRoot": "$HOME/.vs/${projectDirName}/${workspaceHash}/out/build/${name}",
"remoteInstallRoot": "$HOME/.vs/${projectDirName}/${workspaceHash}/out/install/${name}",
"remoteCopySources": true,
"rsyncCommandArgs": "-t --delete",
"remoteCopyBuildOutput": false,
"remoteCopySourcesMethod": "rsync"
},
{
"name": "Linux-GCC-Debug",
"generator": "Ninja",
"configurationType": "Debug",
"cmakeExecutable": "cmake",
"remoteCopySourcesExclusionList": [ ".vs", ".git", "out" ],
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": "",
"inheritEnvironments": [ "linux_x64" ],
"remoteMachineName": "${defaultRemoteMachineName}",
"remoteCMakeListsRoot": "$HOME/.vs/${projectDirName}/${workspaceHash}/src",
"remoteBuildRoot": "$HOME/.vs/${projectDirName}/${workspaceHash}/out/build/${name}",
"remoteInstallRoot": "$HOME/.vs/${projectDirName}/${workspaceHash}/out/install/${name}",
"remoteCopySources": true,
"rsyncCommandArgs": "-t --delete",
"remoteCopyBuildOutput": false,
"remoteCopySourcesMethod": "rsync"
}
]
}

View File

@ -113,17 +113,21 @@ public:
uint32_t lastFPS = 0;
struct Settings {
bool validation = false;
bool fullscreen = false;
bool vsync = false;
bool multiSampling = true;
bool rotateModel = true;
bool enableSaveToImageSequeue = false;
bool headless = false;
uint32_t outputFrameCount = 50;
bool takeScreenShot = false;
bool validation = false; // 校验层开关
bool fullscreen = false; // 全屏开关
bool vsync = false; // 垂直同步开关
bool multiSampling = true; // 多重采样
bool rotateModel = true; // 模型自旋转(暂时失效)
bool headless = false; // 无头开关
VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_4_BIT;
bool enableSaveToImageSequeue = false; // 图片序列开关(暂时弃用)
uint32_t outputFrameCount = 10; // 图片序列结束帧
bool takeScreenShot = false; // 截屏(暂时弃用)
uint32_t startFrameCount = 1; // 图片序列开始帧
uint32_t videoFrameRate = 25;
VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_4_BIT; // 多重采样倍率
} settings;
struct DepthStencil {

Binary file not shown.

View File

@ -0,0 +1,2 @@
ffmpeg -y -r %1 -i %2 -b:v 1440k -vcodec libx264 -crf 18 %3

View File

@ -0,0 +1 @@
ffmpeg -y -r $1 -i $2 -b:v 1440k -vcodec libx264 -crf 18 $3

View File

@ -1806,10 +1806,17 @@ PlumageRender::PlumageRender()
void PlumageRender::outputImageSequence()
{
std::string deviceFilePath = filePath.outputPath + "/device" + std::to_string(selectedPhysicalDeviceIndex);
std::string deviceFilePath = filePath.imageOutputPath + "/device" + std::to_string(selectedPhysicalDeviceIndex);
if (savedFrameCounter == settings.outputFrameCount)
if (savedFrameCounter > settings.outputFrameCount)
{
if (signal.imageSequenceOutputComplete) // 避免重复改变为true
{
return;
}
signal.imageSequenceOutputComplete = true;
std::string fileName = "/%dresult.ppm";
filePath.totalImageOutputPath = deviceFilePath + fileName;
return;
}
if (_access(deviceFilePath.c_str(), 0) == -1)
@ -1817,12 +1824,45 @@ PlumageRender::PlumageRender()
std::filesystem::create_directories(deviceFilePath.c_str());
}
std::string fileName = "/" + std::to_string(savedFrameCounter) + "result.ppm";
std::string outputPath = deviceFilePath + fileName;
filePath.totalImageOutputPath = deviceFilePath + fileName;
//std::cout << outputPath << std::endl;
writeImageToFile(outputPath.c_str());
writeImageToFile(filePath.totalImageOutputPath.c_str());
savedFrameCounter++;
}
void PlumageRender::imageSequenceToVideo()
{
if (!signal.imageSequenceOutputComplete)
{
return;
}
if (signal.imageSequenceToVideoComplete)
{
return;
}
std::string deviceFilePath = filePath.videoOutputPath + "/device" + std::to_string(selectedPhysicalDeviceIndex);
if (_access(deviceFilePath.c_str(), 0) == -1)
{
std::filesystem::create_directories(deviceFilePath.c_str());
}
std::string resultVideoPath = deviceFilePath + "/result.mp4";
std::string commandLineImageSequencePath = filePath.totalImageOutputPath;
//std::string commandLineCodecAndResultPath = resultVideoPath;
std::string commandLineFrameRate = std::to_string(settings.videoFrameRate);
#if defined(_WIN32)
std::string commandLine = filePath.image2videoBatFilePath + " " + commandLineFrameRate + " " + commandLineImageSequencePath + " " + resultVideoPath;
#else
std::string commandLine = filePath.image2videoShFilePath + " " + commandLineFrameRate + " " + commandLineImageSequencePath + " " + resultVideoPath;
#endif
std::cout << commandLine << std::endl;
std::system(commandLine.c_str());
signal.imageSequenceToVideoComplete = true;
std::cout << "vidoe codec complete,saved in:" << resultVideoPath << std::endl;
}
uint32_t PlumageRender::getMemoryTypeIndex(uint32_t typeBits, VkMemoryPropertyFlags properties)
{
VkPhysicalDeviceMemoryProperties deviceMemoryProperties;
@ -1856,6 +1896,7 @@ PlumageRender::PlumageRender()
VK_CHECK_RESULT(vkWaitForFences(device, 1, &waitFences[frameIndex], VK_TRUE, UINT64_MAX));
outputImageSequence();
imageSequenceToVideo();
VK_CHECK_RESULT(vkResetFences(device, 1, &waitFences[frameIndex]));
VkResult acquire = swapChain.acquireNextImage(presentCompleteSemaphores[frameIndex], &currentBuffer);

View File

@ -1,5 +1,16 @@
#pragma once
#if defined(_WIN32)
#include <io.h>
#include <direct.h>
#else
#include<sys/io.h>
#include<dirent.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -7,8 +18,7 @@
#include <vector>
#include <chrono>
#include <map>
#include <io.h>
#include <direct.h>
#include <locale>
#include <codecvt>
#include "algorithm"
@ -41,6 +51,13 @@ public:
} info ;
struct Signal
{
bool imageSequenceOutputComplete = false;
bool imageSequenceToVideoComplete = false;
}signal;
struct Models
{
@ -164,8 +181,13 @@ public:
// output file path
std::string outputPath = getAssetPath() + "output/imageSequence";
std::string imageOutputPath = getAssetPath() + "output/imageSequence";
std::string videoOutputPath = getAssetPath() + "output/video";
std::string totalImageOutputPath;
// script file path
std::string image2videoBatFilePath = getAssetPath() + "script/image2video.bat";
std::string image2videoShFilePath = getAssetPath() + "script/image2video.sh";
} filePath;
@ -278,7 +300,7 @@ public:
UI* gui;
uint64_t savedFrameCounter = 0;
uint64_t savedFrameCounter = settings.startFrameCount;
PlumageRender();
@ -339,9 +361,11 @@ public:
void windowResized();
void prepare();
void submitWork(VkCommandBuffer cmdBuffer, VkQueue queue);
void writeImageToFile(std::string filePath);
void outputImageSequence();
void outputScreenShot();
void imageSequenceToVideo();
//void outputScreenShot();
uint32_t getMemoryTypeIndex(uint32_t typeBits, VkMemoryPropertyFlags properties);
virtual void render();
virtual void updateUIOverlay();