Fix shader bug
This commit is contained in:
@@ -306,9 +306,40 @@ HRESULT YUV420PUploadBackend::CreateGraphicsResources() {
|
||||
}
|
||||
|
||||
HRESULT YUV420PUploadBackend::CompileGraphicsShaders() {
|
||||
const char* vsSource = R"(struct VSOutput { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; }; VSOutput main(uint id : SV_VertexID) { VSOutput o; o.uv = float2((id << 1) & 2, id & 2); o.pos = float4(o.uv * float2(2, -2) + float2(-1, 1), 0, 1); return o; })";
|
||||
const char* psSource = R"(Texture2D t : register(t0); SamplerState s : register(s0); cbuffer C : register(b0) { float4x4 xf; }; float4 main(float4 pos : SV_POSITION, float2 uv : TEXCOORD0) : SV_TARGET { return t.Sample(s, mul(float4(uv, 0, 1), xf).xy); })";
|
||||
// Simplified for brevity, real implementation would be more robust
|
||||
const char* vsSource = R"(
|
||||
struct VSOutput {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
VSOutput main(uint id : SV_VertexID) {
|
||||
VSOutput o;
|
||||
o.uv = float2((id << 1) & 2, id & 2);
|
||||
o.pos = float4(o.uv * float2(2, -2) + float2(-1, 1), 0, 1);
|
||||
return o;
|
||||
})";
|
||||
|
||||
const char* psSource = R"(
|
||||
Texture2D t : register(t0);
|
||||
SamplerState s : register(s0);
|
||||
cbuffer C : register(b0) {
|
||||
float videoAspectRatio;
|
||||
float containerAspectRatio;
|
||||
float uvScaleX;
|
||||
float uvScaleY;
|
||||
float uvOffsetX;
|
||||
float uvOffsetY;
|
||||
float2 padding;
|
||||
};
|
||||
|
||||
float4 main(float4 pos : SV_POSITION, float2 uv : TEXCOORD0) : SV_TARGET {
|
||||
// Apply AspectFit transformation
|
||||
float2 transformedUV = uv * float2(uvScaleX, uvScaleY) + float2(uvOffsetX, uvOffsetY);
|
||||
float4 color = t.Sample(s, transformedUV);
|
||||
// RGB texture (RGBA format) to BGRA backbuffer - no swizzle needed
|
||||
return color;
|
||||
})";
|
||||
|
||||
ComPtr<ID3DBlob> errorBlob;
|
||||
HRESULT hr = D3DCompile(vsSource, strlen(vsSource), nullptr, nullptr, nullptr, "main", "vs_5_0", D3DCOMPILE_OPTIMIZATION_LEVEL3, 0, &m_vertexShaderBlob, &errorBlob);
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
@@ -132,6 +132,49 @@ bool ImageUtils::SaveYUV420PToBMP(const char* filename, const VideoFrame& yuv_fr
|
||||
return false;
|
||||
}
|
||||
|
||||
// Convert relative path to absolute path based on executable directory
|
||||
wchar_t module_path_w[MAX_PATH];
|
||||
DWORD module_len = GetModuleFileNameW(nullptr, module_path_w, MAX_PATH);
|
||||
if (module_len == 0 || module_len >= MAX_PATH) {
|
||||
LOGF_ERROR("[ImageUtils] Failed to get module file name (error: %lu)", GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remove filename to get directory
|
||||
wchar_t* last_slash = wcsrchr(module_path_w, L'\\');
|
||||
if (!last_slash) {
|
||||
last_slash = wcsrchr(module_path_w, L'/');
|
||||
}
|
||||
if (last_slash) {
|
||||
*last_slash = L'\0';
|
||||
}
|
||||
|
||||
// Convert input path to wide string
|
||||
wchar_t filename_w[MAX_PATH];
|
||||
int converted = MultiByteToWideChar(CP_UTF8, 0, filename, -1, filename_w, MAX_PATH);
|
||||
if (converted == 0) {
|
||||
LOGF_ERROR("[ImageUtils] Failed to convert filename to wide string (error: %lu)", GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Build absolute path: module_dir + filename
|
||||
wchar_t absolute_filename_w[MAX_PATH];
|
||||
if (filename_w[0] == L'.' && (filename_w[1] == L'/' || filename_w[1] == L'\\')) {
|
||||
// Relative path starting with "./" or ".\"
|
||||
swprintf_s(absolute_filename_w, MAX_PATH, L"%s\\%s", module_path_w, filename_w + 2);
|
||||
} else if (filename_w[0] != L'\\' && filename_w[1] != L':') {
|
||||
// Relative path without leading "./"
|
||||
swprintf_s(absolute_filename_w, MAX_PATH, L"%s\\%s", module_path_w, filename_w);
|
||||
} else {
|
||||
// Already absolute path
|
||||
wcscpy_s(absolute_filename_w, MAX_PATH, filename_w);
|
||||
}
|
||||
|
||||
// Convert back to UTF-8 for logging
|
||||
char absolute_filename_utf8[MAX_PATH];
|
||||
WideCharToMultiByte(CP_UTF8, 0, absolute_filename_w, -1, absolute_filename_utf8, MAX_PATH, nullptr, nullptr);
|
||||
LOGF_INFO("[ImageUtils] Saving BMP to: %s", absolute_filename_utf8);
|
||||
|
||||
// Allocate RGB buffer
|
||||
size_t rgb_size = yuv_frame.width * yuv_frame.height * 3;
|
||||
std::unique_ptr<uint8_t[]> rgb_buffer(new uint8_t[rgb_size]);
|
||||
@@ -142,8 +185,8 @@ bool ImageUtils::SaveYUV420PToBMP(const char* filename, const VideoFrame& yuv_fr
|
||||
return false;
|
||||
}
|
||||
|
||||
// Save RGB to BMP
|
||||
if (!SaveRGB24ToBMP(filename, rgb_buffer.get(), yuv_frame.width, yuv_frame.height)) {
|
||||
// Convert wide string path to UTF-8 for SaveRGB24ToBMP
|
||||
if (!SaveRGB24ToBMP(absolute_filename_utf8, rgb_buffer.get(), yuv_frame.width, yuv_frame.height)) {
|
||||
LOGF_ERROR("[ImageUtils] BMP save failed");
|
||||
return false;
|
||||
}
|
||||
@@ -156,40 +199,92 @@ bool ImageUtils::CreateDirectoryIfNotExists(const char* dir_path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Convert relative path to absolute path based on executable directory
|
||||
wchar_t module_path_w[MAX_PATH];
|
||||
DWORD module_len = GetModuleFileNameW(nullptr, module_path_w, MAX_PATH);
|
||||
if (module_len == 0 || module_len >= MAX_PATH) {
|
||||
LOGF_ERROR("[ImageUtils] Failed to get module file name (error: %lu)", GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remove filename to get directory
|
||||
wchar_t* last_slash = wcsrchr(module_path_w, L'\\');
|
||||
if (!last_slash) {
|
||||
last_slash = wcsrchr(module_path_w, L'/');
|
||||
}
|
||||
if (last_slash) {
|
||||
*last_slash = L'\0';
|
||||
}
|
||||
|
||||
// Convert input path to wide string
|
||||
wchar_t dir_path_w[MAX_PATH];
|
||||
int converted = MultiByteToWideChar(CP_UTF8, 0, dir_path, -1, dir_path_w, MAX_PATH);
|
||||
if (converted == 0) {
|
||||
LOGF_ERROR("[ImageUtils] Failed to convert path to wide string (error: %lu)", GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Build absolute path: module_dir + dir_path
|
||||
wchar_t absolute_path_w[MAX_PATH];
|
||||
if (dir_path_w[0] == L'.' && (dir_path_w[1] == L'/' || dir_path_w[1] == L'\\')) {
|
||||
// Relative path starting with "./" or ".\"
|
||||
swprintf_s(absolute_path_w, MAX_PATH, L"%s\\%s", module_path_w, dir_path_w + 2);
|
||||
} else if (dir_path_w[0] != L'\\' && dir_path_w[1] != L':') {
|
||||
// Relative path without leading "./"
|
||||
swprintf_s(absolute_path_w, MAX_PATH, L"%s\\%s", module_path_w, dir_path_w);
|
||||
} else {
|
||||
// Already absolute path
|
||||
wcscpy_s(absolute_path_w, MAX_PATH, dir_path_w);
|
||||
}
|
||||
|
||||
// Convert back to UTF-8 for logging
|
||||
char absolute_path_utf8[MAX_PATH];
|
||||
WideCharToMultiByte(CP_UTF8, 0, absolute_path_w, -1, absolute_path_utf8, MAX_PATH, nullptr, nullptr);
|
||||
|
||||
// Check if directory already exists first
|
||||
DWORD attribs = GetFileAttributesA(dir_path);
|
||||
DWORD attribs = GetFileAttributesW(absolute_path_w);
|
||||
if (attribs != INVALID_FILE_ATTRIBUTES && (attribs & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
// Directory already exists
|
||||
return true;
|
||||
}
|
||||
|
||||
// Try to create the directory
|
||||
BOOL result = CreateDirectoryA(dir_path, nullptr);
|
||||
BOOL result = CreateDirectoryW(absolute_path_w, nullptr);
|
||||
if (result == 0) {
|
||||
DWORD error = GetLastError();
|
||||
if (error == ERROR_ALREADY_EXISTS) {
|
||||
// Race condition: directory was created between check and create
|
||||
LOGF_INFO("[ImageUtils] Directory created by another thread: %s", absolute_path_utf8);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Try to create parent directories recursively
|
||||
std::string path_str(dir_path);
|
||||
size_t pos = path_str.find_last_of("/\\");
|
||||
if (pos != std::string::npos && pos > 0) {
|
||||
std::string parent = path_str.substr(0, pos);
|
||||
if (CreateDirectoryIfNotExists(parent.c_str())) {
|
||||
std::wstring path_str_w(absolute_path_w);
|
||||
size_t pos = path_str_w.find_last_of(L"/\\");
|
||||
if (pos != std::wstring::npos && pos > 0) {
|
||||
std::wstring parent_w = path_str_w.substr(0, pos);
|
||||
|
||||
// Convert parent path to UTF-8 for logging
|
||||
char parent_utf8[MAX_PATH];
|
||||
WideCharToMultiByte(CP_UTF8, 0, parent_w.c_str(), -1, parent_utf8, MAX_PATH, nullptr, nullptr);
|
||||
LOGF_INFO("[ImageUtils] Creating parent directory: %s", parent_utf8);
|
||||
|
||||
// Convert parent path to UTF-8 for recursive call
|
||||
if (CreateDirectoryIfNotExists(parent_utf8)) {
|
||||
// Retry after creating parent
|
||||
result = CreateDirectoryA(dir_path, nullptr);
|
||||
result = CreateDirectoryW(absolute_path_w, nullptr);
|
||||
if (result != 0 || GetLastError() == ERROR_ALREADY_EXISTS) {
|
||||
LOGF_INFO("[ImageUtils] Directory created after parent: %s", absolute_path_utf8);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LOGF_ERROR("[ImageUtils] Failed to create directory: %s (error: %lu)", dir_path, GetLastError());
|
||||
LOGF_ERROR("[ImageUtils] Failed to create directory: %s (error: %lu)", absolute_path_utf8, GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
LOGF_INFO("[ImageUtils] Directory created successfully: %s", absolute_path_utf8);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user