feat: multiple test patterns in testpattern node

V210.hpp: add fill_colorbars, fill_ire_ramp, fill_black, fill_white.
Shared fill_solid helper stamps the first line across all rows via
memcpy. Generic write_palette_line template handles both SMPTE and
IRE bar palettes. fill_frame kept as a backward-compat alias.

testpattern/main.cpp: read "pattern" from node config and dispatch
to the appropriate fill function (bars/ire/black/white).

build_graph: pass {"pattern","bars"} to testpattern node params.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
JohannesItten
2026-07-01 13:24:06 +03:00
parent 4245284382
commit 42507886fe
3 changed files with 74 additions and 11 deletions
+60 -4
View File
@@ -2,6 +2,7 @@
#include <array>
#include <cstddef>
#include <cstdint>
#include <cstring>
namespace dmf::v210 {
@@ -82,12 +83,67 @@ inline void write_bar_line(uint8_t* line, int width, uint32_t /*stride*/)
}
}
// Fill an entire frame buffer with color bars.
// Write one horizontal line of an arbitrary bar palette.
template<std::size_t N>
inline void write_palette_line(uint8_t* line, int width, const std::array<Color, N>& palette)
{
const int n = static_cast<int>(N);
const int blocks = width / 6;
for (int b = 0; b < blocks; b++) {
int x = b * 6;
auto color = [&](int px) -> const Color& {
return palette[static_cast<std::size_t>(px * n / width)];
};
const Color& c01 = color(x);
const Color& c23 = color(x + 2);
const Color& c45 = color(x + 4);
pack_block(line + b * 16,
c01, c01.y, color(x+1).y,
c23, c23.y, color(x+3).y,
c45, c45.y, color(x+5).y);
}
}
// Fill a frame with a solid color.
inline void fill_solid(uint8_t* buf, int width, int height, uint32_t stride, Color c)
{
const int blocks = width / 6;
for (int b = 0; b < blocks; b++)
pack_block(buf + b * 16, c, c.y, c.y, c, c.y, c.y, c, c.y, c.y);
for (int y = 1; y < height; y++)
std::memcpy(buf + static_cast<ptrdiff_t>(y) * stride, buf, blocks * 16);
}
// SMPTE 75% color bars.
inline void fill_colorbars(uint8_t* buf, int width, int height, uint32_t stride)
{
for (int y = 0; y < height; y++)
write_palette_line(buf + static_cast<ptrdiff_t>(y) * stride, width, SMPTE_BARS);
}
// IRE 11-step greyscale ramp.
inline void fill_ire_ramp(uint8_t* buf, int width, int height, uint32_t stride)
{
for (int y = 0; y < height; y++)
write_palette_line(buf + static_cast<ptrdiff_t>(y) * stride, width, IRE_BARS);
}
// 10-bit limited black (Y=64, Cb=Cr=512).
inline void fill_black(uint8_t* buf, int width, int height, uint32_t stride)
{
fill_solid(buf, width, height, stride, {64, 512, 512});
}
// 10-bit limited white (Y=940, Cb=Cr=512).
inline void fill_white(uint8_t* buf, int width, int height, uint32_t stride)
{
fill_solid(buf, width, height, stride, {940, 512, 512});
}
// Kept for backward compatibility.
inline void fill_frame(uint8_t* buf, int width, int height, uint32_t stride)
{
for (int y = 0; y < height; y++) {
write_bar_line(buf + static_cast<ptrdiff_t>(y) * stride, width, stride);
}
fill_colorbars(buf, width, height, stride);
}
inline void UYVYtoV210(uint8_t* src_buf, uint8_t* dst_buf, int width, int height, uint32_t src_stride, uint32_t dst_stride)