RTSP 推流服务 H.265 切换为 H.264 排查与修改记录

1. 问题背景与现象

  • 目标: 将设备端的 RTSP 视频推流格式(包含前置与后置摄像头)从 H.265 (HEVC) 统一修改为 H.264。
  • 现象: 检查推流启动脚本 push_video.sh 时,发现在 GStreamer 的备用管道配置中写的是 mpph264enc(瑞芯微硬件 H.264 编码器),但客户端实际拉流检测到的前后摄视频流编码格式依然均为 H.265。

2. 排查过程

2.1 脚本逻辑分支分析

通过进一步拆解 push_video.sh 脚本的执行逻辑,发现推流命令存在 if-else 分支:

  • if 分支(主逻辑): 当系统检测到特定的 USB 摄像头设备(如 SM_USB_107X)时,会调用编译好的 push_video 二进制程序,并传入对应的 JSON 配置文件进行推流。
  • else 分支(备用逻辑): 当未检测到该设备时,才会使用脚本中明文写的 gst-launch-1.0 ... ! mpph264enc ! ... 管道命令。

结论: 实际运行中,设备命中了 if 分支,脚本中裸露的 mpph264enc 代码段并未被执行,真实的推流配置来源于外部的 JSON 文件。

2.2 配置文件溯源

根据脚本中的路径,查看实际被调用的 JSON 配置文件(例如前摄的 SM_USB_107X_0.json):

cat /opt/robot/scripts/board_resources/rtsp_service/SM_USB_107X_0.json

在 JSON 文件的 pipeline_template 字段中,发现了实际生效的 GStreamer 管道字符串:

"pipeline_template": " ... ! videoconvert ! video/x-raw,format=I420 ! mpph265enc rc-mode=0 bps=1800000 ... "

根本原因: JSON 模板中强制指定了使用 mpph265enc 进行编码,导致输出流始终为 H.265。由于前后摄使用的是同系列的配置文件,因此均存在该问题。

3. 解决方案

3.1 修改前后摄配置文件

修改所有相关的 SM_USB_107X 配置文件,将 GStreamer 管道模板中的 H.265 编码器替换为 H.264 编码器。

  1. 修改前摄像头配置:

    vim /opt/robot/scripts/board_resources/rtsp_service/SM_USB_107X_0.json
    

    pipeline_template 字符串中的 mpph265enc 更改为 mpph264enc

  2. 修改后摄像头配置: 根据启动脚本中的映射关系,找到后摄像头对应的配置文件(通常为 SM_USB_107X_1.jsonSM_USB_107X_2.json 等):

    vim /opt/robot/scripts/board_resources/rtsp_service/SM_USB_107X_2.json
    

    同样,将 pipeline_template 中的 mpph265enc 更改为 mpph264enc

(注:为防止后续设备挂载节点变化导致配置错乱,建议将该目录下所有 SM_USB_107X_x.json 里的编码器都统一修改为 mpph264enc。)

3.2 重启推流服务

修改完成后,重启 RTSP 相关服务或直接重启设备以加载最新配置:

# 重启 USB 摄像头推流服务
bash /home/ysc/rtsp_service/usb_ctl.sh enable

4. 验证结果

服务重启后,可通过 ffprobe 命令行工具在终端分别验证前后摄视频流的实际编码格式:

# 验证前摄流 (以 video1 为例)
ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 rtsp://127.0.0.1:8554/video1

# 验证后摄流 (以 video2 为例)
ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 rtsp://127.0.0.1:8554/video2
  • 期望输出: 均返回 h264 (说明前后摄修改均已成功生效)。