4.视频仿真的实现
4.1 视频仿真的基本思路
(1) 根据实际网络的的要求,定义网络节点,配置网络拓朴结构,确定链路的基本特性,如延迟、带宽和选择策略等。
(2) 建立协议代理,包括端设备的协议绑定和通信业务量模型的建立,将视频流和各种背景流绑定到代理中。配置业务量模型的参数,确定网络上的业务量分布。
(3) 设置trace 对象。trace 对象把仿真过程中发生的特定类型事件记录在trace 文件中。NS-2通过trace 文件保存整个仿真过程。仿真完成后,可以对trace 文件(1) 根据实际网络的的要求,定义网络节点,配置网络拓朴结构,确定链路的基本特性,如延迟、带宽和选择策略等。
(4) 将trace文件,注入到NS-2模拟网络中进行传输,然后模拟网络根据trace文件中的参数生成模型,随后得到相应的trace结果。
(5)根据trace文件判断编码产生的压缩视频分组流中哪些分组在传输过程中丢失,哪些分组因为延时超过了一定的限制而不能用来解码。然后从压缩 视频文件中将传输丢失的分组和延时超过限制的分组丢弃,从而产生新的视频压缩文件。解码器对该文件进行解码从而得到经过仿真网络环境传输以后的重建视频, 并可以进行质量的评估。
4.2 视频仿真的具体步骤
由于在视频传输的的仿真中,需要将真实的视频码流在网络中传输,因此必须对NS-2 进行扩展与修改, 添加视频传输仿真过程中所需的网络元素,包括代理的设计。如果研究者需要验证其提出的传输策略,就要使用C+ + 和OTcl对网络元素编程,将其提出的策略加到网络元素中去,然后重新编译NS。在完成了对NS-2的扩展以后,就可以利用NS进行仿真了。
4.2.1 NS-2环境配置
(1)首先下载用作实验的标准YUV视频序列,本课题使用mother_daughtercif.yuv文件。
(2)在路径(C:/cygwin/home/zzz/ns-allinone-2.27/ns-2.27/common)中修改packet.h文件。
struct hdr_cmn {
enum dir_t { DOWN= -1, NONE= 0, UP= 1 };
packet_t ptype_; // 数据包类型
int size_; // 数据包的大小
int uid_; // 标号
int error_; // 错误标记
int errbitcnt_;
int fecsize_;
double ts_; // timestamp: for q-delay measurement
int iface_; // receiving interface (label)
dir_t direction_; // direction: 0=none, 1=up, -1=down
char src_rt_valid;
double ts_arr_; // Required by Marker of JOBS
//添加以下代码
int frametype_; // frame type
double sendtime_; // send time
unsigned long int frame_pkt_id_;
(3)在路径(C:/cygwin/home/zzz/ns-allinone-2.27/ns-2.27/common)中修改agent.h文件。
class Agent : public Connector {
public:
Agent(packet_t pktType);
virtual ~Agent();
void recv(Packet*, Handler*);
......
inline packet_t get_pkttype() { return type_; }
// 添加以下代码
inline void set_frametype(int type) { frametype_ = type; }
inline void set_prio(int prio) { prio_ = prio; }
protected:
int command(int argc, const char*const* argv);
......
int defttl_; // default ttl for outgoing pkts
//添加以下代码
int frametype_;
......
private:
void flushAVar(TracedVar *v);
};
(4) 在路径(C:/cygwin/home/zzz/ns-allinone-2.27/ns-2.27/common)中修改agent.cc文件。
Agent::Agent(packet_t pkttype) :
size_(0), type_(pkttype), frametype_(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 */
//添加以下代码
ch->frametype_= frametype_;
......
(5)将myudp.cc,myudp.h,myudpsink3.cc,myudpsink3.h,mytraffictrace3.cc文件放入myh264文件中。
(6)在该路径(C:/cygwin/home/zzz/ns-allinone-2.27/ns-2.27/tcl/lib)中对文件(ns-default.tcl)进行修改,在文件的末尾添加如下代码,
Agent/myUDP set packetSize_ 1000
Tracefile set debug_ 0
(7)在文件(C:/cygwin/home/zzz/ns-allinone-2.27/ns-2.27/Makefile)末尾添加代码,如下所示。
OBJ_CC = /
tools/random.o tools/rng.o tools/ranvar.o common/misc.o common/timer-handler.o /
common/scheduler.o common/object.o common/packet.o /
common/ip.o routing/route.o common/connector.o common/ttl.o /
trace/trace.o trace/trace-ip.o /
classifier/classifier.o classifier/classifier-addr.o /
classifier/classifier-hash.o /
classifier/classifier-virtual.o /
classifier/classifier-mcast.o /
classifier/classifier-bst.o /
classifier/classifier-mpath.o mcast/replicator.o /
classifier/classifier-mac.o /
classifier/classifier-qs.o /
adc/pointsample-est.o adc/salink.o adc/actp-adc.o /
adc/hb-adc.o adc/expavg-est.o/
adc/param-adc.o adc/null-estimator.o /
adc/adaptive-receiver.o apps/vatrcvr.o adc/consrcvr.o /
......
xcp/xcpq.o xcp/xcp.o xcp/xcp-end-sys.o /
wpan/p802_15_4csmaca.o wpan/p802_15_4fail.o /
wpan/p802_15_4hlist.o wpan/p802_15_4mac.o /
wpan/p802_15_4nam.o wpan/p802_15_4phy.o /
wpan/p802_15_4sscs.o wpan/p802_15_4timer.o /
wpan/p802_15_4trace.o wpan/p802_15_4transac.o /
myh264/myudp.o / //添加下面三行代码
myh264/myudpsink3.o /
myh264/mytraffictrace3.o /
$(OBJ_STL)
(8)编辑,在NS中执行make clean;make 命令,完成配置操作。
4.2.2拓扑结构的设置
在研究具体网络的性能时,一个实际的网络拓扑结构是首先要搭建的。这里我们利用Otcl 语言在NS 中实现了一个具有6个节点拓扑结构(如图5.1所示)。通过节点S1适时传输到节点S2,中间通过节点R1和R2;节点S1带有一个CBR流发生器,也通 过中间节点R1和R2,向节点D2发送,作为影响视频传输的背景流。链路的带宽如图中标注所示。本实例仿真主要想说明CBR的背景流对视频传输质量的影 响,从而论证本分析方案的可行性。
图4.1(拓扑结构)
使用250帧的图像测试序列Mother_daughter_cif.yuv,利用JVT给出的参考模型JM1.7 H.264编码器进行编码与RTP打包,产生mother_daughter_cif.264压缩视频文件,编写程序读取压缩视频文件,产生名为 Mother_daughter_cif.trc的trace文件。按照图2配置网络拓朴结构,确定链路的基本特性,R1和R2之间建立带宽为 0.3Mbps双向链路,在节点S1和D1间建立一条UDP连接,并在其上建立一条视频UDP数据流,传输的起始时间为0s,终止时间为250帧图像以帧 率15帧/秒传输所需时间。S2和D2间建立一条UDP连接,并在其上建立一条CBR数据流。将视频trace文件注入NS-2程序中,部分代码如下:
# 创建simulator 对象
set ns [new Simulator]
#为数据流定义不同的颜色,供NAM用
#$ns color 1 Blue
#$ns color 2 Red
#$ns color green
set nd [open out.tr w]
$ns trace-all $nd
#打开一个 trace file 记录数据包的传送过程
set nf [open out.nam w]
$ns namtrace-all $nf
set packetSize 1500
# 创建结点
set s1 [$ns node]
set s2 [$ns node]
set r1 [$ns node]
set r2 [$ns node]
set d1 [$ns node]
set d2 [$ns node]
# 创建节点之间的链接和拓扑结构以及设置链路带宽、延迟
$ns duplex-link $s1 $r1 1Mb 1ms DropTail
$ns duplex-link $s2 $r1 1Mb 1ms DropTail
$ns simplex-link $r1 $r2 0.3Mb 1ms DropTail
$ns simplex-link $r2 $r2 0.3Mb 1ms DropTail
$ns duplex-link $r2 $d1 1Mb 1ms DropTail
$ns duplex-link $r2 $d2 1Mb 1ms DropTail
$ns duplex-link-op $s1 $r1 orient right-down
$ns duplex-link-op $s2 $r1 orient right-up
$ns simplex-link-op $r1 $r2 orient right
$ns duplex-link-op $r2 $d1 orient right-up
$ns duplex-link-op $r2 $d2 orient right-down
set qr1r2 [[$ns link $r1 $r2] queue]
$qr1r2 set limit_ 10
#Create a UDP agent and attach it to node s2
set udp0 [new Agent/UDP]
… … …
4.2.3 仿真过程
本课题的具体实现分为以下六个步骤,本人主要完成第三步和第四步,其余部分由同组的其他同学完成,所以这些部分在这里只作简单介绍。
(1)将下载的mother_daughter.yuv文件作lencode.exe操作,得到mother_daughter.cif.264压缩文件。
(2) 对mother_daughter_cif.264文件作分析操作(parser.exe),得到mother_daughter_cif.txt文件。
mother_daughter_cif.txt部分内容如下:
0 0.000000 921 1
1 0.000000 1000 1
2 0.000000 996 1
3 0.000000 998 1
4 0.000000 1008 1
5 0.000000 989 1
6 0.000000 997 1
7 0.000000 355 1
8 0.066667 407 2
9 0.133333 97 3
10 0.200000 104 3
… … …
(3)对be.tcl文件作NS操作(ns.exe),运行之后得到sd_be(发送方的trace文件)和rd_be(接收方的trace文 件)文件,这两个文件用来验证信息在执行发送操作后的数据包丢失情况,经过对比9,10,11,12等数据块丢失,运行效果如图5.2.。
图4.2(仿真结果)
sd_be文件部分内容如下:
0.000000 id 0 udp 921
0.000000 id 1 udp 1000
0.000000 id 2 udp 996
0.000000 id 3 udp 998
0.000000 id 4 udp 1008
0.000000 id 5 udp 989
0.000000 id 6 udp 997
0.000000 id 7 udp 355
0.066667 id 8 udp 407
0.133333 id 9 udp 97
0.200000 id 10 udp 104
0.266667 id 11 udp 274
0.333333 id 12 udp 120
0.400000 id 13 udp 102
0.466667 id 14 udp 306
0.533333 id 15 udp 115
0.600000 id 16 udp 80
0.666667 id 17 udp 991
0.666667 id 18 udp 996
0.666667 id 19 udp 990
0.666667 id 20 udp 1006
0.666667 id 21 udp 988
0.666667 id 22 udp 998
0.666667 id 23 udp 361
0.733333 id 24 udp 72
0.800000 id 25 udp 74
0.866667 id 26 udp 334
0.933333 id 27 udp 84
… … …
rd_be 文件部分内容如下:
0.053232 id 0 udp 921
0.081277 id 1 udp 1000
0.121885 id 2 udp 996
0.149261 id 3 udp 998
0.190301 id 4 udp 1008
0.217269 id 5 udp 989
0.258000 id 6 udp 997
0.263077 id 7 udp 355
0.275093 id 8 udp 407
0.388749 id 11 udp 274
0.510840 id 13 udp 102
0.588045 id 14 udp 306
0.643664 id 15 udp 115
0.699597 id 16 udp 80
0.800725 id 17 udp 991
0.841405 id 18 udp 996
0.882392 id 20 udp 1006
0.909688 id 22 udp 998
1.118419 id 28 udp 76
(4)对mother_daughter_cif.264,distorted.264,sd_be,rd_be四个文件执行 errinsert.exe操作,运行之后将结果命名为distorted.264,该操作主要根据sd_be和rd_be文件对比之后,将丢失的数据信 息从原文件(mother_daughter_cif.264)中去掉。
(5)对 distorted.264 文件作解码操作(ldecod.exe),执行程序后将会得到
mother_daughter_cif_distorted.yuv文件,然后用YUV视频播放软件(YuvViewer)对 mother_daughter.yuv(仿真前的视频文件)与mother_daughter_cif_distorted.yuv(仿真前的视频文 件)分别进行播放,会发现仿真后的视频文件会出现图像失真的现象,如图5.3。
仿真后的视频截图
仿真前的视频截图
图4.3
(6)最后对mother_daughter_cif.yuv和mother_daughter_cif_distorted.yuv作PSNR(信号-噪音功率比)操作(psnr.exe),对两个视频进行参数对比,如图5.4。
图4.4 两种情况下PSNR的对比