• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# Copyright (c) 2021 Huawei Device Co., Ltd.
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15import sys
16import struct
17import signal
18from threading import Thread
19from datetime import datetime
20from socketserver import ThreadingTCPServer, StreamRequestHandler
21
22TARGET_WIDTH = 128
23TARGET_HEIGHT = 64
24PIXEL_PER_BYTE = 8
25
26BIN_FRAME_SIZE = int(TARGET_WIDTH * TARGET_HEIGHT / PIXEL_PER_BYTE)
27
28DEFAULT_PORT = 5678
29
30REQUEST_SIZE = 4
31STATUS_SUCCESS = 0
32STATUS_FAILURE = 255
33
34class EncodeHandler(StreamRequestHandler):
35    bitmapList = []
36
37    def handle(self):
38        addr = self.request.getpeername()
39        print('Got connection from', addr)
40
41        while True:
42            startTime = datetime.now()
43            req = self.rfile.read(REQUEST_SIZE)
44            if not req:
45                break
46            # recv request from client
47            frameId = int.from_bytes(req, 'big') # bytes request
48
49            # prepare response
50            status, body = None, bytes()
51            if frameId < len(EncodeHandler.bitmapList):
52                status = STATUS_SUCCESS
53                body = EncodeHandler.bitmapList[frameId]
54            else:
55                status = STATUS_FAILURE
56                print('frameId out of range!')
57                break
58            # response header is: status(4B) + body length(4B)
59            head = struct.pack('>II', status, len(body))
60
61            # send response(header + body) to client
62            self.wfile.write(head + body)
63
64            currentTime = datetime.now()
65            timeCost = currentTime - startTime
66            print('frameId:', frameId, 'timeCost: %.3f' % timeCost.total_seconds())
67        print('handle request from', addr, 'done!')
68        self.wfile.close()
69
70def load_video_bin(binFile):
71    binFrames = []
72    print('loading', binFile, '...')
73    with open(binFile, 'rb') as f:
74        while True:
75            blob = f.read(BIN_FRAME_SIZE)
76            if len(blob) == 0:
77                break
78            binFrames.append(blob)
79    print('load', binFile, 'done!')
80    return binFrames
81
82def main():
83    if len(sys.argv) < 2:
84        print("Usage: {} binFile [port]\n\t".format(sys.argv[0]))
85        exit(-1)
86
87    binFile = sys.argv[1]
88    port = DEFAULT_PORT if len(sys.argv) < 3 else int(sys.argv[2])
89
90    print('binFile:', binFile, 'port:', port)
91    server = ThreadingTCPServer(('', port), EncodeHandler)
92
93    def sigint_handler(signum, frame):
94        print('sig {} raised: {}'.format(signum, frame))
95        server.socket.close()
96        server.shutdown()
97        sys.exit(0)
98    signal.signal(signal.SIGINT, sigint_handler) # main thread will handle signals
99
100    try:
101        EncodeHandler.bitmapList = load_video_bin(binFile)
102        waiterThread = Thread(target=server.serve_forever, args=())
103        waiterThread.start()
104        waiterThread.join()
105    except Exception as e:
106        print('exception raised:', e)
107    finally:
108        server.socket.close()
109        server.shutdown()
110
111if __name__ == "__main__":
112    main()
113