u/Tensorizer

10 bit YUV to 8 bit ARGB conversion

10 bit YUV to 8 bit ARGB conversion

I am looking for the exact formula that BlackMagic uses for converting bmdFormat10BitYUV to bmdFormat8BitARGB in its IDeckLinkVideoConversion

I need to implement this conversion on the GPU where the image will live thus leaving the job to the DeckLink api which runs on the CPU is not viable performance-wise.

BlackMagic Decklink result

The formula I am using results in somewhat washed Black and to a lesser extent Blue:

Apparent difference in Black and (somewhat) in Blue

static float ConvertRec709ToLinear(float Value) {
float Result{};
//BT709 OECF-Different Ranges
if(0.09f > Value)
Result = Value / 4.5f;
else
Result = pow((Value + 0.099f) / 1.099f, 2.2222222f);
return Result;
}
 
static glm::vec3 ConvertRec709ToLinearVector(glm::vec3 value) {
glm::vec3 result{ glm::vec3(0.0f) };
result.r = ConvertRec709ToLinear(value.r);
result.g = ConvertRec709ToLinear(value.g);
result.b = ConvertRec709ToLinear(value.b);
return result;
}

static glm::vec4 ConvertYUVtoRGBA(float Y, float Cb, float Cr, float Alpha) {
Y /= 1023.99f;
Cb /= 1023.99f;
Cr /= 1023.99f;
//Range Clipping
Y -= 0.0f;
Cb -= (512.0f / 1023.0f);
Cr -= (512.0f / 1023.0f);
glm::vec3 YCbCr{ glm::vec3(Y, Cb, Cr) };
glm::vec3 RGB{ glm::vec3(0.0f) };
RGB.r = glm::clamp(glm::dot(YCbCr, glm::vec3(1.000f, 0.0000f, 1.5748f)), 0.0f, 1.0f);
RGB.g = glm::clamp(glm::dot(YCbCr, glm::vec3(1.000f, -0.1873f, -0.4681f)), 0.0f, 1.0f);
RGB.b = glm::clamp(glm::dot(YCbCr, glm::vec3(1.000f, 1.8556f, 0.0000f)), 0.0f, 1.0f);
RGB = ConvertRec709ToLinearVector(RGB);
return glm::vec4(RGB, Alpha);
}

where ConvertYUVtoRGBA() is called with 10bit integer Y, Cb, Cr values cast to float and Alpha = 1.0f

reddit.com
u/Tensorizer — 2 days ago
▲ 7 r/vulkan

Pipeline (Image) Barrier for both layout and queue families

I have a Compute pipeline and a Graphics pipeline that access a VkImage that is created with VK_SHARING_MODE_EXCLUSIVE.

As I was working on the acquire-release mechanism, I've encountered, with the help of Khronos Validation Layer, something I was not expecting:

I have to make two separate vkCmdPipelineBarrier() calls in both acquire and release phases-one for srcQueueFamilyIndex / dstQueueFamilyIndex and another for oldLayout / newLayout.

I was under the impression that a single VkImageMemoryBarrier would suffice, but to satisfy the Khronos Validation Layer I had to perform family index and layout transitions in the release phase as two separate calls and likewise in the acquire counterpart.

Am I misinterpreting something here?

reddit.com
u/Tensorizer — 8 days ago

In ContourPlot3D[] function, one can specify individual colors of the surfaces or, opacity and a single color, as far as I can tell:

ContourStyle -> {Pink, Yellow}

or

ContourStyle -> Directive[Opacity[0.4], Pink]

Is there a way to combine both so that I can get a better visual of the volume of intersection?

reddit.com
u/Tensorizer — 16 days ago
▲ 5 r/vulkan

Optix denoiser requires with 32bit float(rgba32f in GLSL) whereas my Vulkan swapchain needs to work with VK_FORMAT_R8G8B8A8_UNORM (rgba8 in GLSL).

Is there a slick way to perform this conversion without injecting a compute shader into the mix?

reddit.com
u/Tensorizer — 18 days ago