From df67da1ff8e6a1f59242aee942dbcfb3c9e1de8c Mon Sep 17 00:00:00 2001 From: itten Date: Sun, 19 Jul 2026 22:33:55 +0300 Subject: [PATCH] af_xdp tryout --- flow-graphs/2110-20.json | 2 ++ nodes/st2110in/main.cpp | 12 ++++++------ shared/ST2110Receiver.hpp | 22 +++++++++++++++++++--- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/flow-graphs/2110-20.json b/flow-graphs/2110-20.json index 2a9ac64..68d6700 100644 --- a/flow-graphs/2110-20.json +++ b/flow-graphs/2110-20.json @@ -5,6 +5,8 @@ "type": "2110", "params": { "interface": "eno1np0", + "backend": "af_xdp", + "af_xdp_zero_copy": false, "local_ip": "192.168.0.3", "sdp": "v=0\no=- 3150588975 5 IN IP4 192.168.0.2\ns=DeckLink IP/SDI HD (1): Video\nt=0 0\nm=video 16388 RTP/AVP 96\nc=IN IP4 239.255.197.181/255\na=source-filter:incl IN IP4 239.255.197.181 192.168.0.2\na=rtpmap:96 raw/90000\na=fmtp:96 sampling=YCbCr-4:2:2; depth=10; width=1920; height=1080; exactframerate=50; colorimetry=BT709; PM=2110GPM; SSN=ST2110-20:2017; TP=2110TPN;\na=ts-refclk:ptp=IEEE1588-2008:7C-2E-0D-FF-FE-A7-23-B6:127\na=mediaclk:direct=0\na=ssrc:1258156108 cname:EB02FE63F5DB433DA6739B90A9B67B02" } diff --git a/nodes/st2110in/main.cpp b/nodes/st2110in/main.cpp index 1fe16bd..b1844f1 100644 --- a/nodes/st2110in/main.cpp +++ b/nodes/st2110in/main.cpp @@ -103,10 +103,10 @@ class ST2110In : public NodeBase { return; } - log("SMPTE 2110-20 RX %s:%u from %s on %s local=%s %dx%d depth=%d @ %d/%d latency=%d index_mode=%s", + log("SMPTE 2110-20 RX %s:%u from %s on %s backend=%s local=%s %dx%d depth=%d @ %d/%d latency=%d index_mode=%s", cfg.mcast_ip.c_str(), cfg.udp_port, cfg.source_ip.c_str(), cfg.ifname.c_str(), - cfg.local_ip.c_str(), cfg.width, cfg.height, cfg.depth, cfg.fps_num, cfg.fps_den, - cfg.mxl_latency_frames, cfg.mxl_index_mode.c_str()); + cfg.backend.c_str(), cfg.local_ip.c_str(), cfg.width, cfg.height, cfg.depth, + cfg.fps_num, cfg.fps_den, cfg.mxl_latency_frames, cfg.mxl_index_mode.c_str()); try { MTLContext mtl(cfg); @@ -129,9 +129,9 @@ class ST2110In : public NodeBase { uint64_t last_report_frames = 0; auto last_report = std::chrono::steady_clock::now(); - log("MTL version=%s output_stride=%u input_stride=%u direct_v210=%d", mtl_version(), - video_stride, cfg.direct_v210() ? video_stride : uyvy_stride, - cfg.direct_v210() ? 1 : 0); + log("MTL version=%s port=%s output_stride=%u input_stride=%u direct_v210=%d", + mtl_version(), mtl.port_name().c_str(), video_stride, + cfg.direct_v210() ? video_stride : uyvy_stride, cfg.direct_v210() ? 1 : 0); while (g_running.load(std::memory_order_relaxed)) { st_frame* frame = st20p_rx_get_frame(rx.get()); diff --git a/shared/ST2110Receiver.hpp b/shared/ST2110Receiver.hpp index 081c5b9..a11b7a5 100644 --- a/shared/ST2110Receiver.hpp +++ b/shared/ST2110Receiver.hpp @@ -40,6 +40,8 @@ struct ST2110ReceiverConfig { int framebuff_cnt = 3; int mxl_latency_frames = 2; std::string mxl_index_mode = "rtp"; + std::string backend = "kernel"; + bool af_xdp_zero_copy = true; bool direct_v210() const { return depth == 10; } enum st20_fmt transport_fmt() const { @@ -232,6 +234,8 @@ inline ST2110ReceiverConfig parse_st2110_receiver_config(const nlohmann::json& c out.framebuff_cnt = cfg.value("framebuff_cnt", out.framebuff_cnt); out.mxl_latency_frames = cfg.value("mxl_latency_frames", out.mxl_latency_frames); out.mxl_index_mode = cfg.value("mxl_index_mode", out.mxl_index_mode); + out.backend = cfg.value("backend", out.backend); + out.af_xdp_zero_copy = cfg.value("af_xdp_zero_copy", out.af_xdp_zero_copy); if (out.width <= 0 || out.height <= 0) { throw std::runtime_error("width and height must be positive"); @@ -257,6 +261,9 @@ inline ST2110ReceiverConfig parse_st2110_receiver_config(const nlohmann::json& c if (out.mxl_index_mode != "rtp" && out.mxl_index_mode != "live") { throw std::runtime_error("mxl_index_mode must be 'rtp' or 'live'"); } + if (out.backend != "kernel" && out.backend != "af_xdp") { + throw std::runtime_error("backend must be 'kernel' or 'af_xdp'"); + } return out; } @@ -267,16 +274,25 @@ public: mtl_init_params params{}; params.num_ports = 1; - port_name_ = "kernel:" + cfg.ifname; + if (cfg.backend == "kernel") { + port_name_ = "kernel:" + cfg.ifname; + params.pmd[MTL_PORT_P] = MTL_PMD_KERNEL_SOCKET; + } else if (cfg.backend == "af_xdp") { + port_name_ = "native_af_xdp:" + cfg.ifname; + params.pmd[MTL_PORT_P] = MTL_PMD_NATIVE_AF_XDP; + if (!cfg.af_xdp_zero_copy) { + params.flags |= MTL_FLAG_AF_XDP_ZC_DISABLE; + } + } + std::snprintf(params.port[MTL_PORT_P], sizeof(params.port[MTL_PORT_P]), "%s", port_name_.c_str()); - params.pmd[MTL_PORT_P] = MTL_PMD_KERNEL_SOCKET; params.net_proto[MTL_PORT_P] = MTL_PROTO_STATIC; params.rx_queues_cnt[MTL_PORT_P] = 1; params.tx_queues_cnt[MTL_PORT_P] = 0; params.log_level = MTL_LOG_LEVEL_INFO; - params.flags = MTL_FLAG_DEV_AUTO_START_STOP; + params.flags |= MTL_FLAG_DEV_AUTO_START_STOP; st2110_set_ip(params.sip_addr[MTL_PORT_P], cfg.local_ip); handle_ = mtl_init(¶ms);