Skip to content

Commit

Permalink
Add most basic way of piping through PQ video encoding.
Browse files Browse the repository at this point in the history
No metadata implemented yet.
  • Loading branch information
Themaister committed Nov 21, 2024
1 parent 7543863 commit b2dd359
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 8 deletions.
11 changes: 5 additions & 6 deletions assets/shaders/util/rgb_to_yuv.comp
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,10 @@ layout(push_constant) uniform Registers
float dither_strength;
} registers;

// BT709. Row-major.
const mediump mat3 rgb_to_yuv = mat3(
vec3(0.2126, 0.7152, 0.0722),
vec3(-0.114572, -0.385428, 0.5),
vec3(0.5, -0.454153, -0.0458471));
layout(set = 0, binding = 3) uniform Transform
{
mat3 rgb_to_yuv;
};

#define D(x) ((x) - 0.5)
const mediump float dither[] = float[](
Expand All @@ -46,4 +45,4 @@ void main()
imageStore(uLuma, ivec2(coord), ycbcr.xxxx);
imageStore(uChroma, ivec2(coord), ycbcr.yzyz);
}
}
}
30 changes: 28 additions & 2 deletions video/ffmpeg_encode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1014,8 +1014,18 @@ bool VideoEncoder::Impl::init_video_codec_av(const AVCodec *codec)
}

video.av_ctx->color_range = AVCOL_RANGE_MPEG;
video.av_ctx->colorspace = AVCOL_SPC_BT709;
video.av_ctx->color_primaries = AVCOL_PRI_BT709;

if (options.hdr10)
{
video.av_ctx->colorspace = AVCOL_SPC_BT2020_NCL;
video.av_ctx->color_primaries = AVCOL_PRI_BT2020;
video.av_ctx->color_trc = AVCOL_TRC_SMPTE2084; // PQ
}
else
{
video.av_ctx->colorspace = AVCOL_SPC_BT709;
video.av_ctx->color_primaries = AVCOL_PRI_BT709;
}

switch (options.siting)
{
Expand Down Expand Up @@ -1736,6 +1746,22 @@ void VideoEncoder::process_rgb(Vulkan::CommandBuffer &cmd, YCbCrPipeline &pipeli
push.dither_strength = pipeline.constants.dither_strength;
cmd.push_constants(&push, 0, sizeof(push));

auto *color_transform = cmd.allocate_typed_constant_data<vec4>(0, 3, 3);

// Minimal crude implementation to get something HDR10 working.
if (impl->options.hdr10)
{
color_transform[0] = vec4(0.2627f, 0.678f, 0.0593f, 0.0f);
color_transform[1] = vec4(-0.13963f, -0.36037f, 0.5f, 0.0f);
color_transform[2] = vec4(0.5f, -0.459786f, -0.0402143f, 0.0f);
}
else
{
color_transform[0] = vec4(0.2126f, 0.7152f, 0.0722f, 0.0f);
color_transform[1] = vec4(-0.114572f, -0.385428f, 0.5f, 0.0f);
color_transform[2] = vec4(0.5f, -0.454153f, -0.0458471f, 0.0f);
}

auto start_yuv_ts = cmd.write_timestamp(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
cmd.dispatch(pipeline.constants.luma_dispatch[0], pipeline.constants.luma_dispatch[1], 1);
auto end_yuv_ts = cmd.write_timestamp(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
Expand Down
1 change: 1 addition & 0 deletions video/ffmpeg_encode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class VideoEncoder
bool realtime = false;
const char *encoder = "libx264";
bool low_latency = false;
bool hdr10 = false;

struct
{
Expand Down

0 comments on commit b2dd359

Please sign in to comment.