背景:
客户需要一个直连设备实时预览的播放器,就以 ffmpeg + rtsp + SDL 为核心,写了一个多路实时预览的播放器。客户使用之后,反馈会花屏,卡顿。
网上搜索,发现 这篇分析比较全面 转载地址 https://blog.csdn.net/sz76211822/article/details/87797475 ,原文访问不了。
1.修改udp.c
UDP_MAX_PKT_SIZE 大小x10
UDP_TX_BUF_SIZE
这个需要重新编译 ffmpeg 所以 参考 https://blog.csdn.net/nodeman/article/details/106431994?utm_medium=distribute.pc_relevant.none-task-blog-title-5&spm=1001.2101.3001.4242 文章,修改 upd.c 后,重新编译ffmpeg4.3.1 版本。
替换新编译出来的 ffmepg 相关dll 进行测试,发现还是会花屏,并不能解决花屏问题。
2.修改 rtsp 连接参数
AVDictionary* options = NULL;
av_dict_set(&options, "buffer_size", "2048000", 0);
av_dict_set(&options, "max_delay", "500000", 0);
av_dict_set(&options, "stimeout", "10000000", 0); //设置超时断开连接时间 10s
av_dict_set(&options, "rtsp_transport", "tcp", 0); //以udp方式打开,如果以tcp方式打开将udp替换为tcp
buffer_size 改为 2048000, rtsp_transport 连接方式从 udp 改为 tcp。
2.1 测试
修改后重新测试,发现花屏现象减少,但是还是有花屏。花屏减少 ,主要是 连接方式从 udp 改为 tcp.
3. 关注ffmpeg 底层错误 av_log_set_callback
依据第一篇博文,关注ffmpeg 相关错误,因为对ffmpeg 源码不熟悉 和 本项目情况,没有添加全局变量。通过设置 av_log_set_callback 写入日志。当花屏时,通过分析日志,确实出现了第一篇文章描述的相关错误日志。因为是多路实时预览,需要知道是哪一路的视频数据出现问题,通过分析ffmepg 错误日志 代码,发现 av_log_set_callback 的 回调函数第一个参数是 AVCodecContext 指针,应该是 AVFormatContext *m_pFormatCtx->streams[videoindex]->codec,中一致,代码测试确认一下,确实匹配上。这样就能知道是哪一路视频数据出现错误,当发现相关错误时,给对应的通道 设置标志,下一帧需要解I帧。
修改之后测试,花屏没有复现。
参考资料:
https://blog.csdn.net/sz76211822/article/details/87797475
https://blog.csdn.net/leixiaohua1020/article/details/46890739