10a7ce71fSopenharmony_ci#!/usr/bin/env python3 20a7ce71fSopenharmony_ci# Copyright (c) 2021 Huawei Device Co., Ltd. 30a7ce71fSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License"); 40a7ce71fSopenharmony_ci# you may not use this file except in compliance with the License. 50a7ce71fSopenharmony_ci# You may obtain a copy of the License at 60a7ce71fSopenharmony_ci# 70a7ce71fSopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0 80a7ce71fSopenharmony_ci# 90a7ce71fSopenharmony_ci# Unless required by applicable law or agreed to in writing, software 100a7ce71fSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS, 110a7ce71fSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 120a7ce71fSopenharmony_ci# See the License for the specific language governing permissions and 130a7ce71fSopenharmony_ci# limitations under the License. 140a7ce71fSopenharmony_ci 150a7ce71fSopenharmony_ciimport sys 160a7ce71fSopenharmony_ciimport struct 170a7ce71fSopenharmony_ciimport signal 180a7ce71fSopenharmony_cifrom threading import Thread 190a7ce71fSopenharmony_cifrom datetime import datetime 200a7ce71fSopenharmony_cifrom socketserver import ThreadingTCPServer, StreamRequestHandler 210a7ce71fSopenharmony_ci 220a7ce71fSopenharmony_ciTARGET_WIDTH = 128 230a7ce71fSopenharmony_ciTARGET_HEIGHT = 64 240a7ce71fSopenharmony_ciPIXEL_PER_BYTE = 8 250a7ce71fSopenharmony_ci 260a7ce71fSopenharmony_ciBIN_FRAME_SIZE = int(TARGET_WIDTH * TARGET_HEIGHT / PIXEL_PER_BYTE) 270a7ce71fSopenharmony_ci 280a7ce71fSopenharmony_ciDEFAULT_PORT = 5678 290a7ce71fSopenharmony_ci 300a7ce71fSopenharmony_ciREQUEST_SIZE = 4 310a7ce71fSopenharmony_ciSTATUS_SUCCESS = 0 320a7ce71fSopenharmony_ciSTATUS_FAILURE = 255 330a7ce71fSopenharmony_ci 340a7ce71fSopenharmony_ciclass EncodeHandler(StreamRequestHandler): 350a7ce71fSopenharmony_ci bitmapList = [] 360a7ce71fSopenharmony_ci 370a7ce71fSopenharmony_ci def handle(self): 380a7ce71fSopenharmony_ci addr = self.request.getpeername() 390a7ce71fSopenharmony_ci print('Got connection from', addr) 400a7ce71fSopenharmony_ci 410a7ce71fSopenharmony_ci while True: 420a7ce71fSopenharmony_ci startTime = datetime.now() 430a7ce71fSopenharmony_ci req = self.rfile.read(REQUEST_SIZE) 440a7ce71fSopenharmony_ci if not req: 450a7ce71fSopenharmony_ci break 460a7ce71fSopenharmony_ci # recv request from client 470a7ce71fSopenharmony_ci frameId = int.from_bytes(req, 'big') # bytes request 480a7ce71fSopenharmony_ci 490a7ce71fSopenharmony_ci # prepare response 500a7ce71fSopenharmony_ci status, body = None, bytes() 510a7ce71fSopenharmony_ci if frameId < len(EncodeHandler.bitmapList): 520a7ce71fSopenharmony_ci status = STATUS_SUCCESS 530a7ce71fSopenharmony_ci body = EncodeHandler.bitmapList[frameId] 540a7ce71fSopenharmony_ci else: 550a7ce71fSopenharmony_ci status = STATUS_FAILURE 560a7ce71fSopenharmony_ci print('frameId out of range!') 570a7ce71fSopenharmony_ci break 580a7ce71fSopenharmony_ci # response header is: status(4B) + body length(4B) 590a7ce71fSopenharmony_ci head = struct.pack('>II', status, len(body)) 600a7ce71fSopenharmony_ci 610a7ce71fSopenharmony_ci # send response(header + body) to client 620a7ce71fSopenharmony_ci self.wfile.write(head + body) 630a7ce71fSopenharmony_ci 640a7ce71fSopenharmony_ci currentTime = datetime.now() 650a7ce71fSopenharmony_ci timeCost = currentTime - startTime 660a7ce71fSopenharmony_ci print('frameId:', frameId, 'timeCost: %.3f' % timeCost.total_seconds()) 670a7ce71fSopenharmony_ci print('handle request from', addr, 'done!') 680a7ce71fSopenharmony_ci self.wfile.close() 690a7ce71fSopenharmony_ci 700a7ce71fSopenharmony_cidef load_video_bin(binFile): 710a7ce71fSopenharmony_ci binFrames = [] 720a7ce71fSopenharmony_ci print('loading', binFile, '...') 730a7ce71fSopenharmony_ci with open(binFile, 'rb') as f: 740a7ce71fSopenharmony_ci while True: 750a7ce71fSopenharmony_ci blob = f.read(BIN_FRAME_SIZE) 760a7ce71fSopenharmony_ci if len(blob) == 0: 770a7ce71fSopenharmony_ci break 780a7ce71fSopenharmony_ci binFrames.append(blob) 790a7ce71fSopenharmony_ci print('load', binFile, 'done!') 800a7ce71fSopenharmony_ci return binFrames 810a7ce71fSopenharmony_ci 820a7ce71fSopenharmony_cidef main(): 830a7ce71fSopenharmony_ci if len(sys.argv) < 2: 840a7ce71fSopenharmony_ci print("Usage: {} binFile [port]\n\t".format(sys.argv[0])) 850a7ce71fSopenharmony_ci exit(-1) 860a7ce71fSopenharmony_ci 870a7ce71fSopenharmony_ci binFile = sys.argv[1] 880a7ce71fSopenharmony_ci port = DEFAULT_PORT if len(sys.argv) < 3 else int(sys.argv[2]) 890a7ce71fSopenharmony_ci 900a7ce71fSopenharmony_ci print('binFile:', binFile, 'port:', port) 910a7ce71fSopenharmony_ci server = ThreadingTCPServer(('', port), EncodeHandler) 920a7ce71fSopenharmony_ci 930a7ce71fSopenharmony_ci def sigint_handler(signum, frame): 940a7ce71fSopenharmony_ci print('sig {} raised: {}'.format(signum, frame)) 950a7ce71fSopenharmony_ci server.socket.close() 960a7ce71fSopenharmony_ci server.shutdown() 970a7ce71fSopenharmony_ci sys.exit(0) 980a7ce71fSopenharmony_ci signal.signal(signal.SIGINT, sigint_handler) # main thread will handle signals 990a7ce71fSopenharmony_ci 1000a7ce71fSopenharmony_ci try: 1010a7ce71fSopenharmony_ci EncodeHandler.bitmapList = load_video_bin(binFile) 1020a7ce71fSopenharmony_ci waiterThread = Thread(target=server.serve_forever, args=()) 1030a7ce71fSopenharmony_ci waiterThread.start() 1040a7ce71fSopenharmony_ci waiterThread.join() 1050a7ce71fSopenharmony_ci except Exception as e: 1060a7ce71fSopenharmony_ci print('exception raised:', e) 1070a7ce71fSopenharmony_ci finally: 1080a7ce71fSopenharmony_ci server.socket.close() 1090a7ce71fSopenharmony_ci server.shutdown() 1100a7ce71fSopenharmony_ci 1110a7ce71fSopenharmony_ciif __name__ == "__main__": 1120a7ce71fSopenharmony_ci main() 113