#!/usr/bin/python3
"""
Author: <NAME>

Description: Provides a mechanism for measuring Stabilizer stream data throughput.
"""
import argparse
import logging
import sys
import time

from stabilizer.stream import StabilizerStream

class Timer:
    """ A basic timer for measuring elapsed time periods. """

    def __init__(self, period=1.0):
        """ Create the timer with the provided period. """
        self.start_time = time.time()
        self.trigger_time = self.start_time + period
        self.period = period
        self.started = False


    def is_triggered(self):
        """ Check if the timer period has elapsed. """
        now = time.time()
        return now >= self.trigger_time


    def start(self):
        """ Start the timer. """
        self.start_time = time.time()
        self.started = True


    def is_started(self):
        """ Check if the timer has started. """
        return self.started


    def arm(self):
        """ Arm the timer trigger. """
        self.trigger_time = time.time() + self.period


    def elapsed(self):
        """ Get the elapsed time since the timer was started. """
        now = time.time()
        return now - self.start_time


def sequence_delta(previous_sequence, next_sequence):
    """ Check the number of items between two sequence numbers. """
    if previous_sequence is None:
        return 0

    delta = next_sequence - (previous_sequence + 1)
    return delta & 0xFFFFFFFF


def main():
    """ Main program. """
    parser = argparse.ArgumentParser(description='Measure Stabilizer livestream quality')
    parser.add_argument('--port', type=int, default=2000,
                        help='The port that stabilizer is streaming to')

    args = parser.parse_args()

    logging.basicConfig(level=logging.INFO,
                        format='%(asctime)s.%(msecs)03d %(levelname)-8s %(message)s')

    last_index = None

    drop_count = 0
    good_blocks = 0
    total_bytes = 0

    timer = Timer()

    stream = StabilizerStream(args.port)

    while True:
        # Receive any data over UDP and parse it.
        for (seqnum, _) in stream.read_frame():
            if not timer.is_started():
                timer.start()

            # Handle any dropped packets.
            drop_count += sequence_delta(last_index, seqnum)
            last_index = seqnum
            good_blocks += 1

        # Report the throughput periodically.
        if timer.is_triggered():
            drate = stream.get_rx_bytes() * 8 / 1e6 / timer.elapsed()

            print(f'''
Data Rate:       {drate:.3f} Mbps
Received Blocks: {good_blocks}
Dropped blocks:  {drop_count}

Metadata: {total_bytes / 1e6:.3f} MB in {timer.elapsed():.2f} s
----
''')
            sys.stdout.flush()
            timer.arm()


if __name__ == '__main__':
    main()

#!/usr/bin/python3
"""
Author: <NAME>

Description: Provides a mechanism for measuring Stabilizer stream data throughput.
"""
import argparse
import logging
import sys
import time

from stabilizer.stream import StabilizerStream

class Timer:
    """ A basic timer for measuring elapsed time periods. """

    def __init__(self, period=1.0):
        """ Create the timer with the provided period. """
        self.start_time = time.time()
        self.trigger_time = self.start_time + period
        self.period = period
        self.started = False


    def is_triggered(self):
        """ Check if the timer period has elapsed. """
        now = time.time()
        return now >= self.trigger_time


    def start(self):
        """ Start the timer. """
        self.start_time = time.time()
        self.started = True


    def is_started(self):
        """ Check if the timer has started. """
        return self.started


    def arm(self):
        """ Arm the timer trigger. """
        self.trigger_time = time.time() + self.period


    def elapsed(self):
        """ Get the elapsed time since the timer was started. """
        now = time.time()
        return now - self.start_time


def sequence_delta(previous_sequence, next_sequence):
    """ Check the number of items between two sequence numbers. """
    if previous_sequence is None:
        return 0

    delta = next_sequence - (previous_sequence + 1)
    return delta & 0xFFFFFFFF


def main():
    """ Main program. """
    parser = argparse.ArgumentParser(description='Measure Stabilizer livestream quality')
    parser.add_argument('--port', type=int, default=2000,
                        help='The port that stabilizer is streaming to')

    args = parser.parse_args()

    logging.basicConfig(level=logging.INFO,
                        format='%(asctime)s.%(msecs)03d %(levelname)-8s %(message)s')

    last_index = None

    drop_count = 0
    good_blocks = 0
    total_bytes = 0

    timer = Timer()

    stream = StabilizerStream(args.port)

    while True:
        # Receive any data over UDP and parse it.
        for (seqnum, _) in stream.read_frame():
            if not timer.is_started():
                timer.start()

            # Handle any dropped packets.
            drop_count += sequence_delta(last_index, seqnum)
            last_index = seqnum
            good_blocks += 1

        # Report the throughput periodically.
        if timer.is_triggered():
            drate = stream.get_rx_bytes() * 8 / 1e6 / timer.elapsed()

            print(f'''
Data Rate:       {drate:.3f} Mbps
Received Blocks: {good_blocks}
Dropped blocks:  {drop_count}

Metadata: {total_bytes / 1e6:.3f} MB in {timer.elapsed():.2f} s
----
''')
            sys.stdout.flush()
            timer.arm()


if __name__ == '__main__':
    main()

#!/usr/bin/python3 Author: <NAME>  Description: Provides a mechanism for measuring Stabilizer stream data throughput. A basic timer for measuring elapsed time periods. Create the timer with the provided period. Check if the timer period has elapsed. Start the timer. Check if the timer has started. Arm the timer trigger. Get the elapsed time since the timer was started. Check the number of items between two sequence numbers. Main program. # Receive any data over UDP and parse it. # Handle any dropped packets. # Report the throughput periodically. Data Rate:       {drate:.3f} Mbps Received Blocks: {good_blocks} Dropped blocks:  {drop_count}  Metadata: {total_bytes / 1e6:.3f} MB in {timer.elapsed():.2f} s ----