Script per l'analisi del bitrate

 

 

Per l’analisi del bitrate degli streaming in uscita si sono realizzati alcuni script in AWK adatti allo scopo.

Quello fondamentale è countEcalc.awk.

 

NOTA: Gli script devono essere contenuti nella stessa directory e per l'esecuzione delle righe di comando che li richiamano posizionarsi in essa.

 

Tale script elabora l’output dell’analizzatore di rete/packet sniffer Tcpdump a cui già si passano alcuni parametri per formattare l’output, per filtrare il traffico e analizzare i soli pacchetti udp su porta 1234 (quella utilizzata da VLC):

 

# tcpdump -i eth0 -nqtt \( udp and ip multicast and port 1234 and host <IP-LiveStreamer>\)

 

Lo script, a cui si passa lo standard output di tcpdump, accetta come parametro la finestra di analisi in millisecondi.

 

# tcpdump -i eth0 -nqtt \( udp and ip multicast and port 1234 and host <IP-LiveStreamer>\)\

|awk -f ./countEcalc.awk -v msec=1000

 

A partire dall’istante del primo pacchetto arrivato, lo script considera tutti quelli giunti ogni x millisecondi. Per il calcolo dell’occupazione di banda effettiva sulla rete, si è aggiunto alla dimensione dei pacchetti rilevata da tcpdump ( payload RTP) l’overhead dato dagli header del protocollo UDP (8 byte) e di quello IP (20 byte).

Come detto l’ampiezza delle finestre su cui vengono calcolati i bitrate medi può essere variata (msec=x).

Lo script, se richiamato in questo modo, ogni x ms aggiunge all’output di tcpdump, a video, una riga con indicato lo step di campionamento, il numero di arrivi, la corrispondente bitrate calcolata, quella media dall’inizio, la massima e la minima.

 

L’output è del tipo:

 

1078526435.908508 160.78.27.16.33213 > 224.0.1.2.1234: udp 1328 (DF), arrivo numero:263

1078526435.912738 160.78.27.16.33213 > 224.0.1.2.1234: udp 1328 (DF), arrivo numero:264

1078526435.917715 160.78.27.16.33213 > 224.0.1.2.1234: udp 1328 (DF), arrivo numero:265

1078526435.919502 160.78.27.16.33213 > 224.0.1.2.1234: udp 1328 (DF), arrivo numero:266

1078526435.923708 160.78.27.16.33213 > 224.0.1.2.1234: udp 1328 (DF), arrivo numero:267

step: 3 (corrisp_a_1078526435.923753) arrivati: 267  bitrate: 2896416 bit/sec  media: 3326720  brmin: 2896416  brmax: 3720864

 

Per stampare a video esclusivamente queste rige basta aggiungere alla precedente:

 

|grep step

 

Il cui risultato è del tipo:

 

step: 36 (corrisp_a_1078526144.817540) arrivati: 874  bitrate: 9481152 bit/sec  media: 5903722  brmin: 1312608  brmax: 9481152

step: 37 (corrisp_a_1078526145.817540) arrivati: 793  bitrate: 8602464 bit/sec  media: 5976661  brmin: 1312608  brmax: 9481152

step: 38 (corrisp_a_1078526146.817540) arrivati: 589  bitrate: 6389472 bit/sec  media: 5987525  brmin: 1312608  brmax: 9481152

step: 39 (corrisp_a_1078526147.817540) arrivati: 843  bitrate: 9144864 bit/sec  media: 6068482  brmin: 1312608  brmax: 9481152

step: 40 (corrisp_a_1078526148.817540) arrivati: 671  bitrate: 7279008 bit/sec  media: 6098745  brmin: 1312608  brmax: 9481152

 

La formattazione  risultante è adatta per un’analisi e interpretazione dei dati da parte dell’utente, in tempo reale, ma al fine di generare un output tabellare per una successiva rappresentazione grafica, si è creato un’ulteriore script da concatenare al precedente, totab.awk :

 

# tcpdump -i eth0 -nqtt \( udp and ip multicast and port 1234 and host streamserver.xyz.it\)\

|awk -f ./countEcalc.awk -v msec=1000| awk -f totab.awk

 

Permette di ottenere:

 

   Step   Istantanea     Media       Minima      Massima

         1    3710016    3710016    3710016    3710016

         2    3373728    3541872    3373728    3710016

         3    2896416    3326720    2896416    3710016

         4    2907264    3221856    2896416    3710016

         5    3699168    3317318    2896416    3710016

 

 

 

Di seguito è indicato il codice dei due script realizzati:

 

 

countEcalc.awk

 

#Script di awk per il calcolo della bitrate "istantanea" di uscita sulla rete.

#Conta i pacchetti arrivati in ogni "finestra" (impostabile a piacere) assumendo

 pacchetti

#udp a dimensione fissa (come accade sempre nelle nostre trasmissioni) leggendo

tale

#dimensione solo per il primo arrivato)

 

 

BEGIN   {

 

        res=msec/1000;

 

        increm=res;

 

        last=1;                         #last contiene l'istante (in step dell'ultimo arrivo).

 

        brmin=15000000

 

        }

 

NR == 1 {

 

        dim=$6+28;                        # 20 byte di IP Header + 8 di UDP header

 

        start=$1;

 

        print "Pckts dim: " dim,"Start a: "start, "Finestra: " msec,"millisecondi\n";

 

        }

 

 

{

if ($1<start+increm)    {

 

                        arrivi++;

 

                        printf("%s, arrivo numero:%d\n",$0,arrivi)

 

                        }

 

 

else    {

        n=int(($1-start)/res);

 

        bitrate=(dim*8*arrivi)/res;

 

                        if (bitrate<brmin)      {brmin=bitrate};    #per ilcalcolo della bitrate minima non verranno

                                                                                                    #contemplati gli intervalli in cui non viene

                        if (bitrate>brmax)      {brmax=bitrate};        #inviato nulla (bitrate 0)

 

        arrivitotali+=arrivi

 

        brmedia=(dim*8*arrivitotali)/(res*last)

 

        printf("step: %d (corrispondente_a_%f) arrivati: %3d  bitrate: %7d bit/sec  media: %7d  brmin: %7d  brmax: %7d\n"\

        ,last,start+(last*res),arrivi,bitrate,brmedia,brmin,brmax);

 

        while   (n-last>0)                              #per contemplare intervalli di zero

 

                {                                                  #superiori a "res" (la finestra)

                last++;

 

                printf("step: %d (corrispondente_a_%f) arrivati:   0   bitrate:     0 bit/sec  media: %7d bit/sec\n"\

                        ,last,start+(last*res),(dim*8*arrivitotali)/(res*last));

 

                };

 

                arrivi=1;

 

                last++

 

                increm=(last)*res;

 

                printf("%s, arrivo numero:%d\n",$0,arrivi)

 

        }

}

 

 

totab.awk

 

#Estrae dall'output dello script precedente step, bitrate "istantaneo" (sulla finestra

#precedentemente impostata),bitrate medio dall'inizio e minimo e massimo rilevati.

 

(NR==1) {print ("      Step   Istantanea   Media     Minima      Massima")}

 

($1=="step:") {printf("%10d %10d %10d %10d %10d\n",$2,$7,$10,$12,$14)}

 

 

 

Per la realizzazione dei grafici si è fatto uso del software Gnuplot (http://www.gnuplot.info/).

Si sono creati script come quello indicato di seguito, caricabili in gnuplot attraverso il comando “load”, in modo da poter avere settings preimpostati per ogni grafico:

 

# Gnuplot script file

set title "Andamento della bitrate dei canali su sample di 5 min e campioni a 1 sec"

set xlabel "secondi"

set ylabel "bit/sec"

set ylabel +1

set xrange [0:300]

set yrange [0:10000000]

set xtics 50

set ytics 1000000

set mxtics 5

set mytics

set grid xtics ytics

set key below Right noreverse samplen 4 spacing 1 width -4 title "" box

plot "./bbc_full5min_1sec.dat" using 1:2 title "BBC" with lines, \

"./euronews_full5min_1sec.dat"  using 1:2 title "Euronews" with lines, \

"./rai1_full5min_1sec.dat"  using 1:2 title "RAI1" with lines, \

"./rainews24_full5min_1sec.dat"  using 1:2 title "RAINews24" with lines, \

"./RAISPORT-NTR-5min.dat"  using 1:2 title "RAISPORT" with lines, \

"./italia1_full5min_1sec.dat"  using 1:2 title "Italia1" with lines, \

"./nettuno1_full5min_1sec.dat"  using 1:2 title "Nettuno1" with lines, \

"./nettuno2_full5min_1sec.dat"  using 1:2 title "Nettuno2" with lines