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