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
124 changes: 124 additions & 0 deletions common/include/Logger.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
* Copyright (C) 2025 Igalia, S.L.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _LOGGER_H_
#define _LOGGER_H_

#include <iostream>
#include <fstream>
#include <string>
#include <stdarg.h>

// Enum for log levels
enum LogLevel {
LOG_NONE = 0, // Use this to disable logging
LOG_ERROR,
LOG_WARNING,
LOG_INFO,
LOG_DEBUG
};

#define LOG_S_DEBUG Logger::instance()(LogLevel::LOG_DEBUG)
#define LOG_S_INFO Logger::instance()(LogLevel::LOG_INFO)
#define LOG_S_WARN Logger::instance()(LogLevel::LOG_WARNING)
#define LOG_S_ERROR Logger::instance()(LogLevel::LOG_ERROR)

#define LOG_CAT_LEVEL(LEVEL, CAT, FMT, ...) Logger::instance().printf(LEVEL, FMT, ##__VA_ARGS__)


#define LOG_DEBUG_CAT(CAT, FMT, ...) LOG_CAT_LEVEL(LogLevel::LOG_DEBUG, CAT, FMT, ##__VA_ARGS__)
#define LOG_INFO_CAT(CAT, FMT, ...) LOG_CAT_LEVEL(LogLevel::LOG_INFO, CAT, FMT, ##__VA_ARGS__)
#define LOG_WARN_CAT(CAT, FMT, ...) LOG_CAT_LEVEL(LogLevel::LOG_WARNING, CAT, FMT, ##__VA_ARGS__)
#define LOG_ERROR_CAT(CAT, FMT, ...) LOG_CAT_LEVEL(LogLevel::LOG_ERROR, CAT, FMT, ##__VA_ARGS__)

#define LOG_DEBUG(FMT, ...) LOG_DEBUG_CAT("", FMT, ##__VA_ARGS__)
#define LOG_INFO(FMT, ...) LOG_INFO_CAT("", FMT, ##__VA_ARGS__)
#define LOG_WARN( FMT,...) LOG_WARN_CAT("", FMT, ##__VA_ARGS__)
#define LOG_ERROR( FMT,...) LOG_DEBUG_CAT("", FMT, ##__VA_ARGS__)

#define LOG_DEBUG_CONFIG( FMT, ...) LOG_DEBUG_CAT("config:\t", FMT,##__VA_ARGS__)
#define LOG_INFO_CONFIG( FMT,...) LOG_INFO_CAT("config:\t", FMT,##__VA_ARGS__)
#define LOG_WARN_CONFIG( FMT,...) LOG_WARN_CAT("config:\t", FMT,##__VA_ARGS__)
#define LOG_ERROR_CONFIG( FMT,...) LOG_DEBUG_CAT("config:\t", FMT,##__VA_ARGS__)

class Logger {
private:
std::ostream& os; // The output stream (e.g., std::cout or std::ofstream)
std::ostream& err; // The error stream (e.g., std::cerr)
LogLevel currentLevel; // Current log level
LogLevel messageLevel; // The log level for the current message

public:
static Logger &instance ()
{
static Logger instance;
return instance;
}
// Constructor to set the output stream and log level (default is INFO)
Logger(std::ostream& outStream = std::cout, std::ostream& errStream = std::cerr, LogLevel level = LogLevel::LOG_INFO)
: os(outStream), err(errStream), currentLevel(level), messageLevel(LogLevel::LOG_INFO) {}

// Set the log level for the logger
void setLogLevel(int level) {
if (level > LOG_DEBUG)
level = LOG_DEBUG;
currentLevel = static_cast<LogLevel>(level);
}

// Set the log level for the current message
Logger& operator()(LogLevel level) {
messageLevel = level;
return *this;
}

// Overload the << operator for generic types
template<typename T>
Logger& operator<<(const T& data) {
if (messageLevel <= currentLevel) {
if (messageLevel == LOG_ERROR)
err << data;
else
os << data;
}
return *this;
}

// Overload for stream manipulators (like std::endl)
typedef std::ostream& (*StreamManipulator)(std::ostream&);
Logger& operator<<(StreamManipulator manip) {
if (messageLevel <= currentLevel) {
if (messageLevel == LOG_ERROR)
err << manip;
else
os << manip; // Handle std::endl, std::flush, etc.
}
return *this;
}

void printf(LogLevel level, const char* format, ...) {
if (level <= currentLevel) {
va_list args;
va_start(args, format);
if (level == LOG_ERROR)
vfprintf(stderr, format, args);
else
vfprintf(stdout,format, args);
va_end(args);
}
}
};


#endif
43 changes: 22 additions & 21 deletions common/include/VkVideoCore/VkVideoCoreProfile.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include "vulkan/vulkan.h"
#include "nvidia_utils/vulkan/ycbcr_utils.h"
#include "Logger.h"

typedef enum StdChromaFormatIdc {
chroma_format_idc_monochrome = STD_VIDEO_H264_CHROMA_FORMAT_IDC_MONOCHROME,
Expand Down Expand Up @@ -621,58 +622,58 @@ class VkVideoCoreProfile
{
// formatProfile info based on supported chroma_format_idc
if (pVideoProfile->chromaSubsampling & VK_VIDEO_CHROMA_SUBSAMPLING_MONOCHROME_BIT_KHR) {
std::cout << "MONO, ";
LOG_S_DEBUG << "MONO, ";
}
if (pVideoProfile->chromaSubsampling & VK_VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR) {
std::cout << " 420, ";
LOG_S_DEBUG << " 420, ";
}
if (pVideoProfile->chromaSubsampling & VK_VIDEO_CHROMA_SUBSAMPLING_422_BIT_KHR) {
std::cout << " 422, ";
LOG_S_DEBUG << " 422, ";
}
if (pVideoProfile->chromaSubsampling & VK_VIDEO_CHROMA_SUBSAMPLING_444_BIT_KHR) {
std::cout << " 444, ";
LOG_S_DEBUG << " 444, ";
}

// Profile info based on max bit_depth_luma_minus8
if (pVideoProfile->lumaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR) {
std::cout << "LUMA: 8-bit, ";
LOG_S_DEBUG << "LUMA: 8-bit, ";
}
if (pVideoProfile->lumaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR) {
std::cout << "LUMA: 10-bit, ";
LOG_S_DEBUG << "LUMA: 10-bit, ";
}
if (pVideoProfile->lumaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_12_BIT_KHR) {
std::cout << "LUMA: 12-bit, ";
LOG_S_DEBUG << "LUMA: 12-bit, ";
}

// Profile info based on max bit_depth_chroma_minus8
if (pVideoProfile->chromaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR) {
std::cout << "CHROMA: 8-bit, ";
LOG_S_DEBUG << "CHROMA: 8-bit, ";
}
if (pVideoProfile->chromaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR) {
std::cout << "CHROMA:10-bit, ";
LOG_S_DEBUG << "CHROMA:10-bit, ";
}
if (pVideoProfile->chromaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_12_BIT_KHR) {
std::cout << "CHROMA:12-bit,";
LOG_S_DEBUG << "CHROMA:12-bit,";
}
}

static void DumpH264Profiles(VkVideoDecodeH264ProfileInfoKHR* pH264Profiles)
{
switch (pH264Profiles->stdProfileIdc) {
case STD_VIDEO_H264_PROFILE_IDC_BASELINE:
std::cout << "BASELINE, ";
LOG_S_DEBUG << "BASELINE, ";
break;
case STD_VIDEO_H264_PROFILE_IDC_MAIN:
std::cout << "MAIN, ";
LOG_S_DEBUG << "MAIN, ";
break;
case STD_VIDEO_H264_PROFILE_IDC_HIGH:
std::cout << "HIGH, ";
LOG_S_DEBUG << "HIGH, ";
break;
case STD_VIDEO_H264_PROFILE_IDC_HIGH_444_PREDICTIVE:
std::cout << "HIGH_444_PREDICTIVE, ";
LOG_S_DEBUG << "HIGH_444_PREDICTIVE, ";
break;
default:
std::cout << "UNKNOWN PROFILE, ";
LOG_S_DEBUG << "UNKNOWN PROFILE, ";
break;
}
}
Expand All @@ -681,22 +682,22 @@ class VkVideoCoreProfile
{
switch (pH265Profiles->stdProfileIdc) {
case STD_VIDEO_H265_PROFILE_IDC_MAIN:
std::cout << "MAIN, ";
LOG_S_DEBUG << "MAIN, ";
break;
case STD_VIDEO_H265_PROFILE_IDC_MAIN_10:
std::cout << "MAIN_10, ";
LOG_S_DEBUG << "MAIN_10, ";
break;
case STD_VIDEO_H265_PROFILE_IDC_MAIN_STILL_PICTURE:
std::cout << "MAIN_STILL_PICTURE, ";
LOG_S_DEBUG << "MAIN_STILL_PICTURE, ";
break;
case STD_VIDEO_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSIONS:
std::cout << "FORMAT_RANGE_EXTENSIONS, ";
LOG_S_DEBUG << "FORMAT_RANGE_EXTENSIONS, ";
break;
case STD_VIDEO_H265_PROFILE_IDC_SCC_EXTENSIONS:
std::cout << "SCC_EXTENSIONS, ";
LOG_S_DEBUG << "SCC_EXTENSIONS, ";
break;
default:
std::cout << "UNKNOWN PROFILE, ";
LOG_S_DEBUG << "UNKNOWN PROFILE, ";
break;
}
}
Expand Down
91 changes: 45 additions & 46 deletions common/include/VkVideoCore/VulkanVideoCapabilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "VkCodecUtils/VulkanDeviceContext.h"
#include "VkCodecUtils/Helpers.h"
#include "VkVideoCore/VkVideoCoreProfile.h"
#include "Logger.h"

class VulkanVideoCapabilities
{
Expand Down Expand Up @@ -52,7 +53,7 @@ class VulkanVideoCapabilities
VkResult result = GetVideoCapabilities(vkDevCtx, videoProfile, &videoCapabilities);
assert(result == VK_SUCCESS);
if (result != VK_SUCCESS) {
fprintf(stderr, "\nERROR: Input is not supported. GetVideoCapabilities() result: 0x%x\n", result);
LOG_ERROR("ERROR: Input is not supported. GetVideoCapabilities() result: 0x%x\n", result);
}
return result;
}
Expand All @@ -76,7 +77,7 @@ class VulkanVideoCapabilities
VkResult result = GetVideoCapabilities(vkDevCtx, videoProfile, &videoCapabilities);
assert(result == VK_SUCCESS);
if (result != VK_SUCCESS) {
fprintf(stderr, "\nERROR: Input is not supported. GetVideoCapabilities() result: 0x%x\n", result);
LOG_ERROR("ERROR: Input is not supported. GetVideoCapabilities() result: 0x%x\n", result);
}
return result;
}
Expand Down Expand Up @@ -118,13 +119,13 @@ class VulkanVideoCapabilities
pictureFormat = supportedOutFormats[0];

} else {
fprintf(stderr, "\nERROR: Unsupported decode capability flags.");
LOG_ERROR("ERROR: Unsupported decode capability flags.");
return VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR;
}

assert(result == VK_SUCCESS);
if (result != VK_SUCCESS) {
fprintf(stderr, "\nERROR: GetVideoFormats() result: 0x%x\n", result);
LOG_ERROR("ERROR: GetVideoFormats() result: 0x%x\n", result);
}

assert((referencePicturesFormat != VK_FORMAT_UNDEFINED) && (pictureFormat != VK_FORMAT_UNDEFINED));
Expand Down Expand Up @@ -218,46 +219,45 @@ class VulkanVideoCapabilities
return result;
}

if (dumpData) {
std::cout << "\t\t\t" << ((videoProfile.GetCodecType() == VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR) ? "h264" : "h265") << "decode capabilities: " << std::endl;

if (pVideoCapabilities->flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR) {
std::cout << "\t\t\t" << "Use separate reference images" << std::endl;
}
LOG_S_ERROR << "\t\t\t" << videoProfile.CodecToName(videoProfile.GetCodecType()) << " capabilities: " << std::endl;

std::cout << "\t\t\t" << "minBitstreamBufferOffsetAlignment: " << pVideoCapabilities->minBitstreamBufferOffsetAlignment << std::endl;
std::cout << "\t\t\t" << "minBitstreamBufferSizeAlignment: " << pVideoCapabilities->minBitstreamBufferSizeAlignment << std::endl;
std::cout << "\t\t\t" << "pictureAccessGranularity: " << pVideoCapabilities->pictureAccessGranularity.width << " x " << pVideoCapabilities->pictureAccessGranularity.height << std::endl;
std::cout << "\t\t\t" << "minCodedExtent: " << pVideoCapabilities->minCodedExtent.width << " x " << pVideoCapabilities->minCodedExtent.height << std::endl;
std::cout << "\t\t\t" << "maxCodedExtent: " << pVideoCapabilities->maxCodedExtent.width << " x " << pVideoCapabilities->maxCodedExtent.height << std::endl;
std::cout << "\t\t\t" << "maxDpbSlots: " << pVideoCapabilities->maxDpbSlots << std::endl;
std::cout << "\t\t\t" << "maxActiveReferencePictures: " << pVideoCapabilities->maxActiveReferencePictures << std::endl;

if (videoProfile.GetCodecType() == VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR) {
const VkVideoDecodeH264CapabilitiesKHR* pH264DecCapabilities = (VkVideoDecodeH264CapabilitiesKHR*)pVideoDecodeCapabilities->pNext;
std::cout << "\t\t\t" << "maxLevelIdc: " << pH264DecCapabilities->maxLevelIdc << std::endl;
std::cout << "\t\t\t" << "fieldOffsetGranularity: " << pH264DecCapabilities->fieldOffsetGranularity.x << " x " << pH264DecCapabilities->fieldOffsetGranularity.y << std::endl;

if (strncmp(pVideoCapabilities->stdHeaderVersion.extensionName,
VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_EXTENSION_NAME,
sizeof (pVideoCapabilities->stdHeaderVersion.extensionName) - 1U) ||
(pVideoCapabilities->stdHeaderVersion.specVersion != VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_SPEC_VERSION)) {
assert(!"Unsupported h.264 STD version");
return VK_ERROR_INCOMPATIBLE_DRIVER;
}
} else if (videoProfile.GetCodecType() == VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR) {
const VkVideoDecodeH265CapabilitiesKHR* pH265DecCapabilities = (VkVideoDecodeH265CapabilitiesKHR*)pVideoDecodeCapabilities->pNext;
std::cout << "\t\t\t" << "maxLevelIdc: " << pH265DecCapabilities->maxLevelIdc << std::endl;
if (strncmp(pVideoCapabilities->stdHeaderVersion.extensionName,
VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_EXTENSION_NAME,
sizeof (pVideoCapabilities->stdHeaderVersion.extensionName) - 1U) ||
(pVideoCapabilities->stdHeaderVersion.specVersion != VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_SPEC_VERSION)) {
assert(!"Unsupported h.265 STD version");
return VK_ERROR_INCOMPATIBLE_DRIVER;
}
} else {
assert(!"Unsupported codec");
if (pVideoCapabilities->flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR) {
LOG_S_DEBUG << "\t\t\t" << "Use separate reference images" << std::endl;
}

LOG_S_DEBUG << "\t\t\t" << "minBitstreamBufferOffsetAlignment: " << pVideoCapabilities->minBitstreamBufferOffsetAlignment << std::endl;
LOG_S_DEBUG << "\t\t\t" << "minBitstreamBufferSizeAlignment: " << pVideoCapabilities->minBitstreamBufferSizeAlignment << std::endl;
LOG_S_DEBUG << "\t\t\t" << "pictureAccessGranularity: " << pVideoCapabilities->pictureAccessGranularity.width << " x " << pVideoCapabilities->pictureAccessGranularity.height << std::endl;
LOG_S_DEBUG << "\t\t\t" << "minCodedExtent: " << pVideoCapabilities->minCodedExtent.width << " x " << pVideoCapabilities->minCodedExtent.height << std::endl;
LOG_S_DEBUG << "\t\t\t" << "maxCodedExtent: " << pVideoCapabilities->maxCodedExtent.width << " x " << pVideoCapabilities->maxCodedExtent.height << std::endl;
LOG_S_DEBUG << "\t\t\t" << "maxDpbSlots: " << pVideoCapabilities->maxDpbSlots << std::endl;
LOG_S_DEBUG << "\t\t\t" << "maxActiveReferencePictures: " << pVideoCapabilities->maxActiveReferencePictures << std::endl;

if (videoProfile.GetCodecType() == VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR) {
const VkVideoDecodeH264CapabilitiesKHR* pH264DecCapabilities = (VkVideoDecodeH264CapabilitiesKHR*)pVideoDecodeCapabilities->pNext;
LOG_S_DEBUG << "\t\t\t" << "maxLevelIdc: " << pH264DecCapabilities->maxLevelIdc << std::endl;
LOG_S_DEBUG << "\t\t\t" << "fieldOffsetGranularity: " << pH264DecCapabilities->fieldOffsetGranularity.x << " x " << pH264DecCapabilities->fieldOffsetGranularity.y << std::endl;

if (strncmp(pVideoCapabilities->stdHeaderVersion.extensionName,
VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_EXTENSION_NAME,
sizeof (pVideoCapabilities->stdHeaderVersion.extensionName) - 1U) ||
(pVideoCapabilities->stdHeaderVersion.specVersion != VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_SPEC_VERSION)) {
assert(!"Unsupported h.264 STD version");
return VK_ERROR_INCOMPATIBLE_DRIVER;
}
} else if (videoProfile.GetCodecType() == VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR) {
const VkVideoDecodeH265CapabilitiesKHR* pH265DecCapabilities = (VkVideoDecodeH265CapabilitiesKHR*)pVideoDecodeCapabilities->pNext;
LOG_S_DEBUG << "\t\t\t" << "maxLevelIdc: " << pH265DecCapabilities->maxLevelIdc << std::endl;
if (strncmp(pVideoCapabilities->stdHeaderVersion.extensionName,
VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_EXTENSION_NAME,
sizeof (pVideoCapabilities->stdHeaderVersion.extensionName) - 1U) ||
(pVideoCapabilities->stdHeaderVersion.specVersion != VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_SPEC_VERSION)) {
assert(!"Unsupported h.265 STD version");
return VK_ERROR_INCOMPATIBLE_DRIVER;
}
} else {
assert(!"Unsupported codec");
}

return result;
Expand Down Expand Up @@ -300,11 +300,10 @@ class VulkanVideoCapabilities

result = vkDevCtx->GetPhysicalDeviceVideoFormatPropertiesKHR(vkDevCtx->getPhysicalDevice(), &videoFormatInfo, &supportedFormatCount, pSupportedFormats);
assert(result == VK_SUCCESS);
if (dumpData) {
std::cout << "\t\t\t" << ((videoProfile.GetCodecType() == VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR) ? "h264" : "h265") << "decode formats: " << std::endl;
for (uint32_t fmt = 0; fmt < supportedFormatCount; fmt++) {
std::cout << "\t\t\t " << fmt << ": " << std::hex << pSupportedFormats[fmt].format << std::dec << std::endl;
}

LOG_S_DEBUG << "\t\t\t" << ((videoProfile.GetCodecType() == VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR) ? "h264" : "h265") << "decode formats: " << std::endl;
for (uint32_t fmt = 0; fmt < supportedFormatCount; fmt++) {
LOG_S_DEBUG << "\t\t\t " << fmt << ": " << std::hex << pSupportedFormats[fmt].format << std::dec << std::endl;
}

formatCount = std::min(supportedFormatCount, formatCount);
Expand Down
Loading