解决FFmpeg播放RTSP推送的H265码流报错问题

这篇具有很好参考价值的文章主要介绍了解决FFmpeg播放RTSP推送的H265码流报错问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、背景介绍

RTSP(Real Time Streaming Protocol),实时流传输协议,是TCP/IP协议体系中的一个应用层协议。

ffmpeg rtsp推流,编程,音视频开发,程序员,ffmpeg,网络,webrtc,音视频,C++

RTP(Real-time Transport Protocol)实时传输协议,是一个网络传输协议,它位于传输层,但通常运行在UDP协议之上。

去年我写过两篇关于使用RTSP推送H265码流并拉流显示的文章。实现HEVC码流RTSP推流并显示和假如我想编码HEVC码流时就显示视频画面。前者是使用RTSP+RTP推送本地的H265码流并使用VLC软件拉流显示。而后者是使用x265编码器,在编码过程中使用RTSP+RTP推流并显示。

我录了一段视频,使用RTSP推送本地H265视频,再用VLC软件拉流显示,效果如下:

,时长00:39

但是大家或许都知道,目前视频播放器(包括流媒体)大多基于FFmpeg的框架实现,更具体一点,就是基于FFplay内核,比如B站的ijkplayer开源项目,也是在FFplay基础上做了适用于移动端的封装和优化。

所以,仅仅使用VLC软件成功拉取H265流和显示还不够,最好再用FFmpeg的FFplay工具拉取RTSP推送的H265码流并播放显示。

但是当我进行这个测试的时候,出现了下面的错误:

ffmpeg rtsp推流,编程,音视频开发,程序员,ffmpeg,网络,webrtc,音视频,C++

可以看到主要报错是:

illegal temporal ID in RTP/HEVC packet

但是比较奇怪的一点是,同一个码流的RTSP地址,我使用VLC软件网络串流,播放的视频画面却是正常的

今天就先来尝试解决一下,FFplay拉流播放失败的这个小bug。

2、问题定位

我在网上搜了一下,全网(包括使用Google搜索)搜到唯一相关的问题讨论是:

ffmpeg rtsp推流,编程,音视频开发,程序员,ffmpeg,网络,webrtc,音视频,C++

不过好像对我没什么用,为什么这么说呢?

我测试用的FFplay,是在FFmpeg官网下载的Release版本exe文件。修改播放端FFplay源码不太现实,而且FFplay既然报了错,也有它的逻辑和规则,强制去掉判断不合理吧。不过上图所说的推流端给ID字段赋值的方法,倒是可以试试。那这个报错的ID到底是什么呢?

【学习地址】: FFmpeg/WebRTC/RTMP/NDK/Android音视频流媒体高级开发
【文章福利】:免费领取更多音视频学习资料包、大厂面试题、技术视频和学习路线图,资料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以点击 1079654574 加群领取哦~

ffmpeg rtsp推流,编程,音视频开发,程序员,ffmpeg,网络,webrtc,音视频,C++

ffmpeg rtsp推流,编程,音视频开发,程序员,ffmpeg,网络,webrtc,音视频,C++

其实第一眼看到temporal ID,大致猜到可能是和H265的nuh_temporal_id_plus1(NALU 头里)相关。

ffmpeg rtsp推流,编程,音视频开发,程序员,ffmpeg,网络,webrtc,音视频,C++

至于是不是真的是这样,还得去FFmpeg的源码里面跟踪查看,打印"Illegal temporal ID in RTP/HEVC packet"错误提示的代码逻辑究竟是什么?

首先得去FFmpeg官网或者Github下载源码,由于我是将FFmpeg的源码加到了Source Insight软件中,所以可以直接在此软件里面搜"Illegal temporal ID in RTP/HEVC packet",得到结果如下:

ffmpeg rtsp推流,编程,音视频开发,程序员,ffmpeg,网络,webrtc,音视频,C++

也就是说,在rtpdec_hevc.c文件中的185行的hevc_handle_packet函数中有这个打印。再仔细一瞅,

ffmpeg rtsp推流,编程,音视频开发,程序员,ffmpeg,网络,webrtc,音视频,C++

可以看到,FFmpeg源码在解析使用RTP封装的H265码流时,如果判断出tid值是0,它就会打印"Illegal temporal ID in RTP/HEVC packet"错误提示。

那此处tid的值是什么呢?

    nal_type =  (buf[0] >> 1) & 0x3f;    lid  = ((buf[0] << 5) & 0x20) | ((buf[1] >> 3) & 0x1f);    tid  =   buf[1] & 0x07;

FFmpeg代码这里的buf[0]和buf[1],实际就对应的是H265码流的NALU Header的2个字节。而buf[1]&0x07处理,即获取NALU Header第二个字节的低3位值,也就是上面猜测的那个nuh_temporal_id_plus1语法元素的值

为什么在FFmpeg的源码里面,一定要去检查nuh_temporal_id_plus1不能为0呢?

在ITU-T的H265白皮书里面可以找到答案:

ffmpeg rtsp推流,编程,音视频开发,程序员,ffmpeg,网络,webrtc,音视频,C++

也就是说,在H265标准里面已经明确规定了这个值不能是0,因而FFmpeg源码做的检查是肯定合理没问题的。所以,在网上查到的那个解决方案里面说去掉客户端里面的判断,这明显是一个错误的处理方法。所以说,网上公开的资料鱼龙混杂,大家平时要小心求证。

我们回过头来再想一下,本地H265码流文件,推送到RTSP服务器,肯定需要对其进行RTP封装过程。既然FFmpeg现在检测到我们推送的RTP包里面nuh_temporal_id_plus1这个值有问题,那就有两个怀疑点。

要么是本地H265码流本身的NALU Header就有问题,要么是在做RTP封装时出现了问题

至于我们测试用的H265码流本身,NALU头里面这个值是否就是0,只要用码流分析软件查看便知,结果如下:

ffmpeg rtsp推流,编程,音视频开发,程序员,ffmpeg,网络,webrtc,音视频,C++

显然这个H265码流文件的NALUHeader里面的nuh_temporal_id_plus1值是1,并不是0。

那么就只能是RTP封装H265码流时存在问题

3、问题解决

不知大家之前是否了解过RTP封装视频原理,实际上RTP封装H265裸流的过程,还是比较简单的。RTP协议的头部是12个字节,然后裸流H265作为RTP的负载。H265裸流作为RTP负载的具体规则,可以参考标准:

https://www.rfc-editor.org/rfc/pdfrfc/rfc7798.txt.pdf

在学习了RTP封装H265码流以后,接下来就去排查自己的RTSP推流H265视频文代码。最终发现在H265Source.cpp文件的HandleFrame函数里面存在逻辑问题。

在RTP协议封装H265视频,获取每个NALU数据时,传入的形参frame_buf和frame_size其实都是包含了NALU 起始码数据和长度的。而按照rfc7798标准,在对H265码流进行RTP封装时,需要跳过起始码,如下图右边所示。

ffmpeg rtsp推流,编程,音视频开发,程序员,ffmpeg,网络,webrtc,音视频,C++

上图是将一个NALU打成一个RTP包的情况,对于一个NALU的实际数据长度,超过最大值MAX_RTP_PAYLOAD_SIZE(这里定义的是1420字节)的情况也需要跳过起始码,如下图所示:

ffmpeg rtsp推流,编程,音视频开发,程序员,ffmpeg,网络,webrtc,音视频,C++

如果不跳过起始码,frame_buf[1]获取的NALU Header里面的tid值就会是0,因为H265码流起始码(0x00 00 00 01)第二个字节值肯定是0。做了代码修改以后,最后再次使用FFplay来获取RTSP的H265码流效果如下:

,时长00:37

可以看到代码修改后,就可以使用FFplay软件播放RTSP推送的本地H265视频了,但是感觉要比VLC软件拉流播放效果卡一些(对比开头的那个视频)

在上面这个视频里面,进行FFplay拉流时,运行了一个脚本ffplay_rtsp.bat,它里面内容是:

.\ffplay.exe -window_title codec2022_test -x 1280 -y 720 -rtsp_transport tcp "rtsp://127.0.0.1:554/codec2021"

其中-window_title codec2022_test的意思是:指定FFplay播放窗口名为codec2022_test,-x 1280 -y 720表示指定FFplay播放器窗口分辨率。而rtsp://127.0.0.1:554/codec2021是我自己设置的RTSP码流地址。

4、小结

以上就是我解决FFplay拉流显示,用RTSP推流本地H265视频报错的一个过程。通过对问题的分析,并层层深入源代码,最终成功用FFplay拉流显示H265视频。希望对你有用。

ffmpeg rtsp推流,编程,音视频开发,程序员,ffmpeg,网络,webrtc,音视频,C++

原文链接:解决FFmpeg播放RTSP推送的H265码流报错问题文章来源地址https://www.toymoban.com/news/detail-611448.html

到了这里,关于解决FFmpeg播放RTSP推送的H265码流报错问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • vue使用vue-h265-player播放h265编码格式视频流

    GitHub地址 vue-h265-player 支持h265编码格式视频流播放 vue使用vue-h265-player 1、安装vue-h265-player 2、拷贝libDecoder.wasm文件到public目录下 复制node_modules/h265-player/lib/libDecoder.wasm文件到public目录下 3、示例代码 url: 需要播放的链接,播放器会根据该值的变化自动重启。 maxRetryCount: 最大尝

    2024年02月14日
    浏览(38)
  • Vue中使用EasyPlayer播放H265视频流

    需要在Vue2的项目中使用EasyPlayer进行H265视频流的播放。使用官方的最新版本加载H265会有问题。一直处于加载中… 引入easyplayer,这里最开始引入了最新版会有问题,因此引入的是3.3.12版本,可参照官方文档进行配置。 EasyPlayer示例及使用说明 在static文件夹中引入对应EasyPlayer.

    2024年02月03日
    浏览(37)
  • H265格式兼容各个浏览器web端播放方案

    可能有很多朋友会遇到H265格式的视频流无法播放,毕竟现在很多相机都支持h265了,确实有很多优点,但是它最大的问题就是很多浏览器无法播放,也有部分浏览器能够兼容h265,但是总不能让用户指定浏览器使用吧,下面来说说怎么兼容各个浏览器播放。 无非两种方案,第一

    2024年02月11日
    浏览(50)
  • 基于GB28181-2022实现web无插件播放H265视频

            目前发布的GB28181-2022增加了对前端设备视频H265编码格式的支持,所以实现国标平台通过浏览器对H265视频流的无插件的解码播放将是未来的趋势。         目前大多的方案都是通过平台端把H265转码为H264,再推送到web前端进行解码播放,这种方式因为需要中间的媒体

    2024年02月06日
    浏览(46)
  • 基于WebAssembly无插件解码H264/H265码流播放器

    基于WebAssembly无插件解码H264/H265码流播放器 之前看到一篇文章:web无插件解码播放H264/H265(WebAssembly解码HTML5播放) H.265/HEVC在Web视频播放的实践 按照文章思路,已经复现了web端无插件解码H265码流。首先说明下我这边的环境,框架。 在海思主板上移植了web服务器nginx,用于pc端请

    2024年01月16日
    浏览(47)
  • 【音视频处理】转编码H264 to H265,FFmpeg,代码分享讲解

    大家好,欢迎来到停止重构的频道。 本期我们讨论音视频文件 转编码 ,如将视频H264转H265等。 内容中所提及的 代码都会放在GitHub ,感兴趣的小伙伴可以到GitHub下载。 我们按这样的顺序展开讨论:​ 1、  编码的作用  2、  转编码的工作原理 3、  编解码器安装  4、  示

    2024年02月11日
    浏览(53)
  • 基于rk3568 Android H265推流SRS低延迟网页播放方案

           在音视频领域,融合推流,低码流,低延迟,浏览器H5化是一个降低成本,提升用户体验的重要手段。同时适配现有直播的生态也是一个必要条件。       在满足上述要求的情况下,我做了以下实践,取得了良好的效果。      在实践中,我们选择采用了成熟的rtmp做

    2024年02月01日
    浏览(52)
  • vue中使用EasyPlayer播放监控视频HLS,H265、H264

    1.使用npm下载依赖 2.将EasyPlayer-lib.min.js文件、EasyPlayer.wasm文件、libDecoder.wasm文件放置到public下 3.创建components,html代码如下 4.使用props接收数据 5.在父组件中引入,传递props中的数据即可运行即可

    2024年02月03日
    浏览(45)
  • 前端实现H265编码的m3u8视频流播放

    前言 视频监控是智慧城市、智慧园区等WebGIS类系统中最为常见的硬件对接设备,最常用的监控视频流格式为m3u8格式,但是m3u8格式通常都是h.265编码格式的,我搜遍了几乎所有前端视频播放插件,几乎普通的播放器插件都不支持h.265格式的视频编码。本文就带领大家了解H265视

    2024年01月18日
    浏览(52)
  • 基于Live555实现RTSP服务器来推送H264实时码流

    实现了一个单播的rtsp服务器来推送实时的h264码流,参考了官方的testProgs目录下的testOnDemandRTSPServer例程和liveMedia目录下的DeviceSource.cpp文件。我这边是把编码出来的h264码流放入了一个缓冲队列,然后从缓冲队列里取出来进行推流。 rtsp.h: rtsp.cpp:  

    2024年02月05日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包