---
# System prepended metadata

title: Network coding on p4 - Video streaming
tags: [SDN, p4, Network coding]

---

Network coding on p4 - Video streaming
===
date:2019-09-02
###### tags: `Network coding` `p4` `SDN`

:dart: Goal
---
- 在mininet+p4的switch環境進行Video streaming
## Topology(我自己的)
![](https://i.imgur.com/iDHlBcf.png)
* 我將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
![](https://i.imgur.com/v0GVkxf.png)
* 在畫面中可以看到4個xterm順序與拓譜是一樣的，可以看到h11,h22正在接收資料

## Trouble
* 目前各自連結Server讀取影片沒有問題，但是如果h11、h22同時，會變得很慢。

