# ema-media-shm-stream **Repository Path**: ematech/ema-media-shm-stream ## Basic Information - **Project Name**: ema-media-shm-stream - **Description**: 基于 EMA Media Service 共享内存订阅机制,实现完整的数据流消费链路: - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-04-24 - **Last Updated**: 2026-06-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # shm_stream_demo - 共享内存数据流订阅 + 硬解码 Demo ## 功能说明 基于 EMA Media Service 共享内存订阅机制,实现完整的数据流消费链路: **gRPC 订阅 → 共享内存接收 → 硬解码 → 输出保存** ## 目录结构 ``` shm_stream_demo/ ├── CMakeLists.txt # CMake 构建配置 ├── build.sh # 本地构建脚本 ├── docker_compile.sh # Docker 交叉编译脚本 ├── app.conf # 打包配置(构建时自动复制到 release/) ├── src/main.cpp # 主程序 ├── proto/ # Proto 文件 │ ├── mediaResult.proto │ ├── aipaasCommon.proto │ ├── github.com/gogo/protobuf/gogoproto/gogo.proto │ └── ema_ipc/ # ema_ipc 内部 proto ├── include/ # 头文件 │ ├── xmpp/ # XMPP 硬解码库头文件 │ ├── ema_ipc/ # ema_ipc 共享内存库头文件 │ ├── grpc/ # gRPC 头文件 │ ├── grpc++/ # gRPC++ 头文件 │ └── boost/ # Boost 头文件 ├── tool/run.sh # 发布包运行脚本 ├── lib/ascend310b1/ # 预编译库 │ ├── libxmpp.so # XMPP 硬解码库 │ ├── libema_ipc.so # 共享内存 IPC 库 │ ├── libgrpc++.so # gRPC 库 │ ├── libprotobuf.so # Protobuf 库 │ ├── libboost_*.so # Boost 库 │ └── liblog4cpp.so # log4cpp 库 └── conf/ └── ipc.pb.conf # ema_ipc 配置文件 ``` ## 构建 ### 本地构建(需要安装依赖) ```bash ./build.sh ``` ### Docker 交叉编译(推荐) ```bash ./docker_compile.sh -p ascend310-gcc10.3.0-sdk7.0.rc1 -e ./build.sh ``` ### 构建托管服务 Docker 镜像 使用 `packet.sh` 将编译好的程序打包为符合 PaaS 平台规范的 Docker 镜像。`app.conf` 位于项目根目录,`build.sh` 会自动将其复制到 `release/`。 **app.conf 格式:** ```ini app_name=shm_stream_demo version=1.0.0 command=shm_stream_demo -u rtsp://10.1.32.193:8554/rtsp/stream10 -W 1280x720 ``` **配置目录示例(release/):** ``` release/ # 由 build.sh 自动生成 ├── app.conf # 从项目根目录自动复制(不会复制到镜像) ├── bin/ │ └── shm_stream_demo # 二进制 ├── lib/ │ ├── libxmpp.so # XMPP 硬解码库 │ ├── libema_ipc.so # 共享内存 IPC 库 │ └── libipc_proto.so # IPC proto 库 └── run.sh # 运行脚本 ``` **用法:** ```bash # 使用 release 目录打包 ./packet.sh -d ./release # 使用自定义目录,命令行覆盖版本号 ./packet.sh -d ./deploy -v 2.0.0 ``` **参数说明:** | 参数 | 说明 | |------|------| | `-d, --dir ` | 应用配置目录(必选,目录下需含 app.conf) | | `-v, --version ` | 镜像版本标签(覆盖 app.conf 中的 version) | | `-h, --help` | 显示帮助 | **app.conf 配置项:** | 配置项 | 说明 | |--------|------| | `app_name` | 应用名称,用于生成镜像名和容器名 | | `version` | 版本号 | | `command` | 启动命令(支持带参数) | **镜像规范:** - 镜像名称:`ai/faas/app/:` - 基础镜像:`ubuntu:22.04` (arm64) - 配置目录内容平铺复制到 `/usr/local/` - docker-compose.yml(含 Ascend 硬件设备映射)以 base64 编码嵌入镜像 LABEL **前置条件:** 1. 配置目录下存在 `app.conf` 且包含 `app_name`、`version`、`command` 2. Docker 可用且支持 arm64 架构(如不支持可运行 `docker run --rm --privileged tonistiigi/binfmt --install arm64`) **下一步:** ```bash # 检查镜像 docker inspect ai/faas/app/shm-stream:1.0.0 # 推送镜像 docker push ai/faas/app/shm-stream:1.0.0 ``` ## 运行 ### 使用发布包运行(推荐) 构建完成后,`release/` 目录即为可部署的发布包: ``` release/ ├── run.sh # 运行脚本(自动设置环境变量) ├── bin/ │ └── shm_stream_demo └── lib/ └── *.so ``` ```bash # 编辑 run.sh 修改参数后直接运行 cd release ./run.sh ``` ### 手动运行(开发调试) ```bash cd release # 基本用法:通过 gRPC 订阅(媒体服务地址由 FoundationService 自动发现) ./bin/shm_stream_demo -u rtsp://10.1.32.193:8554/rtsp/stream10 -W 1280x720 # 保存解码后的帧到文件 ./bin/shm_stream_demo -u rtsp://10.1.32.193:8554/rtsp/stream10 -o output.yuv -n 100 -W 1280x720 # 指定已有的共享内存通道(跳过 gRPC) ./bin/shm_stream_demo -c channel_name_123 -o output.yuv -n 100 # 调试模式 ./bin/shm_stream_demo -u rtsp://10.1.32.193:8554/rtsp/stream10 -W 1280x720 -D ``` ## 参数说明 | 参数 | 说明 | 默认值 | |------|------|--------| | `-u, --url` | 视频源地址(必填,除非指定 -c) | - | | `-o, --output` | 解码后输出文件路径 | 无 | | `-n, --frame-count` | 接收帧数 | -1(无限) | | `-c, --channel` | 共享内存 channel_name | 无 | | `-W, --size` | 视频分辨率(如 1280x720) | 1920x1080 | | `-D, --debug` | 打印每帧详细信息 | false | ## 输出文件播放 解码输出为 NV12 格式的 YUV 文件,可用 ffplay 播放: ```bash ffplay -f rawvideo -pixel_format nv12 -video_size 1920x1080 output.yuv ``` ## 数据流说明 1. **gRPC 订阅**:调用 `SubscribeSourceData` 获取 channel_name 2. **共享内存接收**:通过 ema_ipc 接收 H.264/H.265 编码流 3. **硬解码**:XMPP 解码器将编码流解码为 NV12 帧 4. **输出保存**:将解码帧保存为 YUV 文件 ## 关键映射 | Proto PixelFormat | XMPP VFormat | |-------------------|--------------| | PIX_FORMAT_H264 (19) | XMPP_VFORMAT_H264 (220) | | PIX_FORMAT_H265 (20) | XMPP_VFORMAT_H265 (221) | ## 注意事项 1. channel_name 必须与服务端发布的 stream_name 完全一致 2. XmppVFrame 的 private_data 必须设为 NULL,private_flag 必须设为 0 3. xmpp_init() 必须在所有 XMPP 操作之前调用 4. xmpp_quit() 必须在程序退出时调用