src/jlibrtp/PktBuffer.java
author nikita@nikita-rack
Thu, 09 Apr 2009 20:26:58 +0200
changeset 99 8de21ac527ce
parent 13 e684f11070d5
permissions -rw-r--r--
revert pour refaire un push propre
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
13
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
     1
/**
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
     2
 * Java RTP Library (jlibrtp)
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
     3
 * Copyright (C) 2006 Arne Kepp
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
     4
 * 
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
     5
 * This library is free software; you can redistribute it and/or
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
     6
 * modify it under the terms of the GNU Lesser General Public
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
     7
 * License as published by the Free Software Foundation; either
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
     8
 * version 2.1 of the License, or (at your option) any later version.
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
     9
 *
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    10
 * This library is distributed in the hope that it will be useful,
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    13
 * Lesser General Public License for more details.
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    14
 * 
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    15
 * You should have received a copy of the GNU Lesser General Public
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    16
 * License along with this library; if not, write to the Free Software
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    18
 */
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    19
package jlibrtp;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    20
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    21
/**
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    22
 * A PktBuffer stores packets either for buffering purposes,
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    23
 * or because they need to be assimilated to create a complete frame.
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    24
 * 
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    25
 * This behavior can be controlled through rtpSession.pktBufBehavior()
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    26
 * 
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    27
 * It optionally drops duplicate packets.
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    28
 * 
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    29
 * Note that newest is the most recently received, i.e. highest timeStamp
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    30
 * Next means new to old (from recently received to previously received) 
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    31
 * 
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    32
 * @author Arne Kepp
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    33
 */
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    34
public class PktBuffer {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    35
	/** The RTPSession holds information common to all packetBuffers, such as max size */
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    36
	RTPSession rtpSession;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    37
	/** SSRC of the the participant that this buffer is for */
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    38
	long SSRC;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    39
	/** The parent participant */
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    40
	Participant p;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    41
	/** The length of the buffer */
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    42
	int length = 0;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    43
	/** The oldest, least recently received, packet */
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    44
	PktBufNode oldest = null;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    45
	/** The newest, most recently received, packet */
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    46
	PktBufNode newest = null;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    47
	
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    48
	/** The last sequence number received */
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    49
	int lastSeqNumber = -1;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    50
	/** The last timestamp */
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    51
	long lastTimestamp = -1;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    52
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    53
	/** 
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    54
	 * Creates a new PktBuffer, a linked list of PktBufNode
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    55
	 * 
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    56
	 * @param rtpSession the parent RTPSession
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    57
	 * @param p the participant to which this packetbuffer belongs.
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    58
	 * @param aPkt The first RTP packet, to be added to the buffer 
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    59
	 */
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    60
	protected PktBuffer(RTPSession rtpSession, Participant p, RtpPkt aPkt) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    61
		this.rtpSession = rtpSession;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    62
		this.p = p;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    63
		SSRC = aPkt.getSsrc();
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    64
		PktBufNode newNode = new PktBufNode(aPkt);
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    65
		oldest = newNode;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    66
		newest = newNode;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    67
		//lastSeqNumber = (aPkt.getSeqNumber() - 1);
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    68
		//lastTimestamp = aPkt.getTimeStamp();
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    69
		length = 1;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    70
	}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    71
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    72
	/**
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    73
	 * Adds a packet, this happens in constant time if they arrive in order.
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    74
	 * Optimized for the case where each pkt is a complete frame.
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    75
	 * 
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    76
	 * @param aPkt the packet to be added to the buffer.
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    77
	 * @return integer, negative if operation failed (see code)
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    78
	 */
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    79
	protected synchronized int addPkt(RtpPkt aPkt) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    80
		if(aPkt == null) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    81
			System.out.println("! PktBuffer.addPkt(aPkt) aPkt was null");
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    82
			return -5;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    83
		}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    84
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    85
		long timeStamp = aPkt.getTimeStamp();
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    86
		if(RTPSession.rtpDebugLevel > 7) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    87
			System.out.println("-> PktBuffer.addPkt() , length:" + length + " , timeStamp of Pkt: " + Long.toString(timeStamp));
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    88
		}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    89
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    90
		
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    91
		PktBufNode newNode = new PktBufNode(aPkt);
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    92
		if(aPkt.getSsrc() != SSRC) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    93
			System.out.println("PktBuffer.addPkt() SSRCs don't match!");
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    94
		}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    95
		
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    96
		int retVal = 0;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    97
		if(this.rtpSession.pktBufBehavior > 0) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    98
			retVal = bufferedAddPkt(newNode);
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
    99
		} else if(this.rtpSession.pktBufBehavior == 0) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   100
			retVal = filteredAddPkt(newNode);
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   101
		} else if(this.rtpSession.pktBufBehavior == -1) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   102
			retVal = unfilteredAddPkt(newNode);
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   103
		}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   104
		
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   105
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   106
		if(RTPSession.rtpDebugLevel > 7) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   107
			if(RTPSession.rtpDebugLevel > 10) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   108
				this.debugPrint();
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   109
			}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   110
			System.out.println("<- PktBuffer.addPkt() , length:" + length + " returning " + retVal);
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   111
		}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   112
		return retVal;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   113
	}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   114
	
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   115
	/**
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   116
	 * Adds packets in the same order that they arrive,
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   117
	 * doesn't do any filering or processing.
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   118
	 * 
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   119
	 * @param newNode the node to add to the packet buffer
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   120
	 * @return 0 if everything is okay, -1 otherwise
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   121
	 */
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   122
	private int unfilteredAddPkt(PktBufNode newNode) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   123
		if(RTPSession.rtpDebugLevel > 8) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   124
			System.out.println("<->    PktBuffer.unfilteredAddPkt()");
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   125
		}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   126
		//No magic, just add to the end
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   127
		if(oldest != null) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   128
			oldest.nextFrameQueueNode = newNode;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   129
			newNode.prevFrameQueueNode = oldest; 
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   130
			oldest = newNode;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   131
		} else {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   132
			oldest = newNode;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   133
			newest = newNode;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   134
		}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   135
		return 0;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   136
	}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   137
	
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   138
	/**
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   139
	 * Takes care of duplicate packets
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   140
	 * 
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   141
	 * @param newNode the node to add to the packet buffer
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   142
	 * @return 0 if everything is okay, -1 otherwise
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   143
	 */
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   144
	private int filteredAddPkt(PktBufNode newNode) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   145
		if(RTPSession.rtpDebugLevel > 8) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   146
			System.out.println("<->    PktBuffer.filteredAddPkt()");
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   147
		}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   148
		
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   149
		if(length == 0) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   150
			// The buffer was empty, this packet is the one and only.
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   151
			newest = newNode;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   152
			oldest = newNode;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   153
			length = 1;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   154
		} else {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   155
			// The packetbuffer is not empty.
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   156
			if(newNode.timeStamp > newest.timeStamp || newNode.seqNum > newest.seqNum && (newNode.seqNum - newest.seqNum) < 10) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   157
				// Packet came in order
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   158
				newNode.nextFrameQueueNode = newest;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   159
				newest.prevFrameQueueNode = newNode;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   160
				newest = newNode;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   161
				length++;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   162
			} else {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   163
					if(RTPSession.rtpDebugLevel > 2) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   164
						System.out.println("PktBuffer.filteredAddPkt Dropped a packet due to lag! " +  newNode.timeStamp + " " 
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   165
								+ newNode.seqNum + " vs "+ oldest.timeStamp + " " + oldest.seqNum);
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   166
					}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   167
					return -1;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   168
			}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   169
		}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   170
		
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   171
		return 0;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   172
	}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   173
	
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   174
	/**
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   175
	 * Does most of the packet organization for the application.
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   176
	 * Packets are put in order, duplicate packets or late arrivals are discarded
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   177
	 * 
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   178
	 * If multiple packets make up a frame, these will also be organized
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   179
	 * by RTP timestamp and sequence number, and returned as a complete frame.
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   180
	 * 
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   181
	 * @param newNode the node to add to the packet buffer
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   182
	 * @return 0 if everything is okay, -1 otherwise
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   183
	 */
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   184
	private int bufferedAddPkt(PktBufNode newNode) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   185
		if(RTPSession.rtpDebugLevel > 8) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   186
			System.out.println("<->    PktBuffer.bufferedAddPkt()");
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   187
		}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   188
		if(length == 0) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   189
			// The buffer was empty, this packet is the one and only.
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   190
			newest = newNode;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   191
			oldest = newNode;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   192
		} else {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   193
			// The packetbuffer is not empty.
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   194
			if(newNode.timeStamp > newest.timeStamp || newNode.seqNum > newest.seqNum) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   195
				// Packet came in order
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   196
				newNode.nextFrameQueueNode = newest;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   197
				newest.prevFrameQueueNode = newNode;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   198
				newest = newNode;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   199
			} else {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   200
				//There are packets, we need to order this one right.
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   201
				if(! pktOnTime(newNode.timeStamp, newNode.seqNum) && rtpSession.pktBufBehavior > -1) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   202
					// We got this too late, can't put it in order anymore.
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   203
					if(RTPSession.rtpDebugLevel > 2) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   204
						System.out.println("PktBuffer.addPkt Dropped a packet due to lag! " +  newNode.timeStamp + " " 
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   205
								+ newNode.seqNum + " vs "+ oldest.timeStamp + " " + oldest.seqNum);
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   206
					}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   207
					return -1;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   208
				}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   209
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   210
				//Need to do some real work, find out where it belongs (linear search from the back).
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   211
				PktBufNode tmpNode = newest;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   212
				while(tmpNode.timeStamp > newNode.timeStamp) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   213
					tmpNode = tmpNode.nextFrameQueueNode;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   214
				}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   215
				
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   216
				if( tmpNode.timeStamp == newNode.timeStamp
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   217
						&& rtpSession.frameReconstruction
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   218
						&& newNode.seqNum != tmpNode.seqNum) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   219
					//Packet has same timestamp, presumably belongs to frame. Need to order within frame.
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   220
					if(RTPSession.rtpDebugLevel > 8) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   221
						System.out.println("Found pkt with existing timeStamp: " + newNode.timeStamp);
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   222
					}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   223
					int ret = addToFrame(tmpNode, newNode);
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   224
					if(ret != 0) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   225
						return ret;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   226
					}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   227
				} else {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   228
								
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   229
					// Check that it's not a duplicate
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   230
					if(tmpNode.timeStamp == newNode.timeStamp && newNode.seqNum == tmpNode.seqNum) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   231
						if(RTPSession.rtpDebugLevel > 2) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   232
							System.out.println("PktBuffer.addPkt Dropped a duplicate packet! " 
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   233
									+  newNode.timeStamp + " " + newNode.seqNum );
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   234
						}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   235
						return -1;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   236
					}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   237
				
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   238
					// Insert into buffer
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   239
					newNode.nextFrameQueueNode = tmpNode;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   240
					newNode.prevFrameQueueNode = tmpNode.prevFrameQueueNode;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   241
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   242
					// Update the node behind
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   243
					if(newNode.prevFrameQueueNode != null) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   244
						newNode.prevFrameQueueNode.nextFrameQueueNode = newNode;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   245
					}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   246
					tmpNode.prevFrameQueueNode = newNode;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   247
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   248
					if(newNode.timeStamp > newest.timeStamp) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   249
						newest = newNode; 
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   250
					}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   251
				}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   252
			}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   253
		}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   254
		// Update the length of this buffer
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   255
		length++;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   256
		return 0;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   257
	}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   258
	
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   259
	/**
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   260
	 * 
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   261
	 * @param frameNode the node currently representing the frame in the packet buffer
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   262
	 * @param newNode the new node to be added to the frame
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   263
	 * @return 0 if no error, -2 if this is a duplicate packet
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   264
	 */
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   265
	private int addToFrame(PktBufNode frameNode, PktBufNode newNode) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   266
		// Node has same timeStamp, assume pkt belongs to frame
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   267
		
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   268
		if(frameNode.seqNum < newNode.seqNum) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   269
			// this is not the first packet in the frame
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   270
			frameNode.pktCount++;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   271
			
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   272
			// Find the right spot
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   273
			while( frameNode.nextFrameNode != null 
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   274
					&& frameNode.nextFrameNode.seqNum < newNode.seqNum) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   275
				frameNode = frameNode.nextFrameNode;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   276
			}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   277
			
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   278
			// Check whether packet is duplicate
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   279
			if(frameNode.nextFrameNode != null 
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   280
					&& frameNode.nextFrameNode.seqNum == newNode.seqNum) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   281
				if(RTPSession.rtpDebugLevel > 2) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   282
					System.out.println("PktBuffer.addPkt Dropped a duplicate packet!");
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   283
				}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   284
				return -2;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   285
			}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   286
			
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   287
			newNode.nextFrameNode = frameNode.nextFrameNode;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   288
			frameNode.nextFrameNode = newNode;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   289
		
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   290
		} else {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   291
			// newNode has the lowest sequence number
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   292
			newNode.nextFrameNode = frameNode;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   293
			newNode.pktCount = frameNode.pktCount + 1;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   294
			
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   295
			//Update the queue
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   296
			if(frameNode.nextFrameQueueNode != null) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   297
				frameNode.nextFrameQueueNode.prevFrameQueueNode = newNode;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   298
				newNode.nextFrameQueueNode = frameNode.nextFrameQueueNode;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   299
				frameNode.nextFrameQueueNode = null;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   300
			}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   301
			if(frameNode.prevFrameQueueNode != null) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   302
				frameNode.prevFrameQueueNode.nextFrameQueueNode = newNode;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   303
				newNode.prevFrameQueueNode = frameNode.prevFrameQueueNode;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   304
				frameNode.prevFrameQueueNode = null;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   305
			}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   306
			if(newest.timeStamp == newNode.timeStamp) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   307
				newest = newNode;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   308
			}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   309
		}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   310
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   311
		return 0;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   312
	}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   313
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   314
	/** 
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   315
	 * Checks the oldest frame, if there is one, sees whether it is complete.
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   316
	 * @return Returns null if there are no complete frames available.
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   317
	 */
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   318
	protected synchronized DataFrame popOldestFrame() {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   319
		if(RTPSession.rtpDebugLevel > 7) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   320
			System.out.println("-> PktBuffer.popOldestFrame()");
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   321
		}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   322
		if(RTPSession.rtpDebugLevel > 10) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   323
			this.debugPrint();
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   324
		}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   325
		
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   326
		if(this.rtpSession.pktBufBehavior > 0) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   327
			return this.bufferedPopFrame();
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   328
		} else {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   329
			return this.unbufferedPopFrame();
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   330
		}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   331
	}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   332
	
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   333
	/**
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   334
	 * Will return the oldest frame without checking whether it is in
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   335
	 * the right order, or whether we should wate for late arrivals.
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   336
	 * 
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   337
	 * @return the first frame on the queue, null otherwise
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   338
	 */
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   339
	private DataFrame unbufferedPopFrame() {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   340
		if(oldest != null) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   341
			PktBufNode retNode = oldest;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   342
			
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   343
			popFrameQueueCleanup(retNode, retNode.seqNum);
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   344
			
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   345
			return new DataFrame(retNode, this.p, 
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   346
					rtpSession.appIntf.frameSize(retNode.pkt.getPayloadType()));
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   347
		} else {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   348
			return null;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   349
		}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   350
	}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   351
	
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   352
	/**
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   353
	 * Only returns if the buffer is full, i.e. length exceeds
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   354
	 * rtpSession.pktBufBehavior, or if the next packet directly
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   355
	 * follows the previous one returned to the application.
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   356
	 * 
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   357
	 * @return first frame in order, null otherwise
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   358
	 */
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   359
	private DataFrame bufferedPopFrame() {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   360
		PktBufNode retNode = oldest;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   361
		/**
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   362
		 * Three scenarios:
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   363
		 * 1) There are no packets available
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   364
		 * 2) The first packet is vailable and in order
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   365
		 * 3) The first packet is not the next on in the sequence
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   366
		 * 		a) We have exceeded the wait buffer
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   367
		 * 		b) We wait
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   368
		 */
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   369
		//System.out.println(" Debug:" +(retNode != null) + " " + (retNode.seqNum == this.lastSeqNumber + 1)
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   370
		//		+ " " + ( retNode.seqNum == 0 ) + " " +  (this.length > this.rtpSession.maxReorderBuffer)
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   371
		//		+ " " + (this.lastSeqNumber < 0));
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   372
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   373
		// Pop it off, null all references.
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   374
		if( retNode != null && (retNode.seqNum == this.lastSeqNumber + 1 || retNode.seqNum == 0 
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   375
					|| this.length > this.rtpSession.pktBufBehavior || this.lastSeqNumber < 0)) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   376
			
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   377
				
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   378
			//if(tmpNode.pktCount == compLen) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   379
			if(RTPSession.rtpDebugLevel > 7) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   380
				System.out.println("<- PktBuffer.popOldestFrame() returns frame");
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   381
			}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   382
			
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   383
			DataFrame df = new DataFrame(retNode, this.p, 
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   384
					rtpSession.appIntf.frameSize(oldest.pkt.getPayloadType()));
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   385
			
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   386
			//DataFrame df = new DataFrame(retNode, this.p, 1);
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   387
			popFrameQueueCleanup(retNode, df.lastSeqNum);
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   388
			
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   389
			return df;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   390
		
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   391
		} else {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   392
			// If we get here we have little to show for.
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   393
			if(RTPSession.rtpDebugLevel > 2) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   394
				System.out.println("<- PktBuffer.popOldestFrame() returns null " + retNode.seqNum + " " + this.lastSeqNumber);
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   395
				this.debugPrint();
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   396
			}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   397
			return null;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   398
		}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   399
	}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   400
	
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   401
	/**
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   402
	 * Cleans the packet buffer before returning the frame,
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   403
	 * i.e. making sure the queue has a head etc.
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   404
	 * 
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   405
	 * @param retNode the node that is about to be popped
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   406
	 * @param highestSeq the highest sequence number returned to the application
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   407
	 */
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   408
	private void popFrameQueueCleanup(PktBufNode retNode, int highestSeq) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   409
		if(1 == length) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   410
			//There's only one frame
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   411
			newest = null;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   412
			oldest = null;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   413
		} else {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   414
			//There are more frames
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   415
			oldest = oldest.prevFrameQueueNode;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   416
			oldest.nextFrameQueueNode = null;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   417
		}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   418
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   419
		// Update counters
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   420
		length--;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   421
		
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   422
		//Find the highest sequence number associated with this timestamp
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   423
		this.lastSeqNumber = highestSeq;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   424
		this.lastTimestamp = retNode.timeStamp;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   425
	}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   426
	
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   427
	/** 
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   428
	 * Returns the length of the packetbuffer.
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   429
	 * @return number of frames (complete or not) in packetbuffer.
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   430
	 */
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   431
	protected int getLength() {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   432
		return length;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   433
	}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   434
	
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   435
	/**
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   436
	 * Checks whether a packet is not too late, i.e. the next packet has already been returned.
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   437
	 * @param timeStamp the RTP timestamp of the packet under consideration 
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   438
	 * @param seqNum the sequence number of the packet under consideration
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   439
	 * @return true if newer packets have not been handed to the application
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   440
	 */
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   441
	protected boolean pktOnTime(long timeStamp, int seqNum) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   442
		if(this.lastSeqNumber == -1) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   443
			// First packet
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   444
			return true;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   445
		} else {			
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   446
			if(seqNum >= this.lastSeqNumber) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   447
				if(this.lastSeqNumber < 3 && timeStamp < this.lastTimestamp ) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   448
					return false;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   449
				}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   450
			} else {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   451
				if(seqNum > 3 || timeStamp < this.lastTimestamp) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   452
					return false;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   453
				}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   454
			}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   455
		}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   456
		return true;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   457
	}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   458
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   459
	/** 
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   460
	 * Prints out the packet buffer, oldest node first (on top).
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   461
	 */
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   462
	protected void debugPrint() {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   463
		System.out.println("PktBuffer.debugPrint() : length "+length+" SSRC "+SSRC+" lastSeqNum:"+lastSeqNumber);
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   464
		PktBufNode tmpNode = oldest;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   465
		int i = 0;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   466
		while(tmpNode != null) {
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   467
			//String str = tmpNode.timeStamp.toString();
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   468
			System.out.println("   " + i + " seqNum:"+tmpNode.seqNum+" timeStamp: " + tmpNode.timeStamp + " pktCount:" + tmpNode.pktCount );
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   469
			i++;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   470
			tmpNode = tmpNode.prevFrameQueueNode;
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   471
		}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   472
	}
e684f11070d5 ajout de jlibrtp
nikita@nikita-rack
parents:
diff changeset
   473
}