|
1 | 1 | import argparse
|
2 | 2 | import cv2
|
| 3 | +import math |
3 | 4 | import socket
|
4 | 5 | from turbojpeg import TurboJPEG
|
5 | 6 | import time
|
| 7 | +import threading |
| 8 | +import re |
| 9 | + |
| 10 | +quitting = False |
| 11 | +got_connection = False |
| 12 | + |
| 13 | +def publish_mc_group(): |
| 14 | + global quitting |
| 15 | + global got_connection |
| 16 | + MCAST_GRP = '239.1.1.1' |
| 17 | + MCAST_PORT = 5000 |
| 18 | + sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) |
| 19 | + sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 32) |
| 20 | + while not quitting and not got_connection: |
| 21 | + try: |
| 22 | + sock.sendto(b'Hello World!', (MCAST_GRP, MCAST_PORT)) |
| 23 | + time.sleep(1) |
| 24 | + except: |
| 25 | + break |
| 26 | + print("Multicast thread exiting") |
6 | 27 |
|
7 | 28 | def main(host="0.0.0.0", port=8888):
|
| 29 | + global quitting |
| 30 | + global got_connection |
8 | 31 | header = b'\xaa\xbb\xcc\xdd'
|
9 | 32 | jpeg = TurboJPEG()
|
| 33 | + t = threading.Thread(target=publish_mc_group, args=[]) |
| 34 | + t.start() |
10 | 35 | with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
11 | 36 | s.bind((host, port))
|
12 | 37 | print("server lisening on {}:{}".format(host,port))
|
13 | 38 | s.listen()
|
14 | 39 | conn, addr = s.accept()
|
15 | 40 | with conn:
|
16 | 41 | print(f"Connected by {addr}")
|
| 42 | + got_connection = True |
17 | 43 | total_bytes = 0
|
18 | 44 | total_frames = 0
|
19 | 45 | start = None
|
20 | 46 | while True:
|
21 | 47 | # try to get all chunks of the message
|
| 48 | + # print("Trying to get new image") |
22 | 49 | img_data = bytearray()
|
23 |
| - max_recv_size = 40*1024 |
| 50 | + max_recv_size = 1*1024 |
24 | 51 | remaining = max_recv_size
|
25 | 52 | got_header = False
|
26 | 53 | while True:
|
27 | 54 | recv_len = remaining if remaining < max_recv_size else max_recv_size
|
28 | 55 | # print("receiving", recv_len, "bytes")
|
29 |
| - data = conn.recv(recv_len) |
30 |
| - if not data: |
31 |
| - print("breaking loop because (not data) == true") |
32 |
| - break |
| 56 | + try: |
| 57 | + data = conn.recv(recv_len) |
| 58 | + except KeyboardInterrupt: |
| 59 | + print("quitting...") |
| 60 | + quitting = True |
| 61 | + t.join() |
| 62 | + return |
33 | 63 | if not start:
|
34 | 64 | start = time.time()
|
35 |
| - if data[0:4] == header: |
36 |
| - length = (int(data[4]) << 24) + (int(data[5]) << 16) + (int(data[6]) << 8) + int(data[7]) |
37 |
| - remaining = length - len(data) + 8 |
38 |
| - img_data.extend(data[8:]) |
39 |
| - got_header = True |
40 |
| - # print("Got header, image length:", length) |
41 |
| - # print("remaining:", remaining) |
| 65 | + # find the header in the bytearray |
| 66 | + if not got_header: |
| 67 | + try: |
| 68 | + index = data.index(header) |
| 69 | + if index >= 0: |
| 70 | + got_header = True |
| 71 | + length = \ |
| 72 | + (int(data[index+4]) << 24) + \ |
| 73 | + (int(data[index+5]) << 16) + \ |
| 74 | + (int(data[index+6]) << 8) + \ |
| 75 | + int(data[index+7]) |
| 76 | + data_start = index + 8 |
| 77 | + data_bytes = len(data) - data_start |
| 78 | + num_img_bytes = min(length, data_bytes) |
| 79 | + remaining = length - num_img_bytes |
| 80 | + data_end = data_start + num_img_bytes + 1 |
| 81 | + img_data.extend(data[data_start:data_end]) |
| 82 | + # print("Got index:", index) |
| 83 | + # print("Got data_start:", data_start) |
| 84 | + # print("Got data_end:", data_end) |
| 85 | + # print("Got header, image length:", length) |
| 86 | + # print("remaining:", remaining) |
| 87 | + except: |
| 88 | + pass |
42 | 89 | elif got_header and remaining > 0:
|
43 |
| - if remaining >= len(data): |
44 |
| - remaining = remaining - len(data) |
45 |
| - img_data.extend(data) |
46 |
| - else: |
47 |
| - print("got more data than we needed:", len(data), remaining) |
48 |
| - img_data.extend(data[:remaining]) |
49 |
| - remaining = 0 |
50 |
| - if got_header and remaining <= 0: |
| 90 | + num_img_bytes = min(remaining, len(data)) |
| 91 | + img_data.extend(data[:num_img_bytes]) |
| 92 | + remaining = remaining - num_img_bytes |
| 93 | + |
| 94 | + if got_header and remaining == 0: |
51 | 95 | break;
|
| 96 | + |
52 | 97 | end = time.time()
|
53 | 98 | elapsed = end - start
|
54 | 99 | total_bytes += len(img_data)
|
55 | 100 | total_frames += 1
|
56 |
| - print("got image data, len:", len(img_data)) |
| 101 | + # print("got image data, len:", len(img_data)) |
57 | 102 | print("metrics: {:.0f} KB/s, {:.1f} FPS".format((total_bytes / 1024) / elapsed, total_frames / elapsed))
|
58 | 103 | try:
|
59 | 104 | img = jpeg.decode(img_data)
|
60 | 105 | cv2.imshow('Remote Camera', img)
|
61 | 106 | cv2.waitKey(1)
|
62 |
| - except Exception as e: |
63 |
| - # print("Could not open jpeg image:") |
64 |
| - # print(e) |
| 107 | + except: |
65 | 108 | pass
|
66 | 109 |
|
67 | 110 | if __name__ == "__main__":
|
|
0 commit comments