/
VAware.py
81 lines (66 loc) · 2.77 KB
/
VAware.py
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
import numpy as np
class VAware:
"""
Implementation of Viewport-aware algorithm
"""
def __init__(self, video, params):
self.video = video
self.buffer = 0
self.D = video.D
self.M = len(video.values)
self.downloaded_segments = [0 for _ in range(self.video.N)]
self.last_finished_segments = -1
self.buffer_capacity = params['buffer_capacity']
def get_idle_time(self, buffer_array, downloaded_tiles, required_space, delta):
time_remaining = [buffer_array[i] * delta / downloaded_tiles[i] if downloaded_tiles[i] > 0 else 0 for i in
range(len(downloaded_tiles))]
freed_segment = 0
required_time = 0
for i in range(len(downloaded_tiles)):
if freed_segment >= required_space:
return required_time + 0.01
if time_remaining[i] > 0:
freed_segment += downloaded_tiles[i]
required_time += time_remaining[i]
return required_time + 0.01
def get_action(self, probs, bandwidth_capacity, segment, buffer_array, downloaded_tiles, wait_time, delta):
"""
:param probs: array size D, showing the probability of watching tiles
:return: array size D, showing the selected bitrates of each tile
"""
solution = []
for i in range(self.D):
target_size = bandwidth_capacity * probs[i] * self.video.delta
sizes = self.video.sizes.copy()
diff = np.abs(np.array(sizes) - target_size)
solution.append(int(diff.argmin()))
n = 0
for a in solution:
if a > 0:
n += 1
if n == 0:
solution[0] = 1
n = 1
if n > 0 and self.buffer_capacity - self.buffer >= n:
type = "new"
new_segments = n
action_segment = segment
return solution, type, action_segment, new_segments, 0
else:
type = "wait"
new_segments = 0
action_segment = -1
required_time = max(n - (self.buffer_capacity - self.buffer), 0)
if required_time > 0:
idle_time = self.get_idle_time(buffer_array, downloaded_tiles, required_time, delta)
return [0 for _ in range(self.D)], type, action_segment, new_segments, idle_time
else:
return [0 for _ in range(self.D)], type, action_segment, new_segments, wait_time
def set_buffer(self, buffer):
self.buffer = buffer
def take_action(self, solution, n, time):
number_of_downloaded_segments = 0
for v in solution:
if v > 0:
number_of_downloaded_segments += 1
self.downloaded_segments[n] = number_of_downloaded_segments