NDI入门教程二

一、移植到RK:

编译相关:
ndi本身没有什么好移植编译的,本身提供的就是so库。但是ndi依赖其它第三方开源库:
avahi; dbus; expat; libcap; libdameon。因为编译这些开源库的服务器也需要安装一些插件所以在自己虚拟机Ubuntu20.04上编译好so,再把so库打包到rootfs目录, 都是开源的读者可以自行下载对应版本就行编译。
目录结构:
 

xxx@xxx-VirtualBox:~/work/rk3588$ ls
avahi               build_spi_nand.sh  mkfirmware.sh                                     rockdev
build               docs               NDI_Advanced_SDK_v5_Linux                         tinyalsa_new
build_all.sh_bk     fdk-aac            note.sh                                           tools
build_avahi_all.sh  IMAGE              RK3588_LINUX_NVR_SDK_Release_V1.4.0_20221021.tgz  u-boot
build_emmc.sh       kernel             rkbin

交叉编译遇到很多问题,这里提供一键编译脚步,编译结果cp到rootfs相应目录:
build_avahi_all.sh 编译脚本:


#!/bin/sh

usage()
{
   echo "USAGE: [-A] [-D] [-E] [-C]  [-L] [-N] [-R]"
    echo "No ARGS means use default build option                  "
    echo "WHERE: -A = build avahi                                 "
    echo "       -D = build dbus                     "
    echo "       -E = build expat                                "
    echo "       -C = build libcap                               "
        echo "       -L = build libdaemon                             "
        echo "       -N = build ndi                             "
        echo "       -R = build libdaemon                             "
    exit 1
}

CODE_PATH=$PWD

BUILD_AVAHI=false
BUILD_DBUS=false
BUILD_EXPAT=false
BUILD_CAP=false
BUILD_DAEMON=false
BUILD_NDI=false
BUILD_CLEAN_FLAG=false

BUILD_JOBS=8
# check pass argument
while getopts "ADECLNR" arg
do
    case $arg in
        A)
            echo "will build avahi"
            BUILD_AVAHI=true
            ;;
        D)
            echo "will dbus"
            BUILD_DBUS=true
            ;;
        E)
            echo "will build expat"
            BUILD_EXPAT=true
            ;;
        C)
            echo "will build libcap"
            BUILD_CAP=true
            ;;
        L)
            echo "will build libdaemon"
            BUILD_DAEMON=true
            ;;
        N)
            echo "will build ndi"
            BUILD_NDI=true
            ;;                        
        R)
            echo "will clean"
            BUILD_CLEAN_FLAG=true
            ;;                        
        ?)
            usage ;;
    esac
done

# set env
echo "start set env.................."
declare -x PATH=$CODE_PATH/build//toolchain/bin/:$PATH
export PATH
declare -x CROSS_COMPILE="aarch64-none-linux-gnu-"
declare -x ARCH="arm64"
${CROSS_COMPILE}gcc -v
echo "end set env.................."

# build libdaemon-0.14
if [ "$BUILD_DAEMON" = true ] ; then
echo "start build libdaemon-0.14................."
if [ "$BUILD_CLEAN_FLAG" = true ] ; then
        echo "start clean && build libdaemon-0.14"
    cd avahi/libdaemon-0.14
        mkdir _install
        make clean
        ./configure \
        CC=aarch64-none-linux-gnu-gcc \
        CXX=aarch64-none-linux-gnu-g++ \
        --host=arm-none-linux \
        --prefix=$(pwd)/_install \
        ac_cv_func_setpgrp_void=yes
        make -j$BUILD_JOBS
        make install

else
        echo "start build libdaemon-0.14"
fi

if [ $? -eq 0 ]; then
    echo "Build libdaemon-0.14 ok!"
else
    echo "Build libdaemon-0.14 failed!"
    exit 1
fi
cd -
fi

# build libcap
if [ "$BUILD_CAP" = true ] ; then
echo "start build libcap-2.25................."
if [ "$BUILD_CLEAN_FLAG" = true ] ; then
        echo "start clean && build libcap"
    cd avahi/libcap-2.25
        mkdir _install
        make clean
        make -j$BUILD_JOBS
        make DESTDIR=$(pwd)/_install install

else
    cd avahi/libcap-2.25
        mkdir _install
        make -j$BUILD_JOBS
        make DESTDIR=$(pwd)/_install install
fi

if [ $? -eq 0 ]; then
    echo "Build libcap-2.25 ok!"
else
    echo "Build libcap-2.25 failed!"
    exit 1
fi
cd -
fi


# build expat
if [ "$BUILD_EXPAT" = true ] ; then
echo "start build expat-2.4.8................."
if [ "$BUILD_CLEAN_FLAG" = true ] ; then
        echo "start clean && build expat-2.4.8"
    cd avahi/expat-2.4.8
        mkdir _install
        ./configure \
        CC=aarch64-none-linux-gnu-gcc \
        CXX=aarch64-none-linux-gnu-g++ \
        --host=aarch64-none-linux \
        --prefix=$(pwd)/_install \
        ac_cv_func_setpgrp_void=yes\
        --enable-shared=no\
        --enable-static=yes
        make clean
        make -j$BUILD_JOBS
        make install

else
    cd avahi/expat-2.4.8
        mkdir _install
        ./configure \
        CC=aarch64-none-linux-gnu-gcc \
        CXX=aarch64-none-linux-gnu-g++ \
        --host=aarch64-none-linux \
        --prefix=$(pwd)/_install \
        ac_cv_func_setpgrp_void=yes\
        --enable-shared=no\
        --enable-static=yes
        make -j$BUILD_JOBS
        make install
fi

if [ $? -eq 0 ]; then
    echo "Build expat-2.4.8 ok!"
else
    echo "Build expat-2.4.8 failed!"
    exit 1
fi
cd -
fi


# build dbus-1.12.16
if [ "$BUILD_DBUS" = true ] ; then
echo "start build dbus-1.12.16................."
if [ "$BUILD_CLEAN_FLAG" = true ] ; then
        echo "start clean && build dbus-1.12.16"
    cd avahi/dbus-1.12.16
        mkdir _install
        make clean
        ./configure \
        CC=aarch64-none-linux-gnu-gcc \
        CXX=aarch64-none-linux-gnu-g++ \
        --host=aarch64-linux  \
        --enable-systemd=no \
        --enable-selinux=no \
        --with-x=no \
        --enable-tests=no \
        EXPAT_CFLAGS="-I$CODE_PATH/avahi/expat-2.4.8/_install/include" \
        EXPAT_LIBS="$CODE_PATH/avahi/expat-2.4.8/_install/lib/libexpat.a" \
        --with-session-socket-dir=/var/run/dbus \
        --with-system-socket=/var/run/dbus/system_bus_socket \
        --with-system-pid-file=/var/run/dbus/pid \
        --prefix=/usr/avahi/dbus-1.12.16/_install
        make -j$BUILD_JOBS
        make install

else
        echo "start build dbus-1.12.16"
fi
if [ $? -eq 0 ]; then
    echo "Build dbus-1.12.16 ok!"
else
    echo "Build dbus-1.12.16 failed!"
    exit 1
fi
cd -
fi


# build avahi
if [ "$BUILD_AVAHI" = true ] ; then
echo "start build avahi-0.8................."
if [ "$BUILD_CLEAN_FLAG" = true ] ; then
        echo "start clean && build avahi-0.8"
    cd avahi/avahi-0.8
        mkdir _install
        make clean
        ./configure \
        CC=aarch64-none-linux-gnu-gcc \
        CXX=aarch64-none-linux-gnu-g++ \
        --host=aarch64-none-linux-gnu \
        --with-xml=expat \
        --disable-qt3 \
        --disable-qt4 \
        --disable-qt5 \
        --disable-mono \
        --disable-libevent \
        --with-distro=none \
        --disable-glib \
        --disable-gobject \
        --disable-gtk \
        --disable-gtk3 \
        --disable-gdbm \
        --disable-python \
        --disable-python-dbus \
        CFLAGS="-I$CODE_PATH/avahi/expat-2.4.8/_install/include -I/usr/avahi/dbus-1.12.16/_install/include  -I$CODE_PATH/avahi/libcap-2.25/_install/usr/include" \
        LDFLAGS="-L/usr/avahi/dbus-1.12.16/_install/lib -L$CODE_PATH/avahi/expat-2.4.8/_install/lib  -L$CODE_PATH/avahi/libcap-2.25/_install/lib64" \
        LIBDAEMON_CFLAGS="-I$CODE_PATH/avahi/libdaemon-0.14/_install/include" \
        LIBDAEMON_LIBS="$CODE_PATH/avahi/libdaemon-0.14/_install/lib/libdaemon.a" \
        ac_cv_header_sys_capability_h=yes \
        --prefix=/usr/avahi/avahi-0.8/_install

        make -j$BUILD_JOBS
        make install

else
        echo "start build avahi-0.8"
fi
if [ $? -eq 0 ]; then
    echo "Build  avahi-0.8ok!"
else
    echo "Build avahi-0.8 failed!"
    exit 1
fi
cd -
fi

#buid ndi examples
if [ "$BUILD_NDI" = true ] ; then
echo "start build ndi................."
if [ "$BUILD_CLEAN_FLAG" = true ] ; then
        echo "start clean && build ndi"
        cd  NDI_Advanced_SDK_v5_Linux/examples/C++
        make NDILIB=aarch64-rockchip-linux-gnu CC=aarch64-none-linux-gnu-gcc CXX=aarch64-none-linux-gnu-g++ -j$BUILD_JOBS

else
        echo "build ndi"
fi

if [ $? -eq 0 ]; then
    echo "Build ndi ok!"
else
    echo "Build ndifailed!"
    exit 1
fi
cd -
fi


sync

mkdir -p build/rootfs/oem/lib
mkdir -p build/rootfs/oem/bin

# cp  libcap so
cp  avahi/libcap-2.25/_install/lib64/libcap.so.2.25 build/rootfs/oem/lib
cd build/rootfs/oem/lib
ln -s libcap.so.2.25 libcap.so.2
ln -s libcap.so.2.25 libcap.so
cd -
# cp  libdaemon so
cp avahi/libdaemon-0.14/_install/lib/libdaemon.so.0.5.0 build/rootfs/oem/lib
cd build/rootfs/oem/lib
ln -s libdaemon.so.0.5.0 libdaemon.so.0
ln -s libdaemon.so.0.5.0 libdaemon.so
cd -
# cp  libdbus so
cp avahi/dbus-1.12.16/_install/lib/libdbus-1.so.3.19.11 build/rootfs/oem/lib
cd build/rootfs/oem/lib
ln -s libdbus-1.so.3.19.11 libdbus-1.so.3
ln -s libdbus-1.so.3.19.11 libdbus-1.so
cd -
cp /usr/avahi/dbus-1.12.16/_install/bin/dbus-daemon build/rootfs/oem/bin

# cp  avahi so
cp avahi/avahi-0.8/_install/lib/libavahi-client.so.3.2.9 build/rootfs/oem/lib/
cp avahi/avahi-0.8/_install/lib/libavahi-common.so.3.5.3 build/rootfs/oem/lib/
cp avahi/avahi-0.8/_install/lib/libavahi-core.so.7.0.2 build/rootfs/oem/lib/
cd build/rootfs/oem/lib
ln -s libavahi-client.so.3.2.9 libavahi-client.so.3
ln -s libavahi-client.so.3.2.9 libavahi-client.so

ln -s libavahi-common.so.3.5.3 libavahi-common.so.3
ln -s libavahi-common.so.3.5.3 libavahi-common.so

ln -s libavahi-core.so.7.0.2 libavahi-core.so.7
ln -s libavahi-core.so.7.0.2 libavahi-core.so
cd -

cp /usr/avahi/avahi-0.8/_install/sbin/avahi-daemon build/rootfs/oem/bin

# cp  ndi sdk so
cp NDI_Advanced_SDK_v5_Linux/lib/aarch64-rockchip-linux-gnu/libndi.so.5.5.2  build/rootfs/oem/lib/
cd build/rootfs/oem/lib
ln -s libndi.so.5.5.2 libndi.so.5
ln -s libndi.so.5.5.2 libndi.so
cd -
cp NDI_Advanced_SDK_v5_Linux/examples/C++/NDIlib_Recv/NDIlib_Recv  build/rootfs/oem/bin/
cp NDI_Advanced_SDK_v5_Linux/examples/C++/NDIlib_Send_Video_and_Audio/NDIlib_Send_Video_and_Audio  build/rootfs/oem/bin/

cp /usr/avahi/avahi-0.8/_install/etc/dbus-1/system.d/avahi-dbus.conf /usr/avahi/dbus-1.12.16/_install/etc/dbus-1/system.conf
cp -rf /usr/avahi/ build/rootfs/usr/


sync

二、板端配置相关:

/etc/init.d/目录增加启动脚本S100_avahi:

#!/bin/sh

source /etc/profile.d/RkEnv.sh

echo "start avahi...................................."
/oem/bin/busybox adduser avahi -D -H
/oem/bin/busybox adduser messagebus -D -H
sync
cat /etc/group | grep avahi
if [ $? -eq 0 ]; then
    echo "Found!"
else
    echo "avahi:x:1001:" >> /etc/group
fi

export

sync
mkdir /var/run/dbus/ -p
/oem/bin/dbus-daemon --system --fork
/oem/bin/avahi-daemon &
#sleep 20 wait for net ready and system time ready.
sleep 20 && /oem/bin/ndi_send_h264_aac /oem/test.h264 /oem/qhc_48.wav &

RK3588 sdk bin目录自带的busybox 不带adduser 命令,需要自己下载重新编译一个。否则avahi和dbus跑不起来。
sleep 20的作用是等待网络获取到ip,以及系统时钟,avahi初始化。如果太早起来会失败,还有系统时间问题导致ndi so检测时间出错立马达到30分钟停止工作,免费版本只能使用30分钟。


三、NDI Demo使用:

普通版sdk裸数据发送:
windows打开 NDI 软件 -》点击 Studio Monitor -》Ubuntu 运行example的NDIlib_Send_Video_and_Audio -》在 Studio Monitor界面选择设备 -》windows看到画面和听到声音。
windows打开 NDI 软件 -》点击 Test Patterns -》Ubuntu 运行example的NDIlib_Send_Audio  -》看到打印信息。

四、高级版NDI Demo相关代码,开发测试程序:

背景:
  高级sdk只有一个发送demo,是基于数组的。
  我们最终是要发送h264和aac文件。需要编写一个读取aac,h264文件进行解码,解析,然后转换到ndi的数据结构再发送出去。
移植fdkaac开源库:
  这个比较简单网上很多。


编写发送h264,aac文件测试程序代码:
  代码路径:
  Z:\rk3588_linux_nvr\anker_3rdparty\NDI_Advanced_SDK_for_Linux\examples\C++_HX2\NDIlib_Send_H264
  编译:
#源码根目录 设置编译环境参数
CODE_PATH=$PWD
declare -x PATH=$CODE_PATH/build/toolchain/bin/:$PATH
export PATH
declare -x ARCH="arm64"
declare -x CROSS_COMPILE="aarch64-none-linux-gnu-"
#进入NDIlib_Send_H264目录编译
make -j8
  得到ndi_send_h264_aac ,运行:/oem/bin/ndi_send_h264_aac /oem/test.h264 /oem/qhc_48.wav &
  可以使用FFmpeg命令把mp4转成h264文件,如:
ffmpeg -i test.mp4 -codec copy -bsf: h264_mp4toannexb -f h264 test.h264
编写接收程序:
  代码位置:anker_3rdparty\NDI_Advanced_SDK_for_Linux\examples\C++_HX2\NDIlib_Recv_H264_AAC。
  高级sdk版本只有发送的demo,没有接收h264 aac的demo。只能自己看英文pdf和头文件去写 去试。
  遇到的问题:
  A. 接收的pcm数据保存成文件后,在audacity播放,声音不对,分析排查后发现ndi api接收到的audio frame的数据不是常用交错排列的pcm数据,而是先放channel_stride_in_bytes数据的通道1,再接着放channel_stride_in_bytes的通道2,以此类推,这是看头文件结构体猜,试出来的,英文pdf并没有介绍。
  B. 在自己虚拟机可以的程序,编译到rk3588 板子无法接收到音频数据。 通过排查分析和猜:编译器,运行环境等。把同样的代码在服务器编译测试现象一样。最后发现是ndi的so库会用dlopen方式加载FFmpeg相关的库去解码aac得到pcm数据。因为rk3588没有FFmpeg库所以导致ndi 库内部无法解码aac而且不会打印任何日志,导致我写的接收程序一直无法接收到音频数据。
  C. 因为存在B问题,而且我们不需要FFmpeg。接收端程序不是一定要接收pcm数据,可以接收aac数据然后用fdk-aac去解码得到pcm数据。查看pdf文档,可以设置参数直接接收aac数。但是接收到的数据保存文件无法在电脑上无法识别。通过分析发现接收到的数据没有adst头,手动添加adts头后电脑可以正确识别但是无法播放出声音。
  D. 分析无法播放出声音的问题。 通过dump数据和发送端对比,发现接收端接收到的audio frame数据比发送端多了44个字节+2字节。44字节不知道是ndi发送api加的还是接收api加的,2字节是发送端的extra data。保存成aac文件的时候去掉前面44字节和后面2字节的extra data即可,这样的aac文件就可以在电脑上播放了。
结合rk mpi,获取camera数据进行发送。camera -> venc -> ndi send。
  音频数据使用wav文件:
  ndi_send_camera_aac 3840 2160 60 /dev/video11 /oem/qhc_48.wav
  3840:x分辨率
  2160:y分辨率
  60: 帧率
  /dev/video11:camera设备节点命令
  /oem/qhc_48.wav: 要发送的wav文件

  音频数据使用声卡:
  ndi_send_camera_aac 3840 2160 60 /dev/video11
代码 rk3588_linux_nvr.git

六、测试:

ndi_send_camera_aac 程序发送4k 60帧 ,win10端接收预览,平均延时在150ms ~ 300ms。和画面变化有关和硬件编码器码率有关。

码率在1 ~ 6.5Mbps之间,和画面运动变化有关。

3. cpu使用率在1% ~5% 变化

内存:
开机后是82M,跑起ndi_send_camera_aac 后是338M, NDI库大概使用1M,大部分内存是RK MPI接口(camera,venc,isp)使用的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/634896.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

notepad++ 批量转所有文件编码格式为UTF-8

1、安装notepad及PythonScript_3.0.18.0插件 建议两者都保持默认路径安装x64版本: 阿里云盘分享https://www.alipan.com/s/xVUDpY8v5QL安装好后如下图: 2、new Script,新建脚本,文件名为ConvertEncoding 3、自动打开脚本&#xff…

Jenkins 动态salve简单配置连接 EKS

安装Jenkins helm repo add jenkins https://charts.jenkins.io helm repo update # 当前版本 jenkins-5.1.18.tgz瘦身后的 values.yaml # grep -Ev ^\s*#|^$ values.yaml nameOverride: fullnameOverride: namespaceOverride: clusterZone: "cluster.local" kubern…

(Oracle)SQL优化基础(三):看懂执行计划顺序

往期内容: (Oracle)SQL优化基础(一):获取执行计划 (Oracle)SQL优化基础(二):统计信息 获取到执行计划后,对于新手朋友来讲可能不知道…

火箭升空AR虚拟三维仿真演示满足客户的多样化场景需求

在航空工业的协同研发领域,航空AR工业装配系统公司凭借前沿的AR增强现实技术,正引领一场革新。通过将虚拟信息无缝融入实际环境中,我们为工程师、设计师和技术专家提供了前所未有的共享和审查三维模型的能力,极大地提升了研发效率…

【华为】BFD与静态路由和RIP联用

【华为】BFD与静态路由和RIP联用 实验需求配置AR1AR2AR3AR4效果抓包查看 实验需求 如上图组网所示,在R1上配置到达R4的Loopback0。 4.4.4.4/32网段的浮动静态路由,正常情况下通过R3访问R4。 当R3故障时,自动选路通过R2访问R4的Loopback0;在R…

企业文件加密软件推荐:迅软DSE加密软件你用了吗?

一、挑选企业文件加密软件需考虑的因素? 1、安全性:软件应采用业界认可的强加密算法,以确保数据的安全性。 迅软特有的256位高强度加密算法,从根本上阻止一切破解的可能性。 2、易用性:软件应该易于部署和管理&…

如何停止 iPad 和 iPhone 之间共享短信,独立接收和发送消息

概括 在当今高度互联的数字世界中,Apple 设备之间的无缝连接性提供了极大的便利,尤其是在消息同步方面。iPhone 和 iPad 用户通常可以享受到设备间短信的自动同步功能,这意味着无论是在哪个设备上,用户都可以接收和回复消息。然而…

游戏联运的挑战与核心关键点

​游戏联运一个看似充满机遇与挑战的行业,吸引了很多创业者的加入。然而,真正踏入这个行业后,许多人会发现,手游代理并非想象中的那么简单。今天,溪谷软件就来和大家聊聊游戏联运是怎么做的,需要注意什么。…

react中的useEffect()的使用

useEffect()是react中的hook函数,作用是用于创建由渲染本身引起的操作,而不是事件的触发,比如Ajax请求,DOM的更改 首先useEffect()是个函数,接受两个参数,第一个参数是一个方法,第二个参数是数…

《计算机体系结构》期末考试复习笔记(一)试卷手写笔记(超重点)

一、MIPS 执行速率执行时间有效CPI【第1题】 二、Amdahl定律 - 性能加速比SP【第2题,第3题,第4题】 (百分比f 倍数r ) 三、哈夫曼编码 2-4扩展码【第5题】 四、互连函数【第9题】 就是每生成一个根节点, 就从小到大重新排…

后量子密码解决方案

什么是后量子密码学 (PQC),为什么准备工作如此重要? 量子计算正在迅速发展;用不了多久,量子网络攻击就会成为可能。量子网络攻击将能够在几分钟内瘫痪大型网络。我们今天赖以保护我们的连接和交易的一切都将受到量子计算机的威胁,危及所有密…

【618狂欢】五款必抢好物!爆款数码好物让你轻松get新潮流!

随着科技的飞速发展,数码产品已经成为我们生活中不可或缺的一部分。它们不仅为我们提供了便捷的生活体验,更成为了我们展示个性和追求潮流的重要载体。而在每年的618购物狂欢节,各大电商平台都会推出众多优惠活动,让我们有机会以更…

Linux——进程信号

目录 一、信号的理解 二、信号的种类 2.1 标准信号 (1-31) 2.2 实时信号 (通常是34及以上) 三、信号的产生 3.1 用户通过终端产生信号 3.1.1 signal 函数 3.1.2 demo 测试 3.1.3 demo 现象 3.2 通过系统函数产生信号 3.2.1 demo 测试 3.3 由软件条件产生信号 3.3.1…

访问列表元素

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 在Python中,如果想将列表的内容输出也比较简单,可以直接使用print()函数即可。例如,创建一个名称为untitle的列表…

JAVA开发 基础Jaccard来计算两个字符串之间的重复率

计算两个字符串之间的重复率 Jaccard实现代码基于最长公共子序列来计算两个字符串之间的重复率 Jaccard Jaccard方法,也称为Jaccard相似度或Jaccard相似系数,是一种用于衡量两个集合相似程度的指标。其逻辑基于集合之间的交集与并集的关系来衡量它们的相…

Linux bc命令(bc指令)(基本计算器)(任意精度计算语言:支持浮点数运算、变量赋值和自定义函数等)

文章目录 bc命令文档英文中文 Linux bc 命令详解bc 命令的基本用法启动 bc 环境进行基本计算退出 bc bc 中的数学功能执行高级数学计算平方根和指数函数对数函数 处理精度问题 变量和数组变量赋值和使用数组的使用 创建和使用自定义函数 bc 命令的高级用法在脚本中使用 bc基本脚…

注解大全更新中~

Slf4j 是什么:Slf4j 是 Lombok 提供的一种注解,用于在类中自动生成一个名为 log 的日志对象。通过使用 Slf4j 注解,可以方便地在代码中使用日志功能,而无需手动创建和初始化日志对象。 怎么用: 1.导入依赖的包lombok…

uniapp移动端骨架屏流程

1.使用微信开发者工具来生成骨架屏;在分窗模式下选择页面信息,下拉选择生成骨架屏;他会基于当前页面生成骨架屏的样式 点击确定; 会自动生成这两个文件;一个是html结构文件,一个是css样式文件。 然后把这两…

R语言使用 ggscidca包优雅的绘制支持向量机决策曲线

DCA(Decision Curve Analysis)临床决策曲线是一种用于评价诊断模型诊断准确性的方法,在2006年由AndrewVickers博士创建,我们通常判断一个疾病喜欢使用ROC曲线的AUC值来判定模型的准确性,但ROC曲线通常是通过特异度和敏感度来评价,…

一文读懂RDMA: Remote Direct Memory Access(远程直接内存访问)

目录 ​编辑 引言 一、RDMA的基本原理 二、RDMA的主要特点 三、RDMA的编程接口 四、RDMA的代码演示 服务器端代码: 客户端代码: 五、总结 引言 RDMA,全称Remote Direct Memory Access,即远程直接内存访问,是…