`

Red5的丢包处理

    博客分类:
  • Red5
阅读更多

    在多媒体应用中,针对Client端的带宽情况,Server端对Video Data要进行不同的处理,当Client带宽比较差时,需要在Server端对不同的视频帧进行是丢弃处理,如在低带宽条件下,对于非关键帧,为了更好的用户体验性和播放的平滑性,可对其进行丢弃,而关键帧,则一般不给予丢弃。下面结合代码,详细分析下Red5是如何根据Client端的带宽进行丢包处理的。

    Red5的Video Data丢包处理的代码集中在其PlayEngine 的 PushMessage方法,代码如下:

if (body instanceof VideoData) {
				IVideoStreamCodec videoCodec = null;
				if (msgIn instanceof IBroadcastScope) {
					IBroadcastStream stream = (IBroadcastStream) ((IBroadcastScope) msgIn)
							.getAttribute(IBroadcastScope.STREAM_ATTRIBUTE);
					if (stream != null && stream.getCodecInfo() != null) {
						videoCodec = stream.getCodecInfo().getVideoCodec();
					}
				}
				//dont try to drop frames if video codec is null - related to SN-77
				if (videoCodec != null && videoCodec.canDropFrames()) {
					if (playlistSubscriberStream.state == State.PAUSED) {
						// The subscriber paused the video
						log.debug("Dropping packet because we are paused");
						videoFrameDropper.dropPacket(rtmpMessage);
						return;
					}

					// Only check for frame dropping if the codec supports it
					long pendingVideos = pendingVideoMessages();
					if (!videoFrameDropper.canSendPacket(rtmpMessage, pendingVideos)) {
						// Drop frame as it depends on other frames that were dropped before.
						log.debug("Dropping packet because frame dropper says we cant send it");
						return;
					}

					if (!receiveVideo) {
						// The client disabled video or the app doesn't have enough bandwidth
						// allowed for this stream.
						log.debug("Dropping packet because we cant receive video or token acquire failed");
						videoFrameDropper.dropPacket(rtmpMessage);
						return;
					}

					// increment the number of times we had pending video frames sequentially
					if (pendingVideos > 1) {
						numSequentialPendingVideoFrames++;
					} else {
						// reset number of sequential pending frames if 1 or 0 are pending.
						numSequentialPendingVideoFrames = 0;
					}
					if (pendingVideos > maxPendingVideoFramesThreshold
							|| numSequentialPendingVideoFrames > maxSequentialPendingVideoFrames) {
						log.debug("Pending: {} Threshold: {} Sequential: {}", new Object[] { pendingVideos,
								maxPendingVideoFramesThreshold, numSequentialPendingVideoFrames });
						// We drop because the client has insufficient bandwidth.
						long now = System.currentTimeMillis();
						if (bufferCheckInterval > 0 && now >= nextCheckBufferUnderrun) {
							// Notify client about frame dropping (keyframe)
							sendInsufficientBandwidthStatus(currentItem);
							nextCheckBufferUnderrun = now + bufferCheckInterval;
						}
						videoFrameDropper.dropPacket(rtmpMessage);
						return;
					}

					videoFrameDropper.sendPacket(rtmpMessage);
				}
			}

 

   首先Red5根据Stream的Codec来决定是不是需要启用丢包处理。Red5共定义了三种Codec,分别为ScreenVideo,SorensonVideo和AVCVideo,其中ScreenVideo是用于屏幕截取,Red5的缺省实现是,不可以采取丢包处理,而SorensonVideo和AVCVideo分别用于手机和视频播放,Red5的缺省实现是可以采取丢包处理。如果我们需要在采用ScreenVideo的时候也启用丢包处理,则需要修改ScreenVideo的代码,如下所示:

	/** {@inheritDoc} */
    public boolean canDropFrames() {
		return false;
	}

    在Red5的代码中,之所有在此处直接返回false,不支持丢包,主要是因为ScreenVideo这种Codec的Video data的Decode依赖于前后帧,如果丢弃了一帧,很可能接下来的好几帧数据都不能正确Decode。当然如果网络非常差的情况下,还是通过修改ScreenVideo的canDropFrames(),使其返回true,则可在低带宽条件下启动丢包处理,只不过这样在播放端就会出现连续的花屏现象。

    在判断Codec是否支持Drop frames后,Red5主要根据Mina通道里的pendingVideos的数量来决定是否丢弃Video data。由上面的代码可以得知,pendingVideos 是通过方法pendingVideoMessages()获取的。pendingVideoMessages的返回的是RTMPConnection里面的pendingVideos的值(当往Mina的通道里写入一个),在Red5的代码中,如果pendingVideos超过最大允许的等待帧数,则启动丢包处理:

 

					// increment the number of times we had pending video frames sequentially
					if (pendingVideos > 1) {
						numSequentialPendingVideoFrames++;
					} else {
						// reset number of sequential pending frames if 1 or 0 are pending.
						numSequentialPendingVideoFrames = 0;
					}
					if (pendingVideos > maxPendingVideoFramesThreshold
							|| numSequentialPendingVideoFrames > maxSequentialPendingVideoFrames) {
						log.debug("Pending: {} Threshold: {} Sequential: {}", new Object[] { pendingVideos,
								maxPendingVideoFramesThreshold, numSequentialPendingVideoFrames });
						// We drop because the client has insufficient bandwidth.
						long now = System.currentTimeMillis();
						if (bufferCheckInterval > 0 && now >= nextCheckBufferUnderrun) {
							// Notify client about frame dropping (keyframe)
							sendInsufficientBandwidthStatus(currentItem);
							nextCheckBufferUnderrun = now + bufferCheckInterval;
						}
						videoFrameDropper.dropPacket(rtmpMessage);
						return;
					}

     这里之所以用pendingVideos和numSequentialPendingVideoFrames同时作为是否启用丢包的判断条件,主要是为了保证统计的实时性和准确性。

  上面分析了Red5如何判断是否应该丢包,及采取什么样的丢包策略,因此在实际应用的时候可以根据具体的需求,对上述流程进行调节和改动,以适用于不同的应用场景。

 

分享到:
评论
2 楼 zhaoduo_79490175 2015-01-04  
lz,我有一个问题想请教下您呀,red5怎么实现播放另一台存储服务器的视频资源呢?貌似red5只支持本地播放呀。还望解答 多谢了!
1 楼 blueram 2011-09-01  
lz 对red5研究的真透呀,向楼主学习,我最近也在搞red5,可以一块交流吗

相关推荐

    VoIP丢包处理技术的研究进展

    丢包处理技术的研究对于提高VoIP通信的稳定性和音质至关重要。 一、前言 VoIP丢包处理技术是现代通信技术领域的重要研究方向,其目的是减少丢包对语音通话质量的影响。随着互联网的广泛应用,VoIP技术在企业通信、...

    android 视频直播+Red5服务器

    同时,需要处理网络抖动、丢包等问题,确保视频通话的流畅性。 视频直播则更侧重于将单个源流分发给多个接收者。Red5服务器在此扮演关键角色,它接收来自Android客户端的视频流,并将其分发给多个订阅者。订阅者...

    udp丢包率.zip

    1. **拥塞避免算法**:虽然UDP本身没有内置的拥塞控制,但开发者可以自定义算法,例如使用随机早期检测(RED)或者尾丢弃(Tail-Drop)策略来减少拥塞导致的丢包。 2. **设置合适的发送速率**:根据网络状况动态调整...

    基于NS2的路由器算法Droptail和RED的分析与比较

    - 总体而言,RED算法通过提前干预和动态调整丢包概率,能够在保持较高吞吐量的同时有效减少拥塞和丢包现象。 #### 五、结论 通过对队尾丢弃(Droptail)算法和随机早期检测(RED)算法在NS2仿真平台上的对比研究...

    RED协议实现(随机早检测)

    3. **概率丢包(Probabilistic Packet Dropping)**:当平均队列长度在Wmin和Wmax之间时,RED会以一定的概率丢弃新到达的数据包。这个概率随着平均队列长度接近Wmax而增加,使得在网络状态恶化前就能采取行动。 4. ...

    一种丢包区分方法及其在Linux下的实现.pdf

    本文主要探讨了一种丢包区分方法,称为WECN(Explicit Congestion Notification,显式拥塞通告),及其在Linux操作系统中的实现。传统TCP拥塞控制策略依赖于丢包作为网络拥塞的标志,但在无线/有线混合环境中,这种...

    安卓Android源码——Red5+安卓Android 直播系统的架构服务端的直播流工程.zip

    3. **网络优化**:在弱网络环境下,需要考虑丢包重传、延迟控制、码率自适应等策略,以保证直播的流畅性。 4. **性能优化**:利用硬件加速来减轻CPU负担,提高直播质量和稳定性。 5. **多码流适应**:根据用户设备...

    基于路由器的RED和Droptail算法比较.pdf

    此外,RED算法的丢包率降低了13%,这意味着网络的可靠性得到改善。 RED算法的这些优势使其成为路由器队列管理的一种理想选择,尤其是在高带宽和高流量的网络环境中。然而,实施RED算法也存在一定的挑战,如需要更...

    tcl.rar_NS2 red_TCL简单代码_ns2 queue_queue_简单 red

    这种策略在高负载情况下会导致突发性的丢包,进而触发TCP的拥塞窗口减小机制,从而降低网络拥塞。然而,Droptail的缺点是它对拥塞的响应较慢,可能会导致不必要的延迟和丢包。 相比之下,RED队列管理策略更为智能。...

    一种改进RED的Web集群许可控制算法

    实验结果表明,MRED算法在Web集群许可控制中的应用可以显著提高系统对突发流量的应对能力,减少数据包的延迟和丢包率,从而提升用户体验和系统的服务水平。 总之,MRED算法通过对传统RED算法的改进,结合Web集群的...

    论文研究-一种动态参数的随机早期检测算法DRED.pdf

    当网络的负载超过其处理能力时,数据包就会被丢弃,导致丢包率上升。 在上述基础上,DRED算法通过动态调节RED算法的参数,改进了网络的适应性和链路利用率。文章指出,DRED算法在模拟实验中表现出良好的性能,有效...

    拥塞控制在路由器中的实现.pdf

    不同于尾丢弃算法,RED在队列长度达到一定阈值但未达到最大门限时就开始随机丢包,这样可以更早地向发送源发出拥塞警告,避免拥塞的加剧。此外,RED通过随机选择丢弃的数据包,减少了全局同步的风险,因为不同源端...

    改进的RED队列管理算法:RED-r (2012年)

    这是因为PID算法在处理快速变化的数据流量时可能会出现过调或欠调的现象,而RED-r算法通过其独特的丢包概率计算方式,能够在数据流量发生变化时提供更加平滑的响应。 #### NS2仿真结果 为了验证RED-r算法的有效性...

    基于模糊控制理论主动队列管理算法的研究报告报告.doc

    RED关注平均队列长度而非瞬间队列长度,避免在队列空闲时丢包,而在队列接近满载时加大丢包概率。 RED算法包含两部分: 1) 平均队列长度估计:采用指数加权滑动平均方法(2.1),通过权值w和当前队列长度q计算。...

    Tuning Red Hat Enterprise performance

    - **网络接口指标**:如吞吐量、丢包率等。 - **块设备指标**:包括磁盘I/O速率和队列长度。 ### 2. 监控工具 #### 2.1 工具功能概述 本部分提供了多种监控工具的介绍和使用方法。 #### 2.2 uptime 显示系统运行...

Global site tag (gtag.js) - Google Analytics