Skip to content

Commit b4228b6

Browse files
committed
Integrate PyroEnc support.
1 parent b23a593 commit b4228b6

13 files changed

+423
-42
lines changed

.gitmodules

+3
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,6 @@
4646
[submodule "third_party/sdl3"]
4747
path = third_party/sdl3
4848
url = https://github.com/libsdl-org/SDL
49+
[submodule "third_party/pyroenc"]
50+
path = third_party/pyroenc
51+
url = https://github.com/HansKristian-Work/pyroenc

assets/shaders/inc/srgb.h

+9-1
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,12 @@ mediump vec3 decode_srgb(mediump vec3 c)
99
return clamp(mix(pow_side, small_side, small), vec3(0.0), vec3(1.0));
1010
}
1111

12-
#endif
12+
mediump vec3 encode_srgb(mediump vec3 c)
13+
{
14+
bvec3 small = lessThanEqual(c, vec3(0.0031308));
15+
mediump vec3 small_side = c * 12.92;
16+
mediump vec3 pow_side = 1.055 * pow(c, vec3(1.0 / 2.4)) - 0.055;
17+
return clamp(mix(pow_side, small_side, small), vec3(0.0), vec3(1.0));
18+
}
19+
20+
#endif

assets/shaders/util/rgb_scale.comp

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#version 450
2+
layout(local_size_x = 8, local_size_y = 8) in;
3+
4+
layout(set = 0, binding = 0) uniform mediump sampler2D uImage;
5+
layout(set = 0, binding = 1) writeonly uniform mediump image2D uOutput;
6+
7+
layout(constant_id = 0) const bool ENCODE_SRGB = false;
8+
9+
#include "../post/lanczos2.h"
10+
#include "../inc/srgb.h"
11+
12+
layout(push_constant) uniform Registers
13+
{
14+
uvec2 resolution;
15+
vec2 inv_resolution;
16+
vec2 input_resolution;
17+
vec2 inv_input_resolution;
18+
float dither_strength;
19+
} registers;
20+
21+
#define D(x) ((x) - 0.5)
22+
const mediump float dither[] = float[](
23+
D(0.0625), D(0.5625), D(0.1875), D(0.6875),
24+
D(0.8125), D(0.3125), D(0.9375), D(0.4375),
25+
D(0.25), D(0.75), D(0.125), D(0.625),
26+
D(1.00), D(0.5), D(0.875), D(0.375));
27+
28+
void main()
29+
{
30+
uvec2 coord = gl_GlobalInvocationID.xy;
31+
if (all(lessThan(coord, registers.resolution)))
32+
{
33+
vec2 uv = (vec2(coord) + 0.5) * registers.inv_resolution;
34+
mediump vec3 rgb = lanczos2(uImage, uv * registers.input_resolution, registers.inv_input_resolution);
35+
36+
if (ENCODE_SRGB)
37+
rgb = encode_srgb(rgb);
38+
39+
rgb += dither[(coord.y & 3u) * 4 + (coord.x & 3u)] * registers.dither_strength;
40+
imageStore(uOutput, ivec2(coord), vec4(rgb, 1.0));
41+
}
42+
}

tests/video_encode_test.cpp

+43-5
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ int main()
2121
options.width = 640;
2222
options.height = 480;
2323
options.frame_timebase = { 1, 60 };
24+
options.encoder = "h264_pyro";
25+
options.low_latency = true;
26+
options.realtime = true;
2427

2528
if (!Vulkan::Context::init_loader(nullptr))
2629
return 1;
@@ -29,12 +32,8 @@ int main()
2932
Vulkan::Context ctx;
3033
ctx.set_system_handles(handles);
3134
if (!ctx.init_instance_and_device(nullptr, 0, nullptr, 0,
32-
#ifdef VK_ENABLE_BETA_EXTENSIONS
3335
Vulkan::CONTEXT_CREATION_ENABLE_VIDEO_ENCODE_BIT |
3436
Vulkan::CONTEXT_CREATION_ENABLE_VIDEO_H264_BIT))
35-
#else
36-
0))
37-
#endif
3837
{
3938
return 1;
4039
}
@@ -57,7 +56,42 @@ int main()
5756
LOGE("Failed to open /tmp/test.ogg.\n");
5857
#endif
5958

60-
if (!encoder.init(&device, "/tmp/test.mkv", options))
59+
struct CB : Granite::MuxStreamCallback
60+
{
61+
void set_codec_parameters(const pyro_codec_parameters &) override
62+
{
63+
LOGI("Setting codec parameters.\n");
64+
}
65+
66+
void write_video_packet(int64_t, int64_t, const void *data, size_t size, bool) override
67+
{
68+
if (fwrite(data, 1, size, file) != size)
69+
LOGE("Failed to write.\n");
70+
}
71+
72+
void write_audio_packet(int64_t pts, int64_t dts, const void *data, size_t size) override
73+
{
74+
LOGI("Got audio.\n");
75+
}
76+
77+
bool should_force_idr() override
78+
{
79+
return false;
80+
}
81+
82+
FILE *file = nullptr;
83+
} cb;
84+
85+
cb.file = fopen("/tmp/test.h264", "wb");
86+
if (!cb.file)
87+
{
88+
LOGE("Failed to open file.\n");
89+
return EXIT_FAILURE;
90+
}
91+
92+
encoder.set_mux_stream_callback(&cb);
93+
94+
if (!encoder.init(&device, nullptr, options))
6195
{
6296
LOGE("Failed to init codec.\n");
6397
return 1;
@@ -74,6 +108,8 @@ int main()
74108
"builtin://shaders/util/rgb_to_yuv.comp")->register_variant({})->get_program();
75109
shaders.chroma_downsample = device.get_shader_manager().register_compute(
76110
"builtin://shaders/util/chroma_downsample.comp")->register_variant({})->get_program();
111+
shaders.rgb_scale = device.get_shader_manager().register_compute(
112+
"builtin://shaders/util/rgb_scale.comp")->register_variant({})->get_program();
77113
auto pipe = encoder.create_ycbcr_pipeline(shaders);
78114

79115
for (unsigned i = 0; i < 1000; i++)
@@ -116,6 +152,8 @@ int main()
116152
device.next_frame_context();
117153
}
118154

155+
fclose(cb.file);
156+
119157
#ifdef HAVE_GRANITE_AUDIO
120158
Global::stop_audio_system();
121159
#endif

third_party/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,5 @@ if (GRANITE_VULKAN_SYSTEM_HANDLES AND GRANITE_RENDERER)
130130
# Custom integration, bypass all the noise.
131131
add_subdirectory(fsr2/src/ffx-fsr2-api/granite)
132132
endif()
133+
134+
add_subdirectory(pyroenc EXCLUDE_FROM_ALL)

third_party/pyroenc

Submodule pyroenc added at ab4169c

video/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,6 @@ endif()
1717
if (GRANITE_FFMPEG_VULKAN)
1818
target_compile_definitions(granite-video PRIVATE HAVE_FFMPEG_VULKAN)
1919
endif()
20+
target_link_libraries(granite-video PRIVATE pyroenc)
2021
target_include_directories(granite-video PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
2122
target_compile_definitions(granite-video PUBLIC HAVE_GRANITE_FFMPEG)

0 commit comments

Comments
 (0)