Network coding on p4 - Video streaming
===
date:2019-09-02
###### tags: `Network coding` `p4` `SDN`
:dart: Goal
---
- 在mininet+p4的switch環境進行Video streaming
## Topology(我自己的)

* 我將Video streaming 的 server用在h1,在h11、h22接收
## Program
### Video streaming with cv2
#### Client
```language=python
import cv2, io, socket, struct, time, pickle, zlib
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('10.0.1.1', 8485))
# cap = cv2.VideoCapture(0) # for live video
cap = cv2.VideoCapture("melt.mpg")
# cap.set(3, 320) # Height
# cap.set(4, 240) # Width
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
print(width, height)
img_counter = 0
encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), 90]
continious = False
while True:
ret, frame = cap.read()
if ret:
result, frame = cv2.imencode('.jpg', frame, encode_param)
data = pickle.dumps(frame, 0)
size = len(data)
print("{}: {}".format(img_counter, size))
client_socket.sendall(struct.pack(">L", size) + data)
img_counter += 1
else:
if continious:
cap = cv2.VideoCapture("melt.mpg")
# cap.set(3, 320) # Height
# cap.set(4, 240) # Width
else:
break
cap.release()
client_socket.close()
```
要確認Server的IP並更改
#### Server
```language=python
import os, sys, subprocess, zlib
import pickle, struct, socket
import numpy as np
import cv2
HOST = ''
PORT = 8485
BUFFER_SIZE = 65535
file_name = 'melt.avi'
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
print('Socket created')
s.bind((HOST,PORT))
print('Socket bind complete')
s.listen(10)
print('Socket now listening')
# writer = cv2.VideoWriter(file_name, cv2.VideoWriter_fourcc('M','J','P','G'), 30, (1280,720))
writer = cv2.VideoWriter(file_name, cv2.VideoWriter_fourcc('M','J','P','G'), 60, (320,200))
conn, addr = s.accept()
data = b"" # declare byte type data
# data = bytearray()
counter = 0
done = False
payload_size = struct.calcsize(">L")
print("payload_size: {}".format(payload_size))
while True:
while len(data) < payload_size:
data += conn.recv(BUFFER_SIZE)
if not data:
done = True
break
# print("Recv: {}".format(len(data)))
if done:
print("Received Done")
print("Opening", file_name)
process = subprocess.Popen([os.path.join("C:/", "Program Files", "VideoLAN", "VLC", "vlc.exe"),\
file_name])
break
# print("Done Recv: {}\n".format(len(data)))
packed_msg_size = data[:payload_size]
data = data[payload_size:]
msg_size = struct.unpack(">L", packed_msg_size)[0]
print("{} received msg_size: {}".format(counter, msg_size))
while len(data) < msg_size:
data += conn.recv(BUFFER_SIZE)
frame_data = data[:msg_size]
data = data[msg_size:]
counter += 1
frame = pickle.loads(frame_data, fix_imports=True, encoding="bytes")
frame = cv2.imdecode(frame, cv2.IMREAD_COLOR)
writer.write(frame)
cv2.imshow('Streaming',frame)
cv2.waitKey(1)
cv2.destroyAllWindows()
s.close()
```
## Result

* 在畫面中可以看到4個xterm順序與拓譜是一樣的,可以看到h11,h22正在接收資料
## Trouble
* 目前各自連結Server讀取影片沒有問題,但是如果h11、h22同時,會變得很慢。