[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