[Red5commits] [1258] Fixed ServerStream? output jerky issue #77 applying the patch from #104 (w/ some

sgong luke at codegent.com
Wed Aug 2 09:50:09 EDT 2006


Fixed ServerStream? output jerky issue #77 applying the patch from #104 (w/ some extra fix)


Timestamp: 08/02/06 23:45:51 (less than one hour ago) 
Change: 1258 
Author: sgong

Files (see diff or trac for details): 
doc/trunk/changelog.txt
java/server/trunk/src/org/red5/server/stream/IFrameDropper.java
java/server/trunk/src/org/red5/server/stream/PlaylistSubscriberStream.java
java/server/trunk/src/org/red5/server/stream/ServerStream.java
java/server/trunk/src/org/red5/server/stream/VideoFrameDropper.java


Trac: http://mirror1.cvsdude.com/trac/osflash/red5/changeset/1258

Index: /java/server/trunk/src/org/red5/server/stream/IFrameDropper.java
===================================================================
--- /java/server/trunk/src/org/red5/server/stream/IFrameDropper.java (revision 1157)
+++ /java/server/trunk/src/org/red5/server/stream/IFrameDropper.java (revision 1258)
@@ -21,4 +21,5 @@
 
 import org.red5.server.net.rtmp.event.IRTMPEvent;
+import org.red5.server.stream.message.RTMPMessage;
 
 /**
@@ -40,29 +41,29 @@
 
 	/**
-	 * Checks if a packet may be sent to the subscriber.
+	 * Checks if a message may be sent to the subscriber.
 	 * 
-	 * @param packet
-	 * 			the packet to check
+	 * @param message
+	 * 			the message to check
 	 * @param pending
 	 * 			the number of pending messages
 	 * @return <code>true</code> if the packet may be sent, otherwise <code>false</code>
 	 */
-	boolean canSendPacket(IRTMPEvent packet, long pending);
+	boolean canSendPacket(RTMPMessage message, long pending);
 
 	/**
 	 * Notify that a packet has been dropped.
 	 * 
-	 * @param packet
-	 * 			the packet that was dropped
+	 * @param message
+	 * 			the message that was dropped
 	 */
-	void dropPacket(IRTMPEvent packet);
+	void dropPacket(RTMPMessage message);
 
 	/**
-	 * Notify that a packet has been sent.
+	 * Notify that a message has been sent.
 	 * 
-	 * @param packet
-	 * 			the packet that was sent
+	 * @param message
+	 * 			the message that was sent
 	 */
-	void sendPacket(IRTMPEvent packet);
+	void sendPacket(RTMPMessage message);
 
 	/** Reset the frame dropper. */
Index: /java/server/trunk/src/org/red5/server/stream/ServerStream.java
===================================================================
--- /java/server/trunk/src/org/red5/server/stream/ServerStream.java (revision 1252)
+++ /java/server/trunk/src/org/red5/server/stream/ServerStream.java (revision 1258)
@@ -89,8 +89,10 @@
 	private String vodJobName;
 	
-	private int nextVideoTS;
-	private int nextAudioTS;
-	private int nextDataTS;
-	private int nextTS;
+	private long vodStartTS;
+	private long serverStartTS;
+	private long nextVideoTS;
+	private long nextAudioTS;
+	private long nextDataTS;
+	private long nextTS;
 	private RTMPMessage nextRTMPMessage;
 	
@@ -321,50 +323,7 @@
 	private void startBroadcastVOD() {
 		nextVideoTS = nextAudioTS = nextDataTS = 0;
-		// send the first RTMP message
-		RTMPMessage firstRTMPMsg = getNextRTMPMessage();
-		if (firstRTMPMsg == null) {
-			onItemEnd();
-			return;
-		}
-		// FIXME hack the first Metadata Tag from FLVReader
-		// the FLVReader will issue a metadata tag of ts 0
-		// even if it is seeked to somewhere in the middle
-		// which will cause the stream to wait too long.
-		// Is this an FLVReader's bug?
-		if (!(firstRTMPMsg.getBody() instanceof VideoData) &&
-				!(firstRTMPMsg.getBody() instanceof AudioData) &&
-				firstRTMPMsg.getBody().getTimestamp() == 0) {
-			firstRTMPMsg.getBody().release();
-			firstRTMPMsg = getNextRTMPMessage();
-			if (firstRTMPMsg == null) {
-				onItemEnd();
-				return;
-			}
-		}
-		IRTMPEvent rtmpEvent = firstRTMPMsg.getBody();
-		if (rtmpEvent instanceof VideoData) {
-			if (!firstRTMPMsg.isTimerRelative()) {
-				nextVideoTS = rtmpEvent.getTimestamp();
-			} else {
-				nextVideoTS += rtmpEvent.getTimestamp();
-			}
-			nextTS = nextVideoTS;
-		} else if (rtmpEvent instanceof AudioData) {
-			if (!firstRTMPMsg.isTimerRelative()) {
-				nextAudioTS = rtmpEvent.getTimestamp();
-			} else {
-				nextAudioTS += rtmpEvent.getTimestamp();
-			}
-			nextTS = nextAudioTS;
-		} else {
-			if (!firstRTMPMsg.isTimerRelative()) {
-				nextDataTS = rtmpEvent.getTimestamp();
-			} else {
-				nextDataTS += rtmpEvent.getTimestamp();
-			}
-			nextTS = nextDataTS;
-		}
-		msgOut.pushMessage(firstRTMPMsg);
-		firstRTMPMsg.getBody().release();
+		nextRTMPMessage = null;
+		vodStartTS = 0;
+		serverStartTS = System.currentTimeMillis();
 		scheduleNextMessage();
 	}
@@ -375,5 +334,6 @@
 	 */
 	private void scheduleNextMessage() {
-		int currentTS = nextTS;
+		boolean first = nextRTMPMessage == null;
+		
 		nextRTMPMessage = getNextRTMPMessage();
 		if (nextRTMPMessage == null) {
@@ -381,4 +341,23 @@
 			return;
 		}
+
+		if (first) {
+			// FIXME hack the first Metadata Tag from FLVReader
+			// the FLVReader will issue a metadata tag of ts 0
+			// even if it is seeked to somewhere in the middle
+			// which will cause the stream to wait too long.
+			// Is this an FLVReader's bug?
+			if (!(nextRTMPMessage.getBody() instanceof VideoData) &&
+					!(nextRTMPMessage.getBody() instanceof AudioData) &&
+					nextRTMPMessage.getBody().getTimestamp() == 0) {
+				nextRTMPMessage.getBody().release();
+				nextRTMPMessage = getNextRTMPMessage();
+				if (nextRTMPMessage == null) {
+					onItemEnd();
+					return;
+				}
+			}
+		}
+		
 		IRTMPEvent rtmpEvent = nextRTMPMessage.getBody();
 		if (rtmpEvent instanceof VideoData) {
@@ -404,5 +383,9 @@
 			nextTS = nextDataTS;
 		}
-		int delta = nextTS - currentTS;
+		if (first) {
+			vodStartTS = nextTS;
+		}
+		long delta = nextTS - vodStartTS - (System.currentTimeMillis() - serverStartTS);
+		
 		vodJobName = scheduler.addScheduledOnceJob(delta, new IScheduledJob() {
 			public void execute(ISchedulingService service) {
Index: /java/server/trunk/src/org/red5/server/stream/PlaylistSubscriberStream.java
===================================================================
--- /java/server/trunk/src/org/red5/server/stream/PlaylistSubscriberStream.java (revision 1241)
+++ /java/server/trunk/src/org/red5/server/stream/PlaylistSubscriberStream.java (revision 1258)
@@ -1103,5 +1103,5 @@
 						// Only check for frame dropping if the codec supports it
 						long pendingVideos = pendingVideoMessages();
-						if (!videoFrameDropper.canSendPacket(body, pendingVideos)) {
+						if (!videoFrameDropper.canSendPacket(rtmpMessage, pendingVideos)) {
 							//System.err.println("Dropping1: " + body + " " + pendingVideos);
 							return;
@@ -1111,9 +1111,9 @@
 						if (!receiveVideo || pendingVideos > 1 || drop) {
 							//System.err.println("Dropping2: " + receiveVideo + " " + pendingVideos + " " + videoBucket + " size: " + size + " drop: " + drop);
-							videoFrameDropper.dropPacket(body);
+							videoFrameDropper.dropPacket(rtmpMessage);
 							return;
 						}
 	
-						videoFrameDropper.sendPacket(body);
+						videoFrameDropper.sendPacket(rtmpMessage);
 					}
 				} else if (body instanceof AudioData) {
Index: /java/server/trunk/src/org/red5/server/stream/VideoFrameDropper.java
===================================================================
--- /java/server/trunk/src/org/red5/server/stream/VideoFrameDropper.java (revision 1163)
+++ /java/server/trunk/src/org/red5/server/stream/VideoFrameDropper.java (revision 1258)
@@ -26,4 +26,5 @@
 import org.red5.server.net.rtmp.event.IRTMPEvent;
 import org.red5.server.net.rtmp.event.VideoData;
+import org.red5.server.stream.message.RTMPMessage;
 
 /**
@@ -79,5 +80,6 @@
 	}
 	
-	public boolean canSendPacket(IRTMPEvent packet, long pending) {
+	public boolean canSendPacket(RTMPMessage message, long pending) {
+		IRTMPEvent packet = message.getBody();
 		if (! (packet instanceof VideoData))
 			// We currently only drop video packets.
@@ -125,5 +127,5 @@
 		// Store timestamp of dropped packet
 		if (!result && countDroppedTimes && type != FrameType.DISPOSABLE_INTERFRAME) {
-			if (packet.getHeader().isTimerRelative())
+			if (message.isTimerRelative())
 				droppedTimes += packet.getTimestamp();
 			else {
@@ -136,5 +138,6 @@
 	}
 
-	public void dropPacket(IRTMPEvent packet) {
+	public void dropPacket(RTMPMessage message) {
+		IRTMPEvent packet = message.getBody();
 		if (! (packet instanceof VideoData))
 			// Only check video packets.
@@ -146,5 +149,5 @@
 		// Store timestamp of dropped packet
 		if (countDroppedTimes && type != FrameType.DISPOSABLE_INTERFRAME) {
-			if (packet.getHeader().isTimerRelative())
+			if (message.isTimerRelative())
 				droppedTimes += packet.getTimestamp();
 			else {
@@ -197,5 +200,6 @@
 	}
 
-	public void sendPacket(IRTMPEvent packet) {
+	public void sendPacket(RTMPMessage message) {
+		IRTMPEvent packet = message.getBody();
 		if (! (packet instanceof VideoData))
 			// Only process video packets.
@@ -209,5 +213,8 @@
 		if (droppedAbsolute) {
 			video.setTimestamp(droppedTimes);
-			video.getHeader().setTimerRelative(true);
+			message.setTimerRelative(true);
+			if (video.getHeader() != null) {
+				video.getHeader().setTimerRelative(true);
+			}
 			droppedAbsolute = true;
 		} else {
Index: /doc/trunk/changelog.txt
===================================================================
--- /doc/trunk/changelog.txt (revision 1256)
+++ /doc/trunk/changelog.txt (revision 1258)
@@ -13,5 +13,5 @@
 - FileConsumer modified position of incoming messages (Trac #91)
 - Events should support reference counting (Trac #103)
-
+- ServerStream playback jerky (Trac #77)
 
 Red5 0.5    (2006-07-25)


Note:
Diffs are chopped if more than 25k.
This is to get past the limit on the mailing list.



More information about the Red5commits mailing list