svn checkout svn://svn.mplayerhq.hu/ffmpeg/trunk ffmpegIf you have trouble compiling ffmpeg, try my pre-compiled binaries.
xvid_encraw -i akiyo_cif.yuv -w 352 -h 288 -framerate 30 -max_key_interval 30 -o a01.m4v
ffmpeg -s cif -vcodec mpeg4 -r 30 -b 64000 -bt 3200 -g 30 -i akiyo_cif.yuv a02.m4v
x264 -I 30 -B 64 --fps 30 -o a03.264 akiyo_cif.yuv 352x288
lencod -d a04.cfg
ffmpeg -s cif -vcodec h263 -r 30 -b 48000 -bt 2400 -g 30 -i akiyo_cif.yuv -f h263 a05.263
MP4Box -hint -mtu 1024 -fps 30 -add a01.m4v a01.mp4
MP4Box -hint -mtu 1024 -fps 30 -add a02.m4v a02.mp4
MP4Box -hint -mtu 1024 -fps 30 -add a03.264 a03.mp4
MP4Box -hint -mtu 1024 -fps 30 -add a04.264 a04.mp4
MP4Box -hint -mtu 1024 -fps 30 -add a05.263 a05.mp4
MP4Box is part of GPAC (very good framework, btw). You should install the CVS version of GPAC:
cvs -z3 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/gpac co -P gpacIf you have trouble compiling MP4Box, try my pre-compiled binaries.
ffmpeg -i a01.mp4 a01_ref.yuv
ffmpeg -i a02.mp4 a02_ref.yuv
ffmpeg -i a03.mp4 a03_ref.yuv
ffmpeg -i a04.mp4 a04_ref.yuv
ffmpeg -i a05.mp4 a05_ref.yuv
The mp4trace tool from EvalVid is able to send a hinted mp4-file per RTP/UDP to a specified destination host.
mp4trace -f -s 192.168.0.2 12346 a01.mp4sends the H.264 track of a01.mp4 to the UDP port 12346 of host 192.168.0.2. You can watch the video with, e.g., QuickTime Player from Apple. For this purpose you need a SDP-file including the lines:
m=video 12346 RTP/AVP 96
a=rtpmap:96 H264/90000 (or H263-1998/90000 or whatever)
If you have MP4Box, you can extract the SDP-file with:
MP4Box -std -sdp a01.mp4 > a01.sdp
and replace port 0 by, e.g., 12346 in the "m=video" line of a01.sdp.
If you are only interested in off-line evaluation you should use something like
netcat -l -u -p 12346 > /dev/nullto avoid unnecessary ICMP traffic. Furthermore, the output of mp4trace will be needed later, so it should be redirected to a file:
mp4trace -f -s 192.168.0.2 12346 a01.mp4 > st_a01
In order to evaluate the transmission you have to trace the IP packets at the sender and at the receiver. For this purpose I recommend tcpdump/windump. The command line on the sender is:
tcpdump -n -tt -v udp port 12346 > sd_a01and on the receiver respectively:
tcpdump -n -tt -v udp port 12346 > rd_a01Alternatively it is possible to use the RTP sequence number instead of the IPv4 sequence number. This is mandatory in case of IPv6 traces, since there is no sequence number in IPv6 anymore. The command line in this case is:
tcpdump -n -tt -v -T rtp udp port 12346
If there are both a video and an audio track encapsulated in the mp4 file mp4trace will send both streams to the given host address. The audio track is delivered on the given port plus 2. The resulting trace file will include packets/frames from both streams. It can be split by
grep A st > sta
grep -v A st > stvThe corresponding dump files can be generated/recorded for instance as follows:
tcpdump -w all.cap
tcpdump -r all.cap -n -tt -v udp port 12346 > [s/r]dv
tcpdump -r all.cap -n -tt -v udp port 12348 > [s/r]daThe evaluation with etmp4 can be done separately for the audio and video tracks. There is no difference in the command line options. For the evaluation of the perceptual quality of the audio track I recommend PESQ and PEAQ respectively.
| akiyo_cif.yuv (and a01_ref.yuv) | raw source files (before and after encoding) |
| a01.mp4 | encoded, encapsulated and hinted video file |
| sd_a01 | sender dump (IP packet dump sender) |
| rd_a01 | receiver dump (IP packet dump receiver) |
| st_a01 | sender trace (information about frame types, packet segmentation, ...) |
eg sd_a01 rd_a01g st_a01 AWGN 250000This generates the rd_a01g file assuming an AWGN error model and a BER of 4E-6 (1/250000).
The first step in the evaluation process is the calculation of the reference PSNR. That's the PSNR of the coded and then decoded video without transmission errors/losses in relation to the uncoded raw video source.
psnr 352 288 420 akiyo_cif.yuv a01_ref.yuv > ref_psnr.txt
The next step is the reconstruction of the transmitted video as it is seen by the receiver. For this, the video and trace files are processed by etmp4 (Evaluate Traces of MP4-file transmission):
etmp4 -F -x sd_a01 rd_a01 st_a01 a01.mp4 a01eThis generates a (possibly corrupted) video file, where all frames that got lost or were corrupted are deleted from the original video track. Actually, two files are saved, a MP4-file containing the damaged video track (a01e.mp4), and a raw video file containing only the undamaged frames (a01e.264). These files are decoded to produce the YUV-file as seen at the receiver. If the appropriate decoder is not able to produce a YUV with as much frames as the original, you can try:
ffmpeg -i a01e.mp4 a01e.yuvThe resulting YUV file should contain exactly as much frames as the original YUV file. Unfortunately most codecs are not able to decode corrupted video files properly. E.g., ffmpeg often produces less frames or even crashes. There is nothing I can (or rather want to) do about this. However, in my tests the decoding mostly worked. Sometimes the last frame is not decoded, but this is not really a problem. The PSNR of the received video is calculated by:
psnr 352 288 420 akiyo_cif.yuv a01e.yuv > psnr_a01e.txt
Etmp4 also creates some more files:
| loss_a01e.txt | contains I, P, B and overall frame loss in %) |
| delay_a01e.txt | containes frame-nr., lost-flag, end-to-end delay, inter-frame gap sender, inter-frame gap receiver, and cumulative jitter in seconds |
| rate_s_a01e.txt | contains time, bytes per second (current time interval), and bytes per second (cumulative) measured at the sender |
| rate_r_a01e.txt | contains time, bytes per second (current time interval), and bytes per second (cumulative) measured at the receiver |
If you are interested in delay or jitter distributions, the hist tool could be of interest. E.g.,
awk '{print $3}' delay_a01.txt | hist - 0 .05 50
gives the time, PDF and CDF of the end-to-end delay of transmission a01.
mos /work ref_psnr.txt 25 > mos.txtcalculates the average MOS of every psnr file (last column of mos.txt) and the percentage of frames with a MOS worse than in the reference file in a sliding interval of 25 frames. These percentages are stored in miv_a01e.txt. Finally the MIV command calculates the maximum percentage of frames with a MOS worse than original:
miv /work > miv.txtFor further explanations of this metric have a look at this paper.