3.4.2 JDK 示例参考
本节提供 JDK 多媒体处理库的实用示例。内容从基础 API 使用开始,逐步展示完整应用流水线。
基础示例
JDK 数据帧格式
JdkFrame
是各模块之间传递图像的统一数据结构:
class JdkFrame {
public:
JdkFrame(int dma_fd_, size_t size_, int w, int h);
~JdkFrame();
// 拷贝 DMA 缓冲区数据到主机内存并返回指针
unsigned char* toHost() const;
// 克隆数据至 vector
std::vector<unsigned char> Clone() const;
// 手动释放映射(如有必要)
// 保存为 YUV NV12 格式文件
bool saveToFile(const std::string& filename) const;
bool loadFromFile(const std::string& filename, size_t expected_size);
int getDMAFd() const;
size_t getSize() const { return size_; }
int getWidth() const { return width_; }
int getHeight() const { return height_; }
int MemCopy(const uint8_t* nalu, int nalu_size, int offset = 0);
private:
size_t size_; // 数据总大小,NV12格式宽高相关
int width_;
int height_;
JdkDma dma_;
std::shared_ptr<JdkDmaBuffer> data;
};
MIPI 摄像头采集 (JdkCamera
)
// 打开摄像节点
auto camera = JdkCamera::create("/device/video50", 1920, 1080, V4L2_PIX_FMT_NV12);
// 获取一帧数据
auto frame = camera->getFrame();
编码(JdkEncoder
)
// 创建编码器
auto encoder = std::make_shared<JdkEncoder>(width, height, CODING_H264, PIXEL_FORMAT_NV12);
// 对单帧数据进行编码
auto encodedFrame = encoder->Encode(jdkFrame);
解码(JdkDecoder
)
// 创建解码器
auto decoder = std::make_shared<JdkDecoder>(width, height, CODING_H264, PIXEL_FORMAT_NV12);
// 对单帧数据进行解码
auto decodedFrame = decoder->Decode(jdkFrame);
图像处理(JdkV2D
)
// 创建 V2D 模块实例
auto v2d = std::make_shared<JdkV2D>();
// NV12 转换为 RGB8888 格式
auto rgba_frame = v2d->convert_format(input_nv12, V2D_FMT_RGB888);
// 绘制单个矩形框
v2d->draw_rect(input_nv12, box, 0xFFFFFF00, 4); // 黄色,线宽4
// 绘制多个矩形框
v2d->draw_rects(input_nv12, {{30, 20, 100, 80}, {60, 40, 200, 160}}, 0x00ffcc66, 4); // 线宽4
// 对帧数据缩放
auto resized_frame = v2d->resize(jdkFrame, 1920, 1080);
// 同时缩放并格式转换
auto converted_frame = v2d->resize_and_convert(jdkFrame, 1920, 1080, V2D_FMT_RGB888);
SDL 显示(JdkVo
)
// 创建视频输出(VO)对象
auto jdkvo = std::make_shared<JdkVo>(width, height, PIXEL_FORMAT_NV12);
// 显示一帧图像
auto ret = jdkvo->sendFrame(jdkFrame);
DRM 显示(JdkDrm
)
// 创建 DRM 对象
auto drm = std::make_shared<JdkDrm>(width, height, width, PixelFmt::NV12, "/dev/dri/card1");
// 显示一帧图像
auto ret = drm->sendFrame(jdkFrame1);
AI 推理(YOLOV8Det
)
// 创建算法推理引擎实例
auto engine = YOLOV8Det::create_infer("yolov8n.q.onnx", "onnx");
// 对帧数据进行推理
auto result = engine->commit(jdkFrame).get();
// 绘制推理结果
draw_nv12(jdkFrame, std::any_cast<YOLOV8Det::Objects>(result));
构建与运行示例
本节展示如何配置 SDK、编译模块以及运行示例程序。
JDK SDK 下载与安装
wget https://archive.spacemit.com/ros2/code/jdk_sdk.tar.gz
sudo tar xvf jdk_sdk.tar.gz
目录结构如下:
jdk_sdk
├── include
│ ├── data_type.hpp
│ ├── IConver.hpp
│ ├── IEngine.hpp
│ ├── IPlugin.hpp
│ ├── ITensor.hpp
│ ├── JdkCamera.hpp
│ ├── JdkDecoder.hpp
│ ├── JdkDma.hpp
│ ├── JdkDrm.hpp
│ ├── JdkEncoder.hpp
│ ├── JdkFrame.hpp
│ ├── jdk_log.h
│ ├── JdkUsbCam.hpp
│ ├── jdkV2d.hpp
│ ├── JdkVo.hpp
│ ├── json.hpp
│ └── Tensor.hpp
├── jdk_examples
│ ├── jdk_cam
│ ├── jdk_client
│ ├── jdk_drm
│ ├── jdk_frame
│ ├── jdk_infer
│ ├── jdk_infer@rtsp
│ ├── jdk_server
│ ├── jdk_usbcam
│ ├── jdk_v2d
│ ├── jdk_vdec
│ ├── jdk_venc
│ └── jdk_vo
├── ko
│ └── jdk_dma.ko
├── lib
│ ├── libengine.so
│ ├── libjdk_cam.so
│ ├── libjdk_dma.so
│ ├── libjdk_drm.so
│ ├── libjdk_frame.so
│ ├── libjdk_usbcam.so
│ ├── libjdk_v2d.so
│ ├── libjdk_vdec.so
│ ├── libjdk_venc.so
│ ├── libjdk_vo.so
│ ├── libnet_client.so
│ └── libnet_server.so
├── Makefile
└── README.md
示例说明
jdk_examples
├── jdk_cam # 摄像头模块
├── jdk_client # 客户端模块
├── jdk_drm # DRM 相关模块
├── jdk_frame # 帧处理模块
├── jdk_infer # 推理模块
├── jdk_infer@rtsp# 视频采集RTSP输出和并行推理
├── jdk_server # 服务端模块
├── jdk_v2d # 视频二维模块
├── jdk_vdec # 视频解码模块
├── jdk_venc # 视频编码模块
└── jdk_vo # 视频输出模块
编译示例程序
进入摄像头模块目录并编译示例:
cd jdk_sdk
make all