Multimedia Communication


      In this experiment, you will learn how to use the real video traffic traces [1] to do the simulation in NS2.



        Standard MPEG encoders generate three distinct types of frames, namely I, P, and B frames. The I frame is encoded in Intra mode, and is essential for the prediction coding of other frames. If part of an I frame is lost, then all frames in the group of pictures (GoP) including this particular frame are impaired. The P frame is encoded in prediction mode, while the B frame is encoded in double prediction mode. As with the I frame, the P frame is also important. If part of a P frame is lost, the impairment propagates the particular P frame, previous B frames, and the following frames in the GoP that includes this P frame. Conversely, if part of a B frame is lost, the impairment propagates solely within that frame.


[Evaluation Metrics]     

In this experiment, we adopt two evaluation metrics, namely the fraction of decodable frames and the useless data received [2]. The fraction of ecodable frames reports the number of decodable frames over the total number of transmitted frames. A frame is considered to be decodable if at least a fraction dt (decodable threshold) of the data in each frame is received. However, a frame is only considered decodable if and only if all of the frames upon which it depends are also decodable. Therefore, when dt=0.75, 25% of the data from a frame can be lost without causing that frame to be considered as undecodable. The useless data received evaluation metric reports the fraction of the data received which is useless to the decoder. The decoder may have useless data from partial received frames or from frames that can not be decoded because they depend on other undecodable frames.



1.      modify common/packet.h

struct hdr_cmn {

  enum dir_t { DOWN= -1, NONE= 0, UP= 1 };

  packet_t ptype_;      // packet type (see above)

  int    size_;               // simulated packet size

  int    uid_;                // unique id

  int    error_;              // error flag

  int     errbitcnt_;     // # of corrupted bits jahn

  int     fecsize_;

  double     ts_;           // timestamp: for q-delay measurement

  int    iface_;              // receiving interface (label)

  dir_t direction_;       // direction: 0=none, 1=up, -1=down

  // source routing

 char src_rt_valid;

  double ts_arr_; // Required by Marker of JOBS

 // add the following two lines

  int frametype_;            // frame type for MPEG video transmission

  int frameseq_;              // frame sequence for MPEG video transmission



2.      modify common/agent.h

class Agent : public Connector {


  Agent(packet_t pktType);

  virtual ~Agent();

  void recv(Packet*, Handler*);



inline packet_t get_pkttype() { return type_; }

// add the following three lines

  inline void set_frametype(int type) { frametype_ = type; }

  inline void set_frameseq(int seq) { frameseq_ = seq; }

  inline void set_prio(int prio) { prio_ = prio; }



  int command(int argc, const char*const* argv);



  int defttl_;                        // default ttl for outgoing pkts


 // add the following two lines

  int frametype_;                // frame type for MPEG video transmission

  int frameseq_;                  // frame sequence for MPEG video transmission




  void flushAVar(TracedVar *v);



3.      modify common/

Agent::Agent(packet_t pkttype) :

  size_(0), type_(pkttype), frametype_(0), frameseq_(0),

  channel_(0), traceName_(NULL),

  oldValueList_(NULL), app_(0), et_(0)





Agent::initpkt(Packet* p) const


  hdr_cmn* ch = hdr_cmn::access(p);

  ch->uid() = uidcnt_++;

  ch->ptype() = type_;

  ch->size() = size_;

  ch->timestamp() = Scheduler::instance().clock();

  ch->iface() = UNKN_IFACE.value(); // from packet.h (agent is local)

  ch->direction() = hdr_cmn::NONE;


  ch->error() = 0;        /* pkt not corrupt to start with */

 // add the following two lines

  ch->frametype_= frametype_;

  ch->frameseq_= frameseq_;



4.      Add a folder named mympeg under ns-2.27.


5.      Copy the files mytraffictrace.ccmyudpsink.ccmyudpsink.h, into mympeg folder


6.      Modify tcl/lib/ns-default.tcl

//add the following line at the bottom of the file.

Tracefile set debug_ 0


7.      Put mympeg/mytraffictrace.o and mympeg/myudpsink.o in the OBJ_CC list


8.      Recomplie NS2

cd ns-allinone-2.27/ns-2.27

make clean; make


9.      Download the the traffic traces from [1]. In the following, we use Verbose_StarWarsIV.dat as an example.


10.   TCL Code(mympeg.tcl)


set ns [new Simulator]

set packetSize  200


set s1 [$ns node]

set d1 [$ns node]

set r1 [$ns node]

set r2 [$ns node]


$ns simplex-link $s1 $r1 10Mb 1ms DropTail

$ns simplex-link $r1 $s1 10Mb 1ms DropTail

$ns simplex-link $r1 $r2 1.024Mb 1ms dsRED/core

$ns simplex-link $r2 $r1 1.024Mb 1ms DropTail

$ns simplex-link $r2 $d1 10Mb 1ms DropTail

$ns simplex-link $d1 $r2 10Mb 1ms DropTail


set q1 [[$ns link $r1 $r2] queue]

$q1 meanPktSize $packetSize

$q1 set numQueues_ 1

$q1 setNumPrec 3

$q1 set limit_ 10

$q1 addPHBEntry 10 0 0

$q1 addPHBEntry 11 0 1

$q1 addPHBEntry 12 0 2

$q1 configQ 0 0 6 8 0.025

$q1 configQ 0 1 4 6 0.05

$q1 configQ 0 2 2 4 0.10


set udp1 [new Agent/UDP]

$ns attach-agent $s1 $udp1

$udp1 set packetSize_ $packetSize

set null1 [new Agent/MyUdpSink]

$ns attach-agent $d1 $null1

$ns connect $udp1 $null1


$null1 set_filename output_result_flow1.dat

set original_file_name Verbose_StarWarsIV.dat

set trace_file_name video1.dat

set original_file_id [open $original_file_name r]

set trace_file_id [open $trace_file_name w]


set frame_count 0


while {[eof $original_file_id] == 0} {


    gets $original_file_id current_line

    scan $current_line "%d%s%d%d" seq_ frametype_ nexttime_ length_


    # 25Frames/sec ( 1000/25 = 40ms = 40000 us)

    set time [expr 1000*40]


    if { $frametype_ == "I" } {

      set type_v 1



    if { $frametype_ == "P" } {

      set type_v 2



    if { $frametype_ == "B" } {

      set type_v 3



    puts $trace_file_id "$time $length_ $type_v $seq_"

    incr frame_count



close $original_file_id

close $trace_file_id

set end_sim_time [expr 1.0 * 40 * ($frame_count)  / 1000]

puts "$end_sim_time"


set trace_file [new Tracefile]

$trace_file filename $trace_file_name

set video1 [new Application/Traffic/myTrace]

$video1 attach-agent $udp1

$video1 attach-tracefile $trace_file


proc finish {} {

    global ns

    exit 0



$ns at 0.0 "$video1 start"

$ns at $end_sim_time "$video1 stop"

$ns at $end_sim_time "$null1 closefile"

$ns at [expr $end_sim_time + 1.0] "finish"


$ns run


[Simulation Steps and Results]

1. $ns mympeg.tcl

After simulation, you will get a file named output_result_flow1.dat.


2. Compile the evaluation tool. (GOP12.c)

$gcc -o  gop12.exe  GOP12.c


3. Perform evaluation.

$./gop12.exe Verbose_StarWarsIV.dat output_result_flow1.dat      1.0   200


4. Results.

Begin processing


total_frame:89998 decodable_frame:13067 Q:0.145192

p_correct:607614 p_useful:53720 U:0.911589

total directly decodable frame: I->1162, P->20051, B->59008

total decodable frame: I->1162, P->3323, B->8582

total frame: I->7500, P->22500, B->59998

end of processing


From the above simulation results, we know that the number of the total transmitted frame is 89998, the number of the decodable frame is 13067, and therefore the fraction of decodable frames is 0.145912. Also, the useless data received is 0.911589.


p.s. In the tcl code, the packetSize is set to 200. It means that each video frame must be fragmented into small packet size. Each packet has the maximum size of 200 bytes.




[2]    A. Ziviani, B. E. Wolfinger, J. F. Rezende, O. C. M. B. Duarte, and S. Fdida, Joint Adoption of QoS Schemes for MPEG Streams,Kluwer Academic Publishers, ISSN: 1380-7501, vol. 26, no. 1, pp. 59-80, May 2005


[Contact Information]

If you have any question about this experiment, please write me an email. (Chih-Heng, Ke [])