帧策略职责明确
This commit is contained in:
@@ -51,7 +51,7 @@ void configure_manual_pixel_delivery(const std::shared_ptr<Plot>& plot) {
|
||||
void schedule_manual_frame(const std::shared_ptr<Plot>& plot,
|
||||
std::uint64_t correlation_sequence) {
|
||||
const auto now = Clock::now();
|
||||
plot->schedule_render(Plot_Render_Tick{
|
||||
plot->schedule_render(Frame_Request{
|
||||
.issued_at = now,
|
||||
.sequence = correlation_sequence,
|
||||
.time_milliseconds =
|
||||
@@ -64,7 +64,7 @@ void schedule_manual_frame(const std::shared_ptr<Plot>& plot,
|
||||
}
|
||||
|
||||
TEST(Gallery_Video_Stream,
|
||||
Encodes_Each_Plots_Independent_Policy_Frames_Without_Grouping) {
|
||||
Publication_Feedback_Task_Releases_Each_Plots_Independent_Frame) {
|
||||
const auto definitions = gallery_plot_definitions();
|
||||
const auto found = std::ranges::find_if(
|
||||
definitions, [](const Plot_Definition& definition) {
|
||||
@@ -82,26 +82,42 @@ TEST(Gallery_Video_Stream,
|
||||
constexpr std::size_t frame_count{5};
|
||||
std::array<std::atomic_uint64_t, frame_count> sequences{};
|
||||
std::atomic_size_t received{};
|
||||
std::atomic<std::shared_ptr<const Encoded_Video_Frame>> outstanding{};
|
||||
const auto subscription = stream->subscribe(
|
||||
"gallery-video-test",
|
||||
[&](Gallery_Stream_Frame frame) {
|
||||
if (!frame.video) return;
|
||||
if (!frame.video) return false;
|
||||
const auto index = received.fetch_add(
|
||||
1, std::memory_order_acq_rel);
|
||||
if (index < sequences.size())
|
||||
sequences[index].store(
|
||||
frame.video->sequence, std::memory_order_release);
|
||||
outstanding.store(std::move(frame.video),
|
||||
std::memory_order_release);
|
||||
return true;
|
||||
},
|
||||
[] { return true; },
|
||||
[] { return nlohmann::json::object(); });
|
||||
|
||||
const std::array<std::shared_ptr<Plot>, frame_count> schedule{
|
||||
plot_a, plot_a, plot_b, plot_a, plot_b};
|
||||
stream->request_taskflow_trace(1);
|
||||
for (std::size_t index = 0; index < schedule.size(); ++index) {
|
||||
const auto published_before = schedule[index]->diagnostics()
|
||||
.at("frame_policy").at("lifecycle")
|
||||
.at("published_frame_count").get<std::uint64_t>();
|
||||
schedule_manual_frame(schedule[index], index + 1U);
|
||||
ASSERT_NO_THROW(corun_until_or_throw("encoded Plot frame", [&] {
|
||||
return received.load(std::memory_order_acquire) > index;
|
||||
}));
|
||||
ASSERT_NO_THROW(corun_until_or_throw(
|
||||
"frame policy publication feedback", [&] {
|
||||
const auto diagnostics = schedule[index]->diagnostics();
|
||||
return diagnostics.at("frame_lifecycle") == "ready" &&
|
||||
diagnostics.at("frame_policy").at("lifecycle")
|
||||
.at("published_frame_count") > published_before;
|
||||
}));
|
||||
outstanding.store({}, std::memory_order_release);
|
||||
}
|
||||
|
||||
EXPECT_EQ(received.load(std::memory_order_acquire), frame_count);
|
||||
@@ -114,6 +130,24 @@ TEST(Gallery_Video_Stream,
|
||||
EXPECT_EQ(diagnostics.at("encoded_frame_count"), frame_count);
|
||||
EXPECT_EQ(diagnostics.at("pending_frame_count"), 0U);
|
||||
|
||||
ASSERT_NO_THROW(corun_until_or_throw("gallery Taskflow trace", [&] {
|
||||
return stream->taskflow_trace().value("complete", false);
|
||||
}));
|
||||
const auto trace = stream->taskflow_trace();
|
||||
ASSERT_EQ(trace.at("frames").size(), 1U);
|
||||
const auto& graphs = trace.at("frames").front().at("graphs");
|
||||
const auto graph = std::ranges::find_if(graphs, [](const auto& value) {
|
||||
return value.value("name", std::string{}) == "gallery.video.frame";
|
||||
});
|
||||
ASSERT_NE(graph, graphs.end());
|
||||
const auto& nodes = graph->at("nodes");
|
||||
const auto feedback = std::ranges::find_if(nodes, [](const auto& value) {
|
||||
return value.value("name", std::string{}) ==
|
||||
"frame.policy.publish.feedback";
|
||||
});
|
||||
ASSERT_NE(feedback, nodes.end());
|
||||
EXPECT_EQ(feedback->at("attributes").at("owner"), "frame_policy");
|
||||
|
||||
stream->unsubscribe(subscription);
|
||||
stream->shutdown();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user