Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ set (VULKAN_SDK_MIN_MINOR_VERSION 4)
set (VULKAN_SDK_MIN_PATCH_VERSION 321)
FIND_VULKAN_SDK(${VULKAN_SDK_MIN_MAJOR_VERSION} ${VULKAN_SDK_MIN_MINOR_VERSION} ${VULKAN_SDK_MIN_PATCH_VERSION})

include(FindShaderc)
option(USE_ENCODER_SHADERC "Enable shaderc GPU compute filters for encoder (e.g. YUV conversion). Only affects the encoder build; the decoder always uses shaderc." ON)
if(BUILD_DECODER OR USE_ENCODER_SHADERC)
include(FindShaderc)
endif()

############ VULKAN_FFMPEG_LIB_PATH ######################################
if (DEFINED ENV{VULKAN_FFMPEG_LIB_DIR_PATH})
Expand Down
2 changes: 1 addition & 1 deletion cmake/LinuxSettings.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ endif()

# Compiler flags for GCC/Clang
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
set(COMMON_COMPILE_FLAGS "-Wall -Wextra -Wundef -Wno-unused-parameter -Wno-missing-field-initializers -Wshadow")
set(COMMON_COMPILE_FLAGS "-Wall -Wextra -Wundef -Wno-unused-parameter -Wno-missing-field-initializers -Wshadow -Wcast-qual")
set(COMMON_COMPILE_FLAGS "${COMMON_COMPILE_FLAGS} -fno-strict-aliasing -fno-builtin-memcmp")

# Warning about implicit fallthrough in switch blocks
Expand Down
2 changes: 1 addition & 1 deletion common/include/VkVideoCore/VulkanVideoCapabilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ class VulkanVideoCapabilities
}
}

formatCount = std::min(supportedFormatCount, formatCount);
formatCount = std::min<uint32_t>(supportedFormatCount, formatCount);

for (uint32_t i = 0; i < formatCount; i++) {
formats[i] = pSupportedFormats[i].format;
Expand Down
8 changes: 4 additions & 4 deletions common/include/mio/mio.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -786,13 +786,13 @@ namespace win {
/** Returns the 4 upper bytes of an 8-byte integer. */
inline DWORD int64_high(int64_t n) noexcept
{
return n >> 32;
return (DWORD)(n >> 32);
}

/** Returns the 4 lower bytes of an 8-byte integer. */
inline DWORD int64_low(int64_t n) noexcept
{
return n & 0xffffffff;
return (DWORD)(n & 0xffffffff);
}

inline std::wstring s_2_ws(const std::string& s)
Expand Down Expand Up @@ -887,7 +887,7 @@ inline size_t query_file_size(file_handle_type handle, std::error_code& error)
error = detail::last_error();
return 0;
}
return static_cast<int64_t>(file_size.QuadPart);
return static_cast<size_t>(file_size.QuadPart);
#else // POSIX
struct stat sbuf;
if(::fstat(handle, &sbuf) == -1)
Expand Down Expand Up @@ -933,7 +933,7 @@ inline mmap_context memory_map(const file_handle_type file_handle, const int64_t
mode == access_mode::read ? FILE_MAP_READ : FILE_MAP_WRITE,
win::int64_high(aligned_offset),
win::int64_low(aligned_offset),
length_to_map));
(size_t)length_to_map));
if(mapping_start == nullptr)
{
// Close file handle if mapping it failed.
Expand Down
18 changes: 18 additions & 0 deletions common/include/nvidia_utils/vulkan/ycbcr_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,24 @@ typedef struct YcbcrPlanesLayoutInfo {
uint8_t reserved; // reserved for structure alignment.
} YcbcrPlanesLayoutInfo;

static inline uint32_t GetBitsPerChannel(const YcbcrPlanesLayoutInfo& pYcbcrPlanesLayoutInfo)
{
switch (pYcbcrPlanesLayoutInfo.bpp) {
case YCBCRA_8BPP:
return 8;
case YCBCRA_10BPP:
return 10;
case YCBCRA_12BPP:
return 12;
case YCBCRA_14BPP:
return 14;
case YCBCRA_16BPP:
return 16;
default:
return 8;
}
}

static inline size_t YcbcrAlign(size_t toAlign, size_t alignment)
{
return ((toAlign + (alignment - 1)) & ~(alignment -1));
Expand Down
2 changes: 1 addition & 1 deletion common/libs/VkCodecUtils/FrameProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ class FrameProcessor : public VkVideoRefCountBase {
FrameProcessor(bool verbose = false)
: m_frameCount(0)
, m_profileFramesCount(0)
, m_displayTimePeriodMilliseconds(1000)
, m_displayTimePeriodMilliseconds(100)
, start_time (std::chrono::steady_clock::now())
, m_verbose(verbose)
{
Expand Down
22 changes: 11 additions & 11 deletions common/libs/VkCodecUtils/Helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ inline VkResult WaitAndGetStatus(const VkInterfaceFunctions* vkIf, VkDevice devi
}

template<typename NodeType, typename ChainedNodeType>
inline VkBaseInStructure* ChainNextVkStruct(NodeType& node, ChainedNodeType& nextChainedNode) {
inline void ChainNextVkStruct(NodeType& node, ChainedNodeType& nextChainedNode) {
// make sure the node is of type VkBaseInStructure
static_assert(offsetof(NodeType, sType) == offsetof(VkBaseInStructure, sType),
"NodeType does not have sType at the same offset as VkBaseInStructure");
Expand All @@ -341,16 +341,16 @@ inline VkBaseInStructure* ChainNextVkStruct(NodeType& node, ChainedNodeType& nex
"ChainedNodeType must be a standard-layout type");

assert(node.sType > 0);
VkBaseInStructure* pNode = (VkBaseInStructure*)&node;
while (pNode->pNext != nullptr) {
pNode = (VkBaseInStructure*)pNode->pNext;
}
pNode->pNext = (VkBaseInStructure*)&nextChainedNode;
// make sure the nextChainedNode is of type VkBaseInStructure
assert(nextChainedNode.sType > 0);
assert(nextChainedNode.pNext == nullptr);
return (VkBaseInStructure*)nextChainedNode.pNext;
}
VkBaseInStructure* pNode = (VkBaseInStructure*)(&node);
VkBaseInStructure* pNextNode = (VkBaseInStructure*)(&nextChainedNode);

// The incoming object may not have anything chained.
assert(pNextNode->pNext == nullptr);

// Inserts the incoming object at the beginning of the list.
pNextNode->pNext = pNode->pNext;
pNode->pNext = pNextNode;
}

class DeviceUuidUtils
{
Expand Down
5 changes: 4 additions & 1 deletion common/libs/VkCodecUtils/VkThreadPool.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,11 @@ class VkThreadPool
std::future<return_type> res = task->get_future();
{
std::unique_lock<std::mutex> lock(queue_mutex);
if(stop)
if(stop) {
#ifdef __cpp_exceptions
throw std::runtime_error("enqueue on stopped ThreadPool");
#endif
}

tasks.emplace([task](){ (*task)(); });
}
Expand Down
140 changes: 53 additions & 87 deletions common/libs/VkCodecUtils/VkVideoFrameToFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,80 +23,7 @@
#include "VulkanDecodedFrame.h"
#include "Helpers.h"
#include "VkVideoFrameOutput.h"

// CRC32 lookup table
static unsigned long Crc32Table[256] = {
0x00000000,0x77073096,0xee0e612c,0x990951ba,
0x076dc419,0x706af48f,0xe963a535,0x9e6495a3,
0x0edb8832,0x79dcb8a4,0xe0d5e91e,0x97d2d988,
0x09b64c2b,0x7eb17cbd,0xe7b82d07,0x90bf1d91,
0x1db71064,0x6ab020f2,0xf3b97148,0x84be41de,
0x1adad47d,0x6ddde4eb,0xf4d4b551,0x83d385c7,
0x136c9856,0x646ba8c0,0xfd62f97a,0x8a65c9ec,
0x14015c4f,0x63066cd9,0xfa0f3d63,0x8d080df5,
0x3b6e20c8,0x4c69105e,0xd56041e4,0xa2677172,
0x3c03e4d1,0x4b04d447,0xd20d85fd,0xa50ab56b,
0x35b5a8fa,0x42b2986c,0xdbbbc9d6,0xacbcf940,
0x32d86ce3,0x45df5c75,0xdcd60dcf,0xabd13d59,
0x26d930ac,0x51de003a,0xc8d75180,0xbfd06116,
0x21b4f4b5,0x56b3c423,0xcfba9599,0xb8bda50f,
0x2802b89e,0x5f058808,0xc60cd9b2,0xb10be924,
0x2f6f7c87,0x58684c11,0xc1611dab,0xb6662d3d,
0x76dc4190,0x01db7106,0x98d220bc,0xefd5102a,
0x71b18589,0x06b6b51f,0x9fbfe4a5,0xe8b8d433,
0x7807c9a2,0x0f00f934,0x9609a88e,0xe10e9818,
0x7f6a0dbb,0x086d3d2d,0x91646c97,0xe6635c01,
0x6b6b51f4,0x1c6c6162,0x856530d8,0xf262004e,
0x6c0695ed,0x1b01a57b,0x8208f4c1,0xf50fc457,
0x65b0d9c6,0x12b7e950,0x8bbeb8ea,0xfcb9887c,
0x62dd1ddf,0x15da2d49,0x8cd37cf3,0xfbd44c65,
0x4db26158,0x3ab551ce,0xa3bc0074,0xd4bb30e2,
0x4adfa541,0x3dd895d7,0xa4d1c46d,0xd3d6f4fb,
0x4369e96a,0x346ed9fc,0xad678846,0xda60b8d0,
0x44042d73,0x33031de5,0xaa0a4c5f,0xdd0d7cc9,
0x5005713c,0x270241aa,0xbe0b1010,0xc90c2086,
0x5768b525,0x206f85b3,0xb966d409,0xce61e49f,
0x5edef90e,0x29d9c998,0xb0d09822,0xc7d7a8b4,
0x59b33d17,0x2eb40d81,0xb7bd5c3b,0xc0ba6cad,
0xedb88320,0x9abfb3b6,0x03b6e20c,0x74b1d29a,
0xead54739,0x9dd277af,0x04db2615,0x73dc1683,
0xe3630b12,0x94643b84,0x0d6d6a3e,0x7a6a5aa8,
0xe40ecf0b,0x9309ff9d,0x0a00ae27,0x7d079eb1,
0xf00f9344,0x8708a3d2,0x1e01f268,0x6906c2fe,
0xf762575d,0x806567cb,0x196c3671,0x6e6b06e7,
0xfed41b76,0x89d32be0,0x10da7a5a,0x67dd4acc,
0xf9b9df6f,0x8ebeeff9,0x17b7be43,0x60b08ed5,
0xd6d6a3e8,0xa1d1937e,0x38d8c2c4,0x4fdff252,
0xd1bb67f1,0xa6bc5767,0x3fb506dd,0x48b2364b,
0xd80d2bda,0xaf0a1b4c,0x36034af6,0x41047a60,
0xdf60efc3,0xa867df55,0x316e8eef,0x4669be79,
0xcb61b38c,0xbc66831a,0x256fd2a0,0x5268e236,
0xcc0c7795,0xbb0b4703,0x220216b9,0x5505262f,
0xc5ba3bbe,0xb2bd0b28,0x2bb45a92,0x5cb36a04,
0xc2d7ffa7,0xb5d0cf31,0x2cd99e8b,0x5bdeae1d,
0x9b64c2b0,0xec63f226,0x756aa39c,0x026d930a,
0x9c0906a9,0xeb0e363f,0x72076785,0x05005713,
0x95bf4a82,0xe2b87a14,0x7bb12bae,0x0cb61b38,
0x92d28e9b,0xe5d5be0d,0x7cdcefb7,0x0bdbdf21,
0x86d3d2d4,0xf1d4e242,0x68ddb3f8,0x1fda836e,
0x81be16cd,0xf6b9265b,0x6fb077e1,0x18b74777,
0x88085ae6,0xff0f6a70,0x66063bca,0x11010b5c,
0x8f659eff,0xf862ae69,0x616bffd3,0x166ccf45,
0xa00ae278,0xd70dd2ee,0x4e048354,0x3903b3c2,
0xa7672661,0xd06016f7,0x4969474d,0x3e6e77db,
0xaed16a4a,0xd9d65adc,0x40df0b66,0x37d83bf0,
0xa9bcae53,0xdebb9ec5,0x47b2cf7f,0x30b5ffe9,
0xbdbdf21c,0xcabac28a,0x53b39330,0x24b4a3a6,
0xbad03605,0xcdd70693,0x54de5729,0x23d967bf,
0xb3667a2e,0xc4614ab8,0x5d681b02,0x2a6f2b94,
0xb40bbe37,0xc30c8ea1,0x5a05df1b,0x2d02ef8d
};

static void getCRC(uint32_t *checksum, const uint8_t *inputBytes, size_t length, unsigned long crcTable[]) {
for (size_t i = 0; i < length; i += 1) {
*checksum = crcTable[inputBytes[i] ^ (*checksum & 0xff)] ^ (*checksum >> 8);
}
}
#include "crcgenerator.h"

// Rotate right for 16-bit unsigned integers.
// Used to normalize MSB-aligned high bit-depth samples (10-bit, 12-bit) to LSB-aligned.
Expand Down Expand Up @@ -240,7 +167,7 @@ class VkVideoFrameToFileImpl : public VkVideoFrameOutput {
}

if (m_outputcrcPerFrame && m_crcOutputFile) {
fprintf(m_crcOutputFile, "CRC Frame[%" PRId64 "]:", pFrame->displayOrder);
fprintf(m_crcOutputFile, "CRC Frame[%lld]:", (long long)pFrame->displayOrder);
for (size_t i = 0; i < m_crcInitValue.size(); i += 1) {
uint32_t frameCrc = m_crcInitValue[i];
getCRC(&frameCrc, pOutputBuffer, usedBufferSize, Crc32Table);
Expand All @@ -265,15 +192,44 @@ class VkVideoFrameToFileImpl : public VkVideoFrameOutput {
}
}

FILE* AttachFile(const char* fileName) {
bool hasExtension(const char* fileName, const char* extension) {
size_t fileLen = std::strlen(fileName);
size_t extLen = std::strlen(extension);

if (fileLen < extLen) {
return false;
}

return std::strcmp(fileName + fileLen - extLen, extension) == 0;
}

FILE* AttachFile(const char* fileName, bool y4mFormat) {
if (m_outputFile) {
fclose(m_outputFile);
m_outputFile = nullptr;
}

std::string fileNameWithModExt;
// Check if the file does not have a y4m extension,
// but y4m format is requested.
if (y4mFormat && !hasExtension(fileName, ".y4m")) {
std::cout << std::endl << "y4m output format is requested, ";
std::cout << "but the output file's (" << fileName << ") extension isn't .y4m!"
<< std::endl;
fileNameWithModExt = fileName + std::string(".y4m");
fileName = fileNameWithModExt.c_str();
} else if ((y4mFormat == false) && !hasExtension(fileName, ".yuv")) {
std::cout << std::endl << "Raw yuv output format is requested, ";
std::cout << "but the output file's (" << fileName << ") extension isn't .yuv!"
<< std::endl;
fileNameWithModExt = fileName + std::string(".yuv");
fileName = fileNameWithModExt.c_str();
}

if (fileName != nullptr) {
m_outputFile = fopen(fileName, "wb");
if (m_outputFile) {
std::cout << "Output file name is: " << fileName << std::endl;
return m_outputFile;
}
}
Expand Down Expand Up @@ -386,6 +342,7 @@ class VkVideoFrameToFileImpl : public VkVideoFrameOutput {
VkDeviceSize maxSize = 0;
const uint8_t* readImagePtr = srcImageDeviceMemory->GetReadOnlyDataPtr(imageOffset, maxSize);
assert(readImagePtr != nullptr);
assert(maxSize <= SIZE_MAX); // Ensure we don't lose data in conversion

int32_t secondaryPlaneWidth = frameWidth;
int32_t secondaryPlaneHeight = frameHeight;
Expand Down Expand Up @@ -461,14 +418,18 @@ class VkVideoFrameToFileImpl : public VkVideoFrameOutput {
// Copy the luma plane
const uint32_t numCompatiblePlanes = 1;
for (uint32_t plane = 0; plane < numCompatiblePlanes; plane++) {
const uint8_t* pSrc = readImagePtr + layouts[plane].offset;
uint8_t* pDst = pOutBuffer + yuvPlaneLayouts[plane].offset;
const uint8_t* pSrc = readImagePtr + static_cast<size_t>(layouts[plane].offset);
uint8_t* pDst = pOutBuffer + static_cast<size_t>(yuvPlaneLayouts[plane].offset);

if (is8Bit) {
CopyPlaneData<uint8_t>(pSrc, pDst, layouts[plane].rowPitch, yuvPlaneLayouts[plane].rowPitch,
assert(layouts[plane].rowPitch <= SIZE_MAX);
assert(yuvPlaneLayouts[plane].rowPitch <= SIZE_MAX);
CopyPlaneData<uint8_t>(pSrc, pDst, static_cast<size_t>(layouts[plane].rowPitch), static_cast<size_t>(yuvPlaneLayouts[plane].rowPitch),
frameWidth, imageHeight);
} else {
CopyPlaneData<uint16_t>(pSrc, pDst, layouts[plane].rowPitch, yuvPlaneLayouts[plane].rowPitch,
assert(layouts[plane].rowPitch <= SIZE_MAX);
assert(yuvPlaneLayouts[plane].rowPitch <= SIZE_MAX);
CopyPlaneData<uint16_t>(pSrc, pDst, static_cast<size_t>(layouts[plane].rowPitch), static_cast<size_t>(yuvPlaneLayouts[plane].rowPitch),
frameWidth, imageHeight, 1, bitShift);
}
}
Expand All @@ -488,21 +449,25 @@ class VkVideoFrameToFileImpl : public VkVideoFrameOutput {
}

if (is8Bit) {
CopyPlaneData<uint8_t>(pSrc, pDst, layouts[srcPlane].rowPitch, yuvPlaneLayouts[plane].rowPitch,
assert(layouts[srcPlane].rowPitch <= SIZE_MAX);
assert(yuvPlaneLayouts[plane].rowPitch <= SIZE_MAX);
CopyPlaneData<uint8_t>(pSrc, pDst, static_cast<size_t>(layouts[srcPlane].rowPitch), static_cast<size_t>(yuvPlaneLayouts[plane].rowPitch),
planeWidth, 1, 2);
} else {
CopyPlaneData<uint16_t>(pSrc, pDst, layouts[srcPlane].rowPitch, yuvPlaneLayouts[plane].rowPitch,
assert(layouts[srcPlane].rowPitch <= SIZE_MAX);
assert(yuvPlaneLayouts[plane].rowPitch <= SIZE_MAX);
CopyPlaneData<uint16_t>(pSrc, pDst, static_cast<size_t>(layouts[srcPlane].rowPitch), static_cast<size_t>(yuvPlaneLayouts[plane].rowPitch),
planeWidth, 1, 2, bitShift);
}
pDst += yuvPlaneLayouts[plane].rowPitch;
}
}

// Calculate total buffer size
outputBufferSize = yuvPlaneLayouts[0].rowPitch * imageHeight;
outputBufferSize = static_cast<size_t>(yuvPlaneLayouts[0].rowPitch * imageHeight);
if (mpInfo->planesLayout.numberOfExtraPlanes >= 1) {
outputBufferSize += yuvPlaneLayouts[1].rowPitch * secondaryPlaneHeight;
outputBufferSize += yuvPlaneLayouts[2].rowPitch * secondaryPlaneHeight;
outputBufferSize += static_cast<size_t>(yuvPlaneLayouts[1].rowPitch * secondaryPlaneHeight);
outputBufferSize += static_cast<size_t>(yuvPlaneLayouts[2].rowPitch * secondaryPlaneHeight);
}

return outputBufferSize;
Expand All @@ -516,6 +481,7 @@ class VkVideoFrameToFileImpl : public VkVideoFrameOutput {
}

VkDeviceSize imageMemorySize = imageResource->GetImageDeviceMemorySize();
assert(imageMemorySize <= SIZE_MAX); // Ensure we don't lose data in conversion

if ((m_pLinearMemory == nullptr) || (imageMemorySize > m_allocationSize)) {
if (m_outputFile) {
Expand All @@ -527,7 +493,7 @@ class VkVideoFrameToFileImpl : public VkVideoFrameOutput {
m_pLinearMemory = nullptr;
}

m_allocationSize = (size_t)(imageMemorySize);
m_allocationSize = static_cast<size_t>(imageMemorySize);
m_pLinearMemory = new uint8_t[m_allocationSize];
if (m_pLinearMemory == nullptr) {
return nullptr;
Expand Down Expand Up @@ -568,7 +534,7 @@ VkResult VkVideoFrameOutput::Create(const char* fileName,
return VK_ERROR_OUT_OF_HOST_MEMORY;
}

FILE* outFile = newFrameToFile->AttachFile(fileName);
FILE* outFile = newFrameToFile->AttachFile(fileName, outputy4m);
if ((fileName != nullptr) && (outFile == nullptr)) {
delete newFrameToFile;
return VK_ERROR_INITIALIZATION_FAILED;
Expand Down
Loading