• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2import sys
3import struct
4import signal
5from threading import Thread
6from datetime import datetime
7from socketserver import ThreadingTCPServer, StreamRequestHandler
8
9TARGET_WIDTH = 128
10TARGET_HEIGHT = 64
11PIXEL_PER_BYTE = 8
12
13BIN_FRAME_SIZE = int(TARGET_WIDTH * TARGET_HEIGHT / PIXEL_PER_BYTE)
14
15DEFAULT_PORT = 5678
16
17REQUEST_SIZE = 4
18STATUS_SUCCESS = 0
19STATUS_FAILURE = 255
20
21class EncodeHandler(StreamRequestHandler):
22    bitmapList = []
23
24    def handle(self):
25        addr = self.request.getpeername()
26        print('Got connection from', addr)
27
28        while True:
29            startTime = datetime.now()
30            req = self.rfile.read(REQUEST_SIZE)
31            if not req:
32                break
33            # recv request from client
34            frameId = int.from_bytes(req, 'big') # bytes request
35
36            # prepare response
37            status, body = None, bytes()
38            if frameId < len(EncodeHandler.bitmapList):
39                status = STATUS_SUCCESS
40                body = EncodeHandler.bitmapList[frameId]
41            else:
42                status = STATUS_FAILURE
43                print('frameId out of range!')
44                break
45            # response header is: status(4B) + body length(4B)
46            head = struct.pack('>II', status, len(body))
47
48            # send response(header + body) to client
49            self.wfile.write(head + body)
50
51            currentTime = datetime.now()
52            timeCost = currentTime - startTime
53            print('frameId:', frameId, 'timeCost: %.3f' % timeCost.total_seconds())
54        print('handle request from', addr, 'done!')
55        self.wfile.close()
56
57def load_video_bin(binFile):
58    binFrames = []
59    print('loading', binFile, '...')
60    with open(binFile, 'rb') as f:
61        while True:
62            blob = f.read(BIN_FRAME_SIZE)
63            if len(blob) == 0:
64                break
65            binFrames.append(blob)
66    print('load', binFile, 'done!')
67    return binFrames
68
69def main():
70    if len(sys.argv) < 2:
71        print("Usage: {} binFile [port]\n\t".format(sys.argv[0]))
72        exit(-1)
73
74    binFile = sys.argv[1]
75    port = DEFAULT_PORT if len(sys.argv) < 3 else int(sys.argv[2])
76
77    print('binFile:', binFile, 'port:', port)
78    server = ThreadingTCPServer(('', port), EncodeHandler)
79
80    def sigint_handler(signum, frame):
81        print('sig {} raised: {}'.format(signum, frame))
82        server.socket.close()
83        server.shutdown()
84        sys.exit(0)
85    signal.signal(signal.SIGINT, sigint_handler) # main thread will handle signals
86
87    try:
88        EncodeHandler.bitmapList = load_video_bin(binFile)
89        waiterThread = Thread(target=server.serve_forever, args=())
90        waiterThread.start()
91        waiterThread.join()
92    except Exception as e:
93        print('exception raised:', e)
94    finally:
95        server.socket.close()
96        server.shutdown()
97
98if __name__ == "__main__":
99    main()
100