def test_repeated_alternating_put_get(): jitter_buffer = JitterBuffer(buffer_length=0) for i in range(1000): jitter_buffer.put_packet(i, i) out = jitter_buffer.get_packet() assert out == i assert len(jitter_buffer) == 0
def test_overly_large_seq_no(): jitter_buffer = JitterBuffer() # Set the roll-over value to a lower number to test the roll-over # code roll_over = 2 jitter_buffer._seq_no_rollover = roll_over with pytest.raises(Exception): jitter_buffer.put_packet(roll_over, None)
def __init__(self, host, port): super().__init__() self._host = host self._port = port # Initialise the jitter buffer packets_to_buffer = 3 self._jitter_buffer = JitterBuffer(packets_to_buffer) self._udp_packetizer = None
def test_get_out_of_order_packets(): # Create jitter buffer buffer_length = 0 jitter_buffer = JitterBuffer(buffer_length=buffer_length) # First valid put (sets expected value) value0 = 0 jitter_buffer.put_packet(value0, value0) assert len(jitter_buffer) == buffer_length + 1 # Out-of-order put value1 = 2 jitter_buffer.put_packet(value1, value1) assert len(jitter_buffer) == buffer_length + 2 # Get initial packet out = jitter_buffer.get_packet() assert out is value0 assert len(jitter_buffer) == buffer_length + 1 # Get missing packet out = jitter_buffer.get_packet() assert out is None assert len(jitter_buffer ) == buffer_length + 1 # because the None wasn't ever stored # Second get (from out-of-order packets) out = jitter_buffer.get_packet() assert out is value1 assert len(jitter_buffer) == buffer_length
def test_repeated_alternating_put_get_with_buffer(): buffer_length = 3 jitter_buffer = JitterBuffer(buffer_length=buffer_length) for i in range(1000): jitter_buffer.put_packet(i, i) out = jitter_buffer.get_packet() if i < buffer_length: assert out is None else: assert out == i - buffer_length assert len(jitter_buffer) == buffer_length
def test_out_of_order_packet(): jitter_buffer = JitterBuffer(buffer_length=0) jitter_buffer.put_packet(0, 0) assert len(jitter_buffer) == 1 out = jitter_buffer.get_packet() assert out == 0 assert len(jitter_buffer) == 0 # Packet should be discarded jitter_buffer.put_packet(0, 0) assert len(jitter_buffer) == 0 # Packet should be kept jitter_buffer.put_packet(2, 2) assert len(jitter_buffer) == 1
class UDPClientBase(DatagramProtocol): def __init__(self, host, port): super().__init__() self._host = host self._port = port # Initialise the jitter buffer packets_to_buffer = 3 self._jitter_buffer = JitterBuffer(packets_to_buffer) self._udp_packetizer = None def startProtocol(self): # "Connect" this to the server self.transport.connect(self._host, self._port) # Initialise UDP Packetizer self._udp_packetizer = UDPPacketizer(self.transport, (self._host, self._port)) def announce(self, client_id): # Announce to UDP server self._udp_packetizer.write_with_seq_no(struct.pack(">Q", client_id), -1) def datagramReceived(self, data, addr): #print("Received UDP packet from", addr) # Extract the timestamp, sequence number, and encoded frame timestamp, seq_no, encoded_packet = self._udp_packetizer.decode(data) # Put the encoded packet in the jitter buffer self._jitter_buffer.put_packet(seq_no, encoded_packet) # Possibly invoked if there is no server listening on the # address to which we are sending. def connectionRefused(self): print("No one listening; stopping") if reactor.running: log.error("STOPPING CLIENT") reactor.stop()
def test_stress_test2(): import random random.seed(1234) from collections import deque # Create jitter buffer jitter_buffer = JitterBuffer() # Set the roll-over value roll_over = 1000 jitter_buffer._seq_no_rollover = roll_over # Number of packets to simulate number_of_packets = 200000 # Duration per packet at source packet_duration = 20 / 1000 # seconds # Packet values packet_values = [i for i in range(number_of_packets)] # Generate missing packets prob_missing = 0.05 keep = int(len(packet_values) * (1 - prob_missing)) packet_values = random.sample(packet_values, keep) # Packet arrival times (no delay) packet_times = [i * packet_duration for i in packet_values] # Add noise in packet arrival time mu = 0 sigma = packet_duration * 5 packet_times = [t + random.gauss(mu, sigma) for t in packet_times] # Join the values and times packets = zip(packet_values, packet_times) # Sort the packets into the correct order sorted_packets = sorted(packets, key=lambda p: p[1]) sorted_packets = deque(sorted_packets) t = 0 + packet_duration while True: # If the deque is empty, break if len(sorted_packets) == 0: break # Put first packet into the buffer if it appears before time t if sorted_packets[0][1] < t: value = sorted_packets[0][0] #print("putting", value) jitter_buffer.put_packet(value % roll_over, value) sorted_packets.popleft() else: # Get the next packet out = jitter_buffer.get_packet() #print("got", out) # Increment simulated time t += packet_duration
def _process_announcement(self, data, addr): print("In _process_announcement") # Extract components timestamp, seq_no, packet_data = UDPPacketizer.decode(data) # Check the sequence number is -1 if seq_no != -1: log.warn( f"Expected announcement, but sequence number was "+ f"{seq_no} and not -1" ) return # Ensure packet data has exactly eight bytes if len(packet_data) != 8: log.warn( f"Expected announcement, but packet data had a "+ f"length of {len(packet_data)} bytes and not 8." ) return # Extract client_id from packet_data client_id = struct.unpack(">Q", packet_data)[0] print("after unpack") log.info( f"Creating UDP connection to client id {client_id} "+ f"with address {addr}." ) print("after log") # Create UDPPacketizer for this address udp_packetizer = UDPPacketizer(self.transport, addr) # Create a JitterBuffer for this address packets_to_buffer = 3 jitter_buffer = JitterBuffer(packets_to_buffer) # Store connection details self._connections_by_address[addr] = { "udp_packetizer": udp_packetizer, "jitter_buffer": jitter_buffer } self._address_by_client_id[client_id] = addr # Announce to Participants self._participants.join_udp(client_id)
def test_get_from_empty(): buffer_length = 0 jitter_buffer = JitterBuffer(buffer_length=buffer_length) # First valid put value = 0 jitter_buffer.put_packet(0, value) assert len(jitter_buffer) == buffer_length + 1 # Get after put out = jitter_buffer.get_packet() assert out == value assert len(jitter_buffer) == buffer_length # Second get (from empty buffer) out = jitter_buffer.get_packet() assert out is None assert len(jitter_buffer) == 0
def test_ignores_before_first_put(): buffer_length = 1 jitter_buffer = JitterBuffer(buffer_length=buffer_length) # Get before put out = jitter_buffer.get_packet() assert out is None assert len(jitter_buffer) == buffer_length # First valid put value = 0 jitter_buffer.put_packet(0, value) assert len(jitter_buffer) == buffer_length + 1 # Get after put out = jitter_buffer.get_packet() assert out is None assert len(jitter_buffer) == buffer_length out = jitter_buffer.get_packet() assert out == value assert len(jitter_buffer) == buffer_length - 1
def test_len_zero_items_zero_buffer(): jitter_buffer = JitterBuffer(buffer_length=0) assert len(jitter_buffer) == 0
def test_create_jitter_buffer(): jitter_buffer = JitterBuffer()
def test_len_zero_items_non_zero_buffer(): buffer_length = 2 jitter_buffer = JitterBuffer(buffer_length=buffer_length) assert len(jitter_buffer) == buffer_length