Esempio n. 1
0
    def __init__(self, bitrate=0.0):
        self.codec = VideoCodec()
        # set frame size fixed
        if not Example_sender.with_frame:
            self.codec.is_fix_frame_size = True

        # update the rate the codec choose
        self.set_bitrate(bitrate)
        self.rate = 0.0

        self.buffer = []
        self.read_frame_interval = 33  # ms
        self.last_read_frame_time = 0

        self.inuse_bitrate = 0
        self.last_set_bitrate_time = 0
        self.set_bitrate_interval = 1000  # ms

        self.cwnd = 10
Esempio n. 2
0
    def __init__(self):
        TCP_CONGESTION = getattr(socket, 'TCP_CONGESTION', 13)
        self.sock = socket.socket()
        self.sock.setsockopt(socket.IPPROTO_TCP, TCP_CONGESTION, 'bbr')
        # self.sock.setsockopt(socket.SOL_SOCKET, socket.MSG_NOSIGNAL, 1)

        self.peer_addr = ('100.64.0.1', 10100)
        # self.peer_addr = ('127.0.0.1', 10100)
        self.sock.connect(self.peer_addr)

        sys.stderr.write("[sender] bbr is running\n")

        self.rate = START_RATE

        self.codec = VideoCodec()
        if not Sender.with_frame:
            self.codec.is_fix_frame_size = True
        self.codec.choose_bps(START_RATE)

        self.buffer = []
        self.read_frame_interval = 33
        self.last_read_frame_time = 0

        self.inuse_bitrate = 0
        self.last_set_bitrate_time = 0
        self.set_bitrate_interval = 1000  # ms

        self.packets_interval = 1500 * 8.0 / (START_RATE)  # the interval between two packets
        self.next_packet_timestamp = time.time()

        self.sent = 0

        # self.kernel_path = "./kernel_info/bbr_kernel.log"

        # record the log
        if Sender.is_multi:
            self.log_path = os.path.join(Sender.dir, 'log', Sender.subdir, 'BBR_send_multi.log')
            self.f = open(self.log_path, mode='w')
        else:
            self.log_path = os.path.join(Sender.dir, 'log', Sender.subdir, 'BBR_send_single.log')
            self.f = open(self.log_path, mode='w')
Esempio n. 3
0
class Sender(object):
    dir = './'
    with_frame = True
    subdir = ''
    is_multi = False

    def __init__(self):
        TCP_CONGESTION = getattr(socket, 'TCP_CONGESTION', 13)
        self.sock = socket.socket()
        self.sock.setsockopt(socket.IPPROTO_TCP, TCP_CONGESTION, 'pcc')
        # self.sock.setsockopt(socket.SOL_SOCKET, socket.MSG_NOSIGNAL, 1)

        self.peer_addr = ('100.64.0.1', 12000)
        # self.peer_addr = ('127.0.0.1', 10100)
        self.sock.connect(self.peer_addr)

        self.rate = START_RATE

        self.codec = VideoCodec()
        if not Sender.with_frame:
            self.codec.is_fix_frame_size = True
        self.codec.choose_bps(START_RATE)

        self.buffer = []
        self.read_frame_interval = 33
        self.last_read_frame_time = 0

        self.inuse_bitrate = 0
        self.last_set_bitrate_time = 0
        self.set_bitrate_interval = 1000  # ms

        self.packets_interval = 1500 * 8.0 / (
            START_RATE)  # the interval between two packets
        self.next_packet_timestamp = time.time()

        # record the log
        if Sender.is_multi:
            self.log_path = os.path.join(Sender.dir, 'log', Sender.subdir,
                                         'pcc_vivace_send_multi.log')
            self.f = open(self.log_path, mode='w')
        else:
            self.log_path = os.path.join(Sender.dir, 'log', Sender.subdir,
                                         'pcc_vivace_send_single.log')
            self.f = open(self.log_path, mode='w')

        self.sent = 0

    def set_bitrate(self, bitrate):
        if ((True) or (self.last_set_bitrate_time == 0) or
            ((1000 * (time.time() - self.last_set_bitrate_time) >
              self.set_bitrate_interval) and
             (abs(self.inuse_bitrate - bitrate) / float(self.inuse_bitrate) >
              0.1))):
            self.last_set_bitrate_time = time.time()
            self.inuse_bitrate = bitrate
            self.codec.choose_bps(bitrate)

    def read_frame_info(self):
        self.set_bitrate(self.rate)  # the codec needs bps
        if Sender.with_frame:
            if self.last_read_frame_time == 0:
                self.last_read_frame_time = time.time()
                self.codec.add_frame()
            elif 1000 * (time.time() -
                         self.last_read_frame_time) > self.read_frame_interval:
                n = 1000 * (time.time() - self.last_read_frame_time
                            ) // self.read_frame_interval
                for i in range(int(n)):
                    self.codec.add_frame()
                self.last_read_frame_time = time.time()
            # add packets to buffer
            new_frame_packet_list = self.codec.read_frame_data()
            self.buffer += new_frame_packet_list
        else:
            # the buffer is empty
            if len(self.buffer) == 0:
                self.codec.add_frame()
                new_frame_packet_list = self.codec.read_frame_data()
                self.buffer += new_frame_packet_list

    def read_kernel_info(self):
        pcc_pacing_rate = get_pcc_pacing_rate()
        if pcc_pacing_rate != 0:
            self.rate = pcc_pacing_rate * 8

        send_rate = "time: " + str(curr_ts_ms()) + " send_rate: " + str(
            self.rate / 1000000.0) + " mbps\n"
        self.f.write(send_rate)
        self.f.flush()
        # print(str(self.rate / 1000000.0) + " mbps(pcc)")

    def get_sending_rate(self):
        while True:
            sys.stderr.write("sender: " +
                             str(self.sent * 1500 * 8 / 1000000.0) + " mbps\n")
            sys.stderr.flush()
            self.sent = 0
            time.sleep(1)

    def send(self):
        while True:
            self.read_kernel_info()
            self.read_frame_info()
            if len(self.buffer) != 0:
                current_timestamp = time.time()
                self.packets_interval = 1500 * 8.0 / self.rate  # second, the interval is too
                if current_timestamp > self.next_packet_timestamp + self.packets_interval:
                    packet = self.buffer.pop(0)
                    packet.send_time_ms = int(1000 * time.time())
                    # packet.payload = (1000) * '#'
                    data = jsonpickle.encode(packet)
                    # data = json.dumps(packet.to_dict())
                    offset = 1500 - len(data)
                    data += " " * offset
                    self.sock.send(data)
                    self.next_packet_timestamp = current_timestamp
                    self.sent += 1

    def run(self):
        thread = threading.Thread(target=self.get_sending_rate, args=())
        thread.setDaemon(True)
        thread.start()
        self.send()

    def cleanup(self):
        self.sock.close()
Esempio n. 4
0
    def __init__(self, ip, port):
        self.peer_addr = (ip, port)

        # UDP socket and poller
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

        self.poller = select.poll()
        self.poller.register(self.sock, ALL_FLAGS)

        self.seq_num = 1

        # the rtt during a MI
        self.rtt_samples = []

        # the parameters of neural network input
        self.latency_inflation = [0.0] * HISTORY_LENGTH
        self.latency_ratio = [1.0] * HISTORY_LENGTH
        self.send_ratio = [1.0] * HISTORY_LENGTH

        self.run_during = 800  # the initial running during (ms), it may need long
        self.last_MI_start_time = None  # last monitor interval start time
        self.MI_end_time = None  # monitor interval end time

        self.sent = 0  # the nun of packets sent during the MI
        self.acked = 0  # the num of acks received during the MI

        self.avg_latency = None  # the avg_latency in a MI
        self.min_latency = None  # the min avg_latency of all past avg_latency

        self.rate = START_RATE

        self.agent = loaded_agent.LoadedModelAgent(
            "./Congestion_controller/model_A")

        # record the log
        if Sender.is_multi:
            self.log_path = os.path.join(Sender.dir, 'log', Sender.subdir,
                                         'Aurora_send_multi.log')
            self.f = open(self.log_path, mode='w')
        else:
            self.log_path = os.path.join(Sender.dir, 'log', Sender.subdir,
                                         'Aurora_send_single.log')
            self.f = open(self.log_path, mode='w')

        self.codec = VideoCodec()
        # without frame
        if not Sender.with_frame:
            self.codec.is_fix_frame_size = True
        self.codec.choose_bps(START_RATE * 1000000)

        self.buffer = []
        self.read_frame_interval = 33
        self.last_read_frame_time = 0

        self.inuse_bitrate = 0
        self.last_set_bitrate_time = 0
        self.set_bitrate_interval = 1000  # ms

        self.packets_interval = 1500 * 8.0 / (
            START_RATE * 1000000)  # the interval between two packets
        self.true_rate = START_RATE

        self.next_packet_timestamp = time.time()
Esempio n. 5
0
class Sender(object):
    dir = './'
    subdir = ''

    is_multi = False
    with_frame = True

    def __init__(self, ip, port):
        self.peer_addr = (ip, port)

        # UDP socket and poller
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

        self.poller = select.poll()
        self.poller.register(self.sock, ALL_FLAGS)

        self.seq_num = 1

        # the rtt during a MI
        self.rtt_samples = []

        # the parameters of neural network input
        self.latency_inflation = [0.0] * HISTORY_LENGTH
        self.latency_ratio = [1.0] * HISTORY_LENGTH
        self.send_ratio = [1.0] * HISTORY_LENGTH

        self.run_during = 800  # the initial running during (ms), it may need long
        self.last_MI_start_time = None  # last monitor interval start time
        self.MI_end_time = None  # monitor interval end time

        self.sent = 0  # the nun of packets sent during the MI
        self.acked = 0  # the num of acks received during the MI

        self.avg_latency = None  # the avg_latency in a MI
        self.min_latency = None  # the min avg_latency of all past avg_latency

        self.rate = START_RATE

        self.agent = loaded_agent.LoadedModelAgent(
            "./Congestion_controller/model_A")

        # record the log
        if Sender.is_multi:
            self.log_path = os.path.join(Sender.dir, 'log', Sender.subdir,
                                         'Aurora_send_multi.log')
            self.f = open(self.log_path, mode='w')
        else:
            self.log_path = os.path.join(Sender.dir, 'log', Sender.subdir,
                                         'Aurora_send_single.log')
            self.f = open(self.log_path, mode='w')

        self.codec = VideoCodec()
        # without frame
        if not Sender.with_frame:
            self.codec.is_fix_frame_size = True
        self.codec.choose_bps(START_RATE * 1000000)

        self.buffer = []
        self.read_frame_interval = 33
        self.last_read_frame_time = 0

        self.inuse_bitrate = 0
        self.last_set_bitrate_time = 0
        self.set_bitrate_interval = 1000  # ms

        self.packets_interval = 1500 * 8.0 / (
            START_RATE * 1000000)  # the interval between two packets
        self.true_rate = START_RATE

        self.next_packet_timestamp = time.time()

    def cleanup(self):
        self.sock.close()

    def handshake(self):
        """Handshake with peer sender. Must be called before run()."""

        self.sock.setblocking(False)  # non-blocking UDP socket

        TIMEOUT = 1000  # ms

        retry_times = 0
        self.poller.modify(self.sock, READ_ERR_FLAGS)

        while True:
            self.sock.sendto(str.encode('Hello from receiver'), self.peer_addr)
            events = self.poller.poll(TIMEOUT)

            if not events:  # timed out
                retry_times += 1
                if retry_times > 30:
                    sys.stderr.write(
                        '[Sender] Handshake failed after 10 retries\n')
                    return
                else:
                    sys.stderr.write(
                        '[Sender] Handshake timed out and retrying...\n')
                    continue

            for fd, flag in events:
                assert self.sock.fileno() == fd

                if flag & ERR_FLAGS:
                    sys.exit('Channel closed or error occurred')

                if flag & READ_FLAGS:
                    msg, addr = self.sock.recvfrom(1600)
                    if addr == self.peer_addr:
                        return

    def window_is_open(self):
        return True  # without window control

    def set_bitrate(self, bitrate):
        if ((True) or (self.last_set_bitrate_time == 0) or
            ((1000 * (time.time() - self.last_set_bitrate_time) >
              self.set_bitrate_interval) and
             (abs(self.inuse_bitrate - bitrate) / float(self.inuse_bitrate) >
              0.1))):
            self.last_set_bitrate_time = time.time()
            self.inuse_bitrate = bitrate
            self.codec.choose_bps(bitrate)

    def read_frame_info(self):
        self.set_bitrate(self.rate *
                         1000000.0)  # the codec needs bps (mbps->bps)
        if Sender.with_frame:
            if self.last_read_frame_time == 0:
                self.last_read_frame_time = time.time()
                self.codec.add_frame()
            elif 1000 * (time.time() -
                         self.last_read_frame_time) > self.read_frame_interval:
                n = 1000 * (time.time() - self.last_read_frame_time
                            ) // self.read_frame_interval
                # print("read frame ",n)
                for i in range(int(n)):
                    self.codec.add_frame()
                self.last_read_frame_time = time.time()
            # add packets to buffer
            new_frame_packet_list = self.codec.read_frame_data()
            self.buffer += new_frame_packet_list
        else:
            # the buffer is empty
            if not self.buffer or len(self.buffer) == 0:
                self.codec.add_frame()
                new_frame_packet_list = self.codec.read_frame_data()
                self.buffer += new_frame_packet_list

    def on_packet_acked(self, rtt):
        self.acked += 1
        self.rtt_samples.append(rtt)

    def get_latency_increase(self):
        half = int(len(self.rtt_samples) / 2)
        if half >= 1:
            return np.mean(self.rtt_samples[half:]) - np.mean(
                self.rtt_samples[:half])
        else:
            return 0.0

    def get_latency_inflation(self):
        latency_increase = self.get_latency_increase()
        if self.run_during > 0.0:
            return latency_increase / self.run_during
        else:
            return 0.0

    def get_send_rate(self):
        if self.run_during > 0.0:
            return 8.0 * self.sent * 1500 / self.run_during
        else:
            return 0.0

    def get_recv_rate(self):
        if self.run_during > 0.0:
            return 8.0 * (self.acked - 1) * 1500 / self.run_during
        return 0.0

    def get_send_ratio(self):
        '''
        :return: send_ratio float
        '''
        send_rate = self.get_send_rate()
        recv_throughput = self.get_recv_rate()
        if recv_throughput > 0.0 and send_rate < 1000.0 * recv_throughput:
            return send_rate / recv_throughput
        return 1.0

    def get_avg_latency(self):
        if len(self.rtt_samples) > 0:
            self.avg_latency = np.mean(self.rtt_samples)
        else:
            self.avg_latency = 0.0

    def get_min_latency(self):
        # the first state
        if self.min_latency is None:
            if self.avg_latency > 0.0:
                self.min_latency = self.avg_latency
            else:
                self.min_latency = 0.0
        # the state except the first time
        else:
            # the avg_latency is not 0.0 and less than min_latency
            if self.avg_latency > 0.0 and self.avg_latency < self.min_latency:
                self.min_latency = self.avg_latency
            else:
                pass
        # print "avg " + str(self.avg_latency)
        # print "min " + str(self.min_latency)

    def get_latency_ratio(self):
        '''
        :return: latency_ration float
        '''
        self.get_avg_latency()
        self.get_min_latency()
        # print "avg_latency" + str(self.avg_latency)
        # print "min_latency" + str(self.min_latency)
        if self.min_latency > 0.0:
            return self.avg_latency / self.min_latency
        return 1.0

    def get_pacer_rate(self):
        packets_in_buffer = len(self.buffer)
        pacer_rate = packets_in_buffer * 1500 * 8 / 2.0 / 1000000  # empty the buffer in 2 seconds, return mbps
        return pacer_rate

    def set_rate(self, new_rate):
        self.rate = new_rate
        if self.rate > MAX_RATE:
            self.rate = MAX_RATE
        if self.rate < MIN_RATE:
            self.rate = MIN_RATE

    def apply_rate_delta(self, delta):
        delta *= DELTA_SCALE
        if delta >= 0.0:
            self.set_rate(self.rate * (1.0 + delta))
        else:
            self.set_rate(self.rate / (1.0 - delta))

    def send(self):
        packet = Packet()
        packet.send_time = time.time() * 1000  # to ms
        packet.seq_num = self.seq_num

        # add video frame
        packet_video = self.buffer.pop(0)
        packet.frame_id = packet_video.frame_id
        packet.frame_start_packet_seq = packet_video.frame_start_packet_seq
        packet.frame_end_packet_seq = packet_video.frame_end_packet_seq
        packet.codec_bitrate = packet_video.codec_bitrate

        # serialize
        data = jsonpickle.encode(packet)
        # print len(data)
        self.sock.sendto(data, self.peer_addr)

        info = "seq:" + str(packet.seq_num) + " frame_id:" + str(
            packet.frame_id) + " send_ms:" + str(
                packet.send_time) + " frame_start:" + str(
                    packet.frame_start_packet_seq) + " frame_end:" + str(
                        packet.frame_end_packet_seq) + "\n"

        # sys.stderr.write(info)

        # when send a packet
        self.seq_num += 1
        self.sent += 1

    def recv(self):
        serialized_ack, addr = self.sock.recvfrom(1600)
        if addr != self.peer_addr:
            return
        ack = jsonpickle.decode(serialized_ack)
        ack.ack_receive_time = time.time() * 1000.0  # to ms

        # rtt formulate : ack_receive - packet_send (ms)
        rtt = ack.ack_receive_time - ack.packet_send_time
        self.on_packet_acked(rtt=rtt)

    def send_thread(self):
        # keep sending
        while True:
            self.read_frame_info()
            if self.buffer and len(self.buffer) != 0:
                if Sender.with_frame:
                    # update the sending rate
                    pacer_rate = self.get_pacer_rate()
                    # print self.rate
                    # print self.true_rate
                    self.true_rate = max(self.rate, pacer_rate)
                    self.packets_interval = PACKET_SIZE * 8.0 / (
                        self.true_rate * 1000000)  # second
                    current_timestamp = time.time()
                    if current_timestamp > self.next_packet_timestamp + self.packets_interval:
                        self.send()
                        self.next_packet_timestamp = current_timestamp
                else:
                    self.packets_interval = PACKET_SIZE * 8.0 / (
                        self.rate * 1000000)  # second
                    current_timestamp = time.time()
                    if current_timestamp > self.next_packet_timestamp + self.packets_interval:
                        self.send()
                        self.next_packet_timestamp = current_timestamp

    def recv_thread(self):
        # keep receiving
        while True:
            self.recv()

    def get_throughput(self):
        while True:
            sys.stderr.write("Aurora sender: " + str(self.rate) +
                             " mbps\n")  # the rate of algorithms
            sys.stderr.flush()
            time.sleep(1)  # second

    def run(self):
        TIMEOUT = 1000  # ms
        self.poller.modify(self.sock, ALL_FLAGS)
        self.sock.setblocking(True)

        # execute send and receive thread
        thread_send = threading.Thread(target=self.send_thread, args=())
        thread_recv = threading.Thread(target=self.recv_thread, args=())
        # print the throughput each second
        thread_get_throughput = threading.Thread(target=self.get_throughput,
                                                 args=())

        thread_send.setDaemon(True)
        thread_recv.setDaemon(True)
        thread_get_throughput.setDaemon(True)

        thread_send.start()
        thread_recv.start()
        thread_get_throughput.start()

        while True:
            # the monitor interval start and end time
            if self.last_MI_start_time is None:
                self.last_MI_start_time = time.time() * 1000  # to ms
            self.MI_end_time = self.last_MI_start_time + self.run_during

            # during the MI
            while time.time() * 1000 < self.MI_end_time:
                events = self.poller.poll(TIMEOUT)
                for fd, flag in events:
                    assert self.sock.fileno() == fd

                    if flag & ERR_FLAGS:
                        sys.exit('Error occurred to the channel')
            # end while (during MI)

            # print(self.rtt_samples)
            # print self.sent
            # print self.acked

            latency_inflation = self.get_latency_inflation()
            latency_ratio = self.get_latency_ratio()
            send_ratio = self.get_send_ratio()

            # reset the rtt_samples and so on.
            self.reset()

            self.latency_inflation.pop(0)
            self.latency_ratio.pop(0)
            self.send_ratio.pop(0)

            self.latency_inflation.append(latency_inflation)
            self.latency_ratio.append(latency_ratio)
            self.send_ratio.append(send_ratio)

            # print "latency inflation, latency ratio, send ratio"
            # print self.latency_inflation
            # print self.latency_ratio
            # print self.send_ratio

            # the input of the neural network
            history = []
            for i in range(HISTORY_LENGTH):
                array = [
                    self.latency_inflation[i], self.latency_ratio[i],
                    self.send_ratio[i]
                ]
                history.append(array)
            history = np.array(history).flatten()

            # call the neural network, get the delta
            delta = self.agent.act(history)
            # if delta < 0.0:
            # print "delta" + str(delta)

            # update rate
            self.apply_rate_delta(delta=delta)

            send_rate = "time: " + str(curr_ts_ms()) + " send_rate: " + str(
                self.rate) + " mbps\n"
            self.f.write(send_rate)
            self.f.flush()

            # update the rate that codec choose
            self.set_bitrate(self.rate * 1000000)  # mbps->bps

            # print str(self.rate) + " mbps"

            # update next run_during
            if self.avg_latency > 0.0:
                self.run_during = 0.5 * self.avg_latency
            # print "run_during " + str(self.run_during)

            # current MI_end_time is next MI_start_time
            self.last_MI_start_time = self.MI_end_time

    def reset(self):
        self.rtt_samples = []
        self.sent = 0
        self.acked = 0
Esempio n. 6
0
class Example_sender(object):
    with_frame = False

    def __init__(self, bitrate=0.0):
        self.codec = VideoCodec()
        # set frame size fixed
        if not Example_sender.with_frame:
            self.codec.is_fix_frame_size = True

        # update the rate the codec choose
        self.set_bitrate(bitrate)
        self.rate = 0.0

        self.buffer = []
        self.read_frame_interval = 33  # ms
        self.last_read_frame_time = 0

        self.inuse_bitrate = 0
        self.last_set_bitrate_time = 0
        self.set_bitrate_interval = 1000  # ms

        self.cwnd = 10

    def set_bitrate(self, bitrate):
        self.rate = bitrate
        if ((True) or (self.last_set_bitrate_time == 0) or
            ((1000 * (time.time() - self.last_set_bitrate_time) >
              self.set_bitrate_interval) and
             (abs(self.inuse_bitrate - bitrate) / float(self.inuse_bitrate) >
              0.1))):
            self.last_set_bitrate_time = time.time()
            self.inuse_bitrate = bitrate
            self.codec.choose_bps(bitrate)

    def send_data(self):
        packet = Packet()
        pass

    def read_frame_info(self):
        if Sender.with_frame:
            if self.last_read_frame_time == 0:
                self.last_read_frame_time = time.time()
                self.codec.add_frame()
            elif 1000 * (time.time() -
                         self.last_read_frame_time) > self.read_frame_interval:
                n = 1000 * (time.time() - self.last_read_frame_time
                            ) // self.read_frame_interval
                # print("read frame ",n)
                for i in range(int(n)):
                    self.codec.add_frame()
                self.last_read_frame_time = time.time()

                # add packets to buffer
            new_frame_packet_list = self.codec.read_frame_data()
            self.buffer += new_frame_packet_list

            self.set_bitrate(self.rate)
        else:
            # the buffer is empty
            if not self.buffer or len(self.buffer) == 0:
                self.codec.add_frame()
                new_frame_packet_list = self.codec.read_frame_data()
                self.buffer += new_frame_packet_list

    def send(self):

        while True:
            # with video frame
            if Example_sender.with_frame:
                if self.last_read_frame_time == 0:
                    self.last_read_frame_time = time.time()
                    self.codec.add_frame()
                elif 1000 * (time.time() - self.last_read_frame_time
                             ) > self.read_frame_interval:
                    n = 1000 * (time.time() - self.last_read_frame_time
                                ) // self.read_frame_interval
                    # print("read frame ",n)
                    for i in range(int(n)):
                        self.codec.add_frame()
                    self.last_read_frame_time = time.time()

                # add packets to buffer
                new_frame_packet_list = self.codec.read_frame_data()
                self.buffer += new_frame_packet_list

                self.set_bitrate(self.rate)

                if self.buffer and len(self.buffer) != 0:
                    self.send_data()
            # without frame
            else:
                # the buffer is empty
                if not self.buffer or len(self.buffer) == 0:
                    self.codec.add_frame()
                    new_frame_packet_list = self.codec.read_frame_data()
                    self.buffer += new_frame_packet_list
                self.set_bitrate(self.rate)
                self.send_data()

    def recv(self, ack):
        rtt = time.time() * 1000 - ack.packet_send_time  # ms
        rtt /= 1000.0  # second
        new_bitrate = self.cwnd * 1500 * 8.0 / rtt  # bps
        self.set_bitrate(new_bitrate)
Esempio n. 7
0
    def __init__(self, ip, port):
        self.peer_addr = (ip, port)

        # UDP socket and poller
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

        self.poller = select.poll()
        self.poller.register(self.sock, ALL_FLAGS)

        self.window_size = 10
        self.seq_num = 1
        self.next_ack = 1

        # current received packet
        self.packet_send_time = 0
        self.packet_receive_time = 0
        # last packet
        self.last_packet_send_time = 0
        self.last_packet_receive_time = 0

        self.rtt = 0
        self.min_rtt = 0

        self.flag_first_packet = 1  # default 1

        self.s_ewma = 0
        self.r_ewma = 0
        self.slow_r_ewma = 0
        self.rtt_ratio = 1.0

        self.win_multiple = 1
        self.win_increment = 1
        self.intersend = 3

        self.last_sent_time = 0

        # get the rule list
        self.rule = Rule()
        self.rule_list = self.rule.generate(outfile="./remy/log.txt")

        self.cc = 0

        self.sent = 0

        # add frame info
        self.codec = VideoCodec()
        # fix the frame size
        if not Sender.with_frame:
            self.codec.is_fix_frame_size = True
        self.rate = START_RATE  # default
        self.set_bitrate(bitrate=self.rate)

        self.buffer = []
        self.read_frame_interval = 33  # ms
        self.last_read_frame_time = 0

        self.inuse_bitrate = 0
        self.last_set_bitrate_time = 0
        self.set_bitrate_interval = 1000  # ms

        if Sender.is_multi:
            self.log_path = os.path.join(Sender.dir, 'log', Sender.subdir,
                                         'RemyCC_send_multi.log')
            self.f = open(self.log_path, mode='w')
        else:
            self.log_path = os.path.join(Sender.dir, 'log', Sender.subdir,
                                         'RemyCC_send_single.log')
            self.f = open(self.log_path, mode='w')

        self.next_packet_timestamps = time.time()
Esempio n. 8
0
class Sender(object):
    alpha = 1.0 / 8.0
    slow_alpha = 1.0 / 256.0

    with_frame = True
    is_multi = False

    dir = './'
    subdir = ''

    def __init__(self, ip, port):
        self.peer_addr = (ip, port)

        # UDP socket and poller
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

        self.poller = select.poll()
        self.poller.register(self.sock, ALL_FLAGS)

        self.window_size = 10
        self.seq_num = 1
        self.next_ack = 1

        # current received packet
        self.packet_send_time = 0
        self.packet_receive_time = 0
        # last packet
        self.last_packet_send_time = 0
        self.last_packet_receive_time = 0

        self.rtt = 0
        self.min_rtt = 0

        self.flag_first_packet = 1  # default 1

        self.s_ewma = 0
        self.r_ewma = 0
        self.slow_r_ewma = 0
        self.rtt_ratio = 1.0

        self.win_multiple = 1
        self.win_increment = 1
        self.intersend = 3

        self.last_sent_time = 0

        # get the rule list
        self.rule = Rule()
        self.rule_list = self.rule.generate(outfile="./remy/log.txt")

        self.cc = 0

        self.sent = 0

        # add frame info
        self.codec = VideoCodec()
        # fix the frame size
        if not Sender.with_frame:
            self.codec.is_fix_frame_size = True
        self.rate = START_RATE  # default
        self.set_bitrate(bitrate=self.rate)

        self.buffer = []
        self.read_frame_interval = 33  # ms
        self.last_read_frame_time = 0

        self.inuse_bitrate = 0
        self.last_set_bitrate_time = 0
        self.set_bitrate_interval = 1000  # ms

        if Sender.is_multi:
            self.log_path = os.path.join(Sender.dir, 'log', Sender.subdir,
                                         'RemyCC_send_multi.log')
            self.f = open(self.log_path, mode='w')
        else:
            self.log_path = os.path.join(Sender.dir, 'log', Sender.subdir,
                                         'RemyCC_send_single.log')
            self.f = open(self.log_path, mode='w')

        self.next_packet_timestamps = time.time()

    def set_bitrate(self, bitrate):
        self.rate = bitrate
        if ((True) or (self.last_set_bitrate_time == 0) or
            ((1000 * (time.time() - self.last_set_bitrate_time) >
              self.set_bitrate_interval) and
             (abs(self.inuse_bitrate - bitrate) / float(self.inuse_bitrate) >
              0.1))):
            self.last_set_bitrate_time = time.time()
            self.inuse_bitrate = bitrate
            self.codec.choose_bps(bitrate)

    def get_pacer_rate(self):
        packets_in_buffer = len(self.buffer)
        pacer_rate = packets_in_buffer * 1500 * 8 / 2  # bps
        return pacer_rate

    def get_rate_from_window(self):
        # print self.rtt
        new_rate = self.window_size * 1500 * 8.0 / (self.rtt / 1000)  # bps
        return new_rate

    def read_frame_info(self):
        self.set_bitrate(self.rate)
        if Sender.with_frame:
            if self.last_read_frame_time == 0:
                self.last_read_frame_time = time.time()
                self.codec.add_frame()
            elif 1000 * (time.time() -
                         self.last_read_frame_time) > self.read_frame_interval:
                n = 1000 * (time.time() - self.last_read_frame_time
                            ) // self.read_frame_interval
                # print("read frame ",n)
                for i in range(int(n)):
                    self.codec.add_frame()
                self.last_read_frame_time = time.time()

                # add packets to buffer
            new_frame_packet_list = self.codec.read_frame_data()
            self.buffer += new_frame_packet_list

            self.set_bitrate(self.rate)
        else:
            # the buffer is empty
            if not self.buffer or len(self.buffer) == 0:
                self.codec.add_frame()
                new_frame_packet_list = self.codec.read_frame_data()
                self.buffer += new_frame_packet_list

    def cleanup(self):
        self.sock.close()

    def handshake(self):
        """Handshake with peer sender. Must be called before run()."""

        self.sock.setblocking(False)  # non-blocking UDP socket

        TIMEOUT = 1000  # ms

        retry_times = 0
        self.poller.modify(self.sock, READ_ERR_FLAGS)

        while True:
            self.sock.sendto(str.encode('Hello from receiver'), self.peer_addr)
            events = self.poller.poll(TIMEOUT)

            if not events:  # timed out
                retry_times += 1
                if retry_times > 30:
                    sys.stderr.write(
                        '[Sender] Handshake failed after 10 retries\n')
                    return
                else:
                    sys.stderr.write(
                        '[Sender] Handshake timed out and retrying...\n')
                    continue

            for fd, flag in events:
                assert self.sock.fileno() == fd

                if flag & ERR_FLAGS:
                    sys.exit('Channel closed or error occurred')

                if flag & READ_FLAGS:
                    msg, addr = self.sock.recvfrom(1600)

                    if addr == self.peer_addr:
                        return

    def window_is_open(self):
        return self.seq_num < self.next_ack + self.window_size

    def send(self):
        # the interval between two packets
        if 1000 * time.time() - self.last_sent_time > self.intersend:
            video_packet = self.buffer.pop(0)

            packet = Packet()
            packet.send_time = time.time() * 1000
            packet.seq_num = self.seq_num

            # the video frame info
            packet.frame_id = video_packet.frame_id
            packet.frame_start_packet_seq = video_packet.frame_start_packet_seq
            packet.frame_end_packet_seq = video_packet.frame_end_packet_seq
            packet.codec_bitrate = video_packet.codec_bitrate

            # serialize
            data = jsonpickle.encode(packet)
            # print len(data)
            self.sock.sendto(data, self.peer_addr)

            info = "seq:" + str(packet.seq_num) + " frame_id:" + str(
                packet.frame_id) + " send_ms:" + str(
                    packet.send_time) + " frame_start:" + str(
                        packet.frame_start_packet_seq) + " frame_end:" + str(
                            packet.frame_end_packet_seq) + "\n"

            # sys.stderr.write(info)

            # save the last packet send time
            self.last_sent_time = packet.send_time
            self.seq_num += 1

            self.sent += 1

    def recv(self):
        serialized_ack, addr = self.sock.recvfrom(1600)

        if addr != self.peer_addr:
            return
        try:
            ack = jsonpickle.decode(serialized_ack)
        except BaseException as e:
            return
        ack.ack_receive_time = time.time() * 1000.0  # to ms
        # get the next ack
        self.next_ack = max(self.next_ack, ack.seq_num + 1)

        # rtt formulate : ack_receive - packet_send
        self.rtt = ack.ack_receive_time - ack.packet_send_time

        # first packet
        if self.flag_first_packet == 1:
            self.flag_first_packet = 0  # reset 0
            self.last_packet_send_time = ack.packet_send_time
            self.last_packet_receive_time = ack.packet_receive_time
            self.min_rtt = self.rtt
        # not first packet
        else:
            self.packet_send_time = ack.packet_send_time
            self.packet_receive_time = ack.packet_receive_time

            self.s_ewma = (1 - Sender.alpha) * self.s_ewma + Sender.alpha * (
                self.packet_send_time - self.last_packet_send_time)
            self.r_ewma = (1 - Sender.alpha) * self.r_ewma + Sender.alpha * (
                self.packet_receive_time - self.last_packet_receive_time)
            self.slow_r_ewma = (
                1 -
                Sender.slow_alpha) * self.slow_r_ewma + Sender.slow_alpha * (
                    self.packet_receive_time - self.last_packet_receive_time)

            # upgrade the last packet
            self.last_packet_send_time = self.packet_send_time
            self.last_packet_receive_time = self.packet_receive_time
            self.min_rtt = min(self.min_rtt, self.rtt)

            self.rtt_ratio = self.rtt * 1.0 / self.min_rtt

            # print self.s_ewma, self.r_ewma, self.rtt_ratio, self.slow_r_ewma

            self.win_increment, self.win_multiple, self.intersend = self.rule.control(
                self.s_ewma, self.r_ewma, self.rtt_ratio, self.slow_r_ewma,
                self.rule_list)
            # update the window_size
            self.window_size = self.rule.act(self.window_size,
                                             self.win_increment,
                                             self.win_multiple)

        # print self.window_size
        # update the rate that codec choose
        new_rate = self.get_rate_from_window()

        sender_rate = "time: " + str(curr_ts_ms()) + " send_rate: " + str(
            new_rate / 1000000.0) + " mbps\n"
        self.f.write(sender_rate)
        self.f.flush()

        # sys.stderr.write(sender_rate)
        # sys.stderr.flush()
        # print new_rate
        self.set_bitrate(new_rate)

    def run(self):
        TIMEOUT = 1000  # ms
        self.poller.modify(self.sock, ALL_FLAGS)
        curr_flags = ALL_FLAGS

        # print throughput
        thread_get_throughput = threading.Thread(target=self.get_throughput,
                                                 args=())
        thread_get_throughput.setDaemon(True)
        thread_get_throughput.start()

        while True:
            if self.window_is_open():
                if curr_flags != ALL_FLAGS:
                    self.poller.modify(self.sock, ALL_FLAGS)
                    curr_flags = ALL_FLAGS
            else:
                if curr_flags != READ_ERR_FLAGS:
                    self.poller.modify(self.sock, READ_ERR_FLAGS)
                    curr_flags = READ_ERR_FLAGS

            events = self.poller.poll(TIMEOUT)

            for fd, flag in events:
                assert self.sock.fileno() == fd

                if flag & ERR_FLAGS:
                    sys.exit('Error occurred to the channel')

                if flag & READ_FLAGS:
                    self.recv()

                if flag & WRITE_FLAGS:
                    self.read_frame_info()
                    # the buffer is not empty
                    if self.buffer and len(self.buffer) != 0:
                        if Sender.with_frame:
                            pacer_rate = self.get_pacer_rate()  # bps
                            if self.rate < pacer_rate:
                                # use timestamp
                                current_timestamps = time.time()
                                if current_timestamps > self.next_packet_timestamps + 1500 * 8.0 / pacer_rate:
                                    self.send()
                                    self.next_packet_timestamps = current_timestamps
                            else:
                                if self.window_is_open():
                                    self.send()
                        else:
                            # print "no frame"
                            if self.window_is_open():
                                self.send()

    def get_throughput(self):
        while True:
            sys.stderr.write("RemyCC sender: " +
                             str(self.sent * 1500 * 8.0 / 1000000) + " mbps\n")
            sys.stderr.flush()
            self.sent = 0
            time.sleep(1)  # second