#include #include #include #include "behavior/behavior_event.h" #include "frame/frame.h" #include "node.h" #include "utils/simple_json.h" #include "../plugins/event_fusion/event_fusion_node.h" namespace rk3588 { namespace { SimpleJson ParseFusionConfig(const std::string& text) { SimpleJson config; std::string err; const bool ok = ParseSimpleJson(text, config, err); EXPECT_TRUE(ok) << err; return config; } TEST(EventFusionTest, AssignsStableEventIdAcrossFramesForSameTrackAndType) { EventFusionNode node; const std::string config_text = R"({ "id": "event_fusion" })"; SimpleJson config = ParseFusionConfig(config_text); NodeContext ctx; auto out = std::make_shared>(4, QueueDropStrategy::DropOldest); ctx.output_queues.push_back(out); ASSERT_TRUE(node.Init(config, ctx)); ASSERT_TRUE(node.Start()); auto frame1 = std::make_shared(); frame1->pts = 1000; frame1->behavior_events = std::make_shared(); { BehaviorEventItem item; item.type = BehaviorEventType::Fall; item.status = BehaviorEventStatus::Active; item.track_ids = {42}; item.source = "action_recog"; frame1->behavior_events->items.push_back(item); } auto frame2 = std::make_shared(); frame2->pts = 1100; frame2->behavior_events = std::make_shared(); { BehaviorEventItem item; item.type = BehaviorEventType::Fall; item.status = BehaviorEventStatus::Active; item.track_ids = {42}; item.source = "action_recog"; frame2->behavior_events->items.push_back(item); } EXPECT_EQ(static_cast(node.Process(frame1)), static_cast(NodeStatus::OK)); EXPECT_EQ(static_cast(node.Process(frame2)), static_cast(NodeStatus::OK)); ASSERT_EQ(frame1->behavior_events->items.size(), 1u); ASSERT_EQ(frame2->behavior_events->items.size(), 1u); EXPECT_GT(frame1->behavior_events->items[0].event_id, 0); EXPECT_EQ(frame1->behavior_events->items[0].event_id, frame2->behavior_events->items[0].event_id); } TEST(EventFusionTest, MarksEventEndedWhenSourceStopsEmittingIt) { EventFusionNode node; const std::string config_text = R"({ "id": "event_fusion" })"; SimpleJson config = ParseFusionConfig(config_text); NodeContext ctx; auto out = std::make_shared>(4, QueueDropStrategy::DropOldest); ctx.output_queues.push_back(out); ASSERT_TRUE(node.Init(config, ctx)); ASSERT_TRUE(node.Start()); auto frame1 = std::make_shared(); frame1->pts = 1000; frame1->behavior_events = std::make_shared(); { BehaviorEventItem item; item.type = BehaviorEventType::Intrusion; item.status = BehaviorEventStatus::Active; item.track_ids = {9}; item.source = "region_event"; item.region_id = "zone_a"; frame1->behavior_events->items.push_back(item); } auto frame2 = std::make_shared(); frame2->pts = 1300; frame2->behavior_events = std::make_shared(); EXPECT_EQ(static_cast(node.Process(frame1)), static_cast(NodeStatus::OK)); EXPECT_EQ(static_cast(node.Process(frame2)), static_cast(NodeStatus::OK)); ASSERT_EQ(frame2->behavior_events->items.size(), 1u); EXPECT_EQ(frame2->behavior_events->items[0].type, BehaviorEventType::Intrusion); EXPECT_EQ(frame2->behavior_events->items[0].status, BehaviorEventStatus::Ended); EXPECT_GT(frame2->behavior_events->items[0].event_id, 0); } } // namespace } // namespace rk3588