live555 推RTSP音视频流总结(三) 推送H264实时流产生的花屏问题

live555 做RTSP Server推送实时流的时候,花屏问题采用的解决方法
应该有不少的地方都可以优化,目前只采用了3个策略解决:

由于对live555 错中复杂的类很不熟悉,这些都是经过浅显调试的结论:

1.StreamParser.cpp

按我的理解,这个参数是代表着一帧H264数据的大小,默认150K,如果分辨率大了,很可能会超出大小,可能每一帧都会因为丢数据花屏--------->但我只是改了; 并没有实际改大分辨率验证

#define BANK_SIZE 800000 //300 -> 800

2.修改maxSize 大小

OutPacketBuffer::maxSize = 1000000; // 

在H264FramedLiveSource::doGetNextFrame()中,通常会对H264做内存拷贝的操作:

memcpy(fTo ,video_buf,fMaxSize);

fTo是live555 释放出来的指针,它指向的最大内存为maxSize ,随着每一次向fTo拷贝数据,fMaxSize会从maxSize 慢慢减小,直到0,然后重新指向一个maxSize 大小的内存

因此 我看到的现象是:将maxSize 的大小从200k增加,会发现花屏的问题得到了改善,但是,隔几十秒还是会花屏

3.利用FrameSource中的fNumTruncatedBytescans

接着上一条:,随着每一次向fTo拷贝数据,fMaxSize会从maxSize 慢慢减小,直到0,然后重新指向一个maxSize 大小的内存,那么在fTo的buf即将耗尽时,最后一帧H264数据放不下了,就会把放不下的数据,我手动给丢掉,然后就花屏了!喵的

那么fNumTruncatedBytescans是FrameSource中的一个参数,意思是被舍弃的包的数目,但其实直接操作它并没有作用。只能自定义一个数目来执行我的想法:
每一次fTo耗尽的时候,把丢掉的数据保存在本地,下一次回调doGetNextFrame()时,先把丢掉的数据写进去,再把这次要写的264包放到后面。
由于H264是有NALU的,有严格的头和尾的标志;所以这样做似乎OK的
然后,live555的buf不是直接操作fTo的那个buf,也不是这个buf就只能存一帧数据,这个也是之前的错误观念

上伪代码:

void H264FramedLiveSource::doGetNextFrame()
{

      	int ret = 0;
		int h264_total_size = 0;
		int64_t timeStamp;
		unsigned char video_buf[MAX_VDATA_SIZE];
		memset(video_buf,0,sizeof(video_buf));
		
		getH264Data(&h264_total_size,&timeStamp ,video_buf);

		if(h264_total_size > fMaxSize) { // buff耗尽的帧
			memcpy(fTo ,video_buf,fMaxSize);
			memcpy(truncatedBytes, video_buf+fMaxSize,h264_total_size-fMaxSize);
			fNumTruncatedBytes = h264_total_size - fMaxSize;
			NumTruncatedBytes = h264_total_size - fMaxSize;
			fFrameSize = fMaxSize;
		} 
		else 
		{
			if(NumTruncatedBytes != 0)
			{
				memcpy(fTo ,truncatedBytes,NumTruncatedBytes);
				memcpy(fTo+NumTruncatedBytes ,video_buf,h264_total_size);
				fFrameSize = h264_total_size+NumTruncatedBytes;
				fNumTruncatedBytes = 0;
				NumTruncatedBytes = 0;
				memset(truncatedBytes,0,sizeof(truncatedBytes));
			}
			else
			{
				memset(truncatedBytes,0,sizeof(truncatedBytes));	
				memcpy(fTo ,video_buf,h264_total_size);
				fFrameSize = h264_total_size;
				fNumTruncatedBytes = 0;
				NumTruncatedBytes = 0;
			}
		}

    FramedSource::afterGetting(this);

    return;
}
  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: live555是一个基于C++的开源媒体服务器,是由美国的Live Networks公司开发并维护。它的主要功能是在网络上实现实时传输,支持RTSP、RTP/RTCP和SIP等协议。 在使用live555推送实时之前,我们需要先设置好服务器地址、端口号以及媒体文件等参数。然后,我们通过live555中的MediaSession类,创建一个媒体会话,将需要传输的媒体加入到会话中。媒体可以是音频或视频,也可以是音视频混合的多媒体。 接着,我们使用live555提供的MediaSubsession类,将加入媒体会话的媒体进行分割。分割后的媒体将按照RTSP或RTP协议进行传输,可以通过RTSP或RTP服务器进行接收。其中,RTSP用于控制媒体的播放、暂停、停止等操作;而RTP则是在网络传输中实现实时数据传输和同步的协议。 总的来说,通过使用live555的媒体会话和媒体分割功能,我们可以轻松地实现实时推送和传输,为视频监控、视频会议、实时视频直播等应用提供了非常可靠和高效的技术支持。 ### 回答2: Live555是一个开源的C++多媒体框架,可用于实现实时推送Live555提供了一套完整的库和工具,能够支持常见的视频和音频协议,例如RTSP,RTP,RTCP等。 实时推送的过程可以概括为以下几个步骤: 1. 创建一个`RTSPServer`实例,用于接收客户端的连接请求。 2. 为需要推送的媒体资源创建一个`MediaSession`实例,并将其添加到`RTSPServer`中。 3. 创建一个`RTSPClientConnection`实例,用于处理客户端的连接和请求。 4. 在`RTSPSession`中添加需要推送的媒体资源,并为其创建一个`RTPSink`实例,用于将媒体数据发送到客户端。 5. 创建一个`MediaSource`实例,用于从媒体源(例如摄像头或音频设备)中获取实时数据。 6. 将`MediaSource`连接到`RTPSink`,并启动数据传输。 7. 开始监听客户端的连接请求,并响应相应的RTSP请求。 8. 当有客户端连接成功后,将媒体数据通过RTP协议发送给客户端。 9. 如果有多个客户端连接,可以使用多线程或多进程来处理并发连接。 通过以上步骤,Live555可以实现将实时从媒体源推送到客户端。实时推送广泛应用于视频直播、视频会议等领域,能够实现高效的实时数据传输和播放。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值