SSH通道下FFmpeg传输H264原始帧仅接收单帧的问题排查
问题分析与解决
直接错误点
你代码里的核心问题出在循环内的ssh_channel_read调用:
nbytes = ssh_channel_read(channel, data, sizeof(memsize), 0);
这里用了sizeof(memsize)作为读取缓冲区的大小,但memsize是size_t类型(64位系统下占8字节),导致每次循环只尝试读取8字节数据,这就是你拿到无效8字节的直接原因。要改成和第一次调用一致的memsize:
nbytes = ssh_channel_read(channel, data, memsize, 0);
额外需要注意的关键点
H264帧边界处理
FFmpeg通过管道输出的是裸H264流,包含连续的NAL单元。你的DataParser不能直接把单次读取的缓冲区当作完整帧解析——一次ssh_channel_read可能返回不完整的帧,或者多个连续帧。你需要维护一个全局缓冲区,把每次读取的数据追加进去,然后从中识别NALU起始码(0x000001或0x00000001),提取完整的NAL单元后再解码显示。完善错误处理
当ssh_channel_read返回SSH_ERROR时要跳出循环,避免无限阻塞或错误循环,修改后的循环逻辑可以是:
size_t nbytes = ssh_channel_read(channel, data, memsize, 0); while (true) { if (nbytes == SSH_ERROR) { sprintf_s(buffer, "SSH Read Error: %s\n", ssh_get_error(session)); SendMessage(hStatus, SB_SETTEXT, 3, (LPARAM)buffer); break; } if (nbytes <= 0) break; DataParser(data, nbytes); nbytes = ssh_channel_read(channel, data, memsize, 0); }
- FFmpeg参数验证
- 如果是实时RTSP流,
-stream_loop -1参数没必要,反而可能导致流异常; - 可以添加
-v error参数屏蔽FFmpeg的日志输出,避免日志混杂在H264流中干扰解析。
- 服务器端流验证
先在服务器本地执行ffmpeg -rtsp_transport tcp -i rtsp://localhost:554/101 -c copy -f h264 test.h264,生成的文件能正常播放的话,说明FFmpeg输出的流本身是正常的,排除服务器端FFmpeg配置问题。
内容的提问来源于stack exchange,提问作者lars
相关产品推荐
相关产品推荐

