-
Notifications
You must be signed in to change notification settings - Fork 8
/
framefiller
executable file
·156 lines (125 loc) · 4.7 KB
/
framefiller
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#!/usr/bin/env python
#
# Copyright 2009 Claudio Pisa (claudio dot pisa at uniroma2 dot it)
#
# This file is part of SVEF (SVC Streaming Evaluation Framework).
#
# SVEF is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# SVEF is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with SVEF. If not, see <http://www.gnu.org/licenses/>.
#
# Simple error concealing script. Requires the dd utility.
import sys
import commands
import tempfile
from nalulib import *
if(len(sys.argv) < 6):
print """
Perform frame filling (a naive form of concealing) on a received YUV video.
Usage: %s <filtered received stream's trace> <bytes per frame>
<total frames> <distorted YUV> <concealed YUV (output)>
Where:
<filtered received stream's trace>: the trace file obtained from the
NAL unit dependency filtering process. For example:
$ nalufilter originaltrace.txt receivedtrace.txt > filteredtrace.txt
<bytes per frame>: length in bytes of each YUV frame, obtained from
width*height*1.5. i.e. 152064 for CIF, 608256 for 4CIF, 4866048 for HD.
<total frames>: total number of frames in the original video.
<distorted YUV>: the received YUV, reconstructed from the filtered
trace file using the JSVM tools. For example:
$ BitstreamExtractorStatic foreman.264 foreman-d.264 -et filtered.txt
$ H264AVCDecoderLibTestStatic foreman-d.264 foreman-d.yuv
<concealed YUV (output)>: the file containing the YUV resulting from
the frame filling process. For each missing frame, the previously
available frame is inserted.
Example: $ %s filteredtrace.txt 152064 1490 foreman-d.yuv foreman-c.yuv
""" % (os.path.basename(sys.argv[0]), os.path.basename(sys.argv[0]))
sys.exit(1)
filteredtracefilename = sys.argv[1]
bytesperframe = int(sys.argv[2])
totalframes = int(sys.argv[3])
distortedyuvfilename = sys.argv[4]
concealedyuvfilename = sys.argv[5]
# collect the frames that are present in the filtered trace file
frameset = set()
filteredfile = open(filteredtracefilename)
for line in filteredfile:
newnalu = NALU(line)
try:
if newnalu.frame_number >= 0:
frameset.add(newnalu.frame_number)
except KeyError:
pass
filteredfile.close()
if len(frameset) == totalframes:
print "%d frames in the filtered trace file. No concealing needed. Hardlinking the distorted YUV." % len(frameset)
command1 = "ln %s %s" % (distortedyuvfilename, concealedyuvfilename)
dothem([command1])
sys.exit(0)
framelist = list(frameset)
framelist.sort()
#print "%d frames in the filtered received trace: " % len(framelist), framelist
#numberofframes = 1 + max(framelist)
numberofframes = totalframes
def findsubstituteframe(currentframe):
# search backwards
i = currentframe - 1
while i >= 0:
if i in framelist:
return i
i-=1
# search forward
i = currentframe + 1
while i < numberofframes:
if i in framelist:
return i
i+=1
# not found
raise NALUException("frame not found: %s" % currentframe)
# create a sequence of frames from the distorted YUV, as will appear in the concealed YUV
missingframes = []
framesequence = []
addcounter = 0
for i in range(numberofframes):
if i in framelist:
framesequence.append(i)
else:
missingframes.append(i)
concframe = findsubstituteframe(i)
framesequence.append(concframe)
addcounter += 1
print "Sequence: ", framesequence
assert len(framesequence) == numberofframes
# make and get a temporary directory
tmpdir = tempfile.mkdtemp("","/tmp/wicloconc",".")
# mince the filtered video
mince(distortedyuvfilename, bytesperframe, tmpdir, framelist)
# create the concealed video
command1 = "touch %s" % concealedyuvfilename
command2 = "rm %s" % concealedyuvfilename
command3 = "touch %s" % concealedyuvfilename
dothem([command1, command2, command3])
for frame in framesequence:
framefilename = "%s/%d.yuv" % (tmpdir, frame)
command = "cat %s >> %s" % (framefilename, concealedyuvfilename)
dothem([command])
print "Missing Frames: %s " % missingframes
print """Statistics:
%d frames in original video
%d frames in distorted video
%d frames added
""" % (numberofframes, len(framelist), addcounter)
assert numberofframes == len(framelist) + addcounter
srconcealed = os.stat(concealedyuvfilename)
assert srconcealed.st_size == bytesperframe * numberofframes
command = "rm -rf %s/" % (tmpdir,)
dothem([command])