From 3d0382268958a5923fe3eb1df8161c78375fcf93 Mon Sep 17 00:00:00 2001 From: Anthony Wang Date: Sun, 12 May 2024 16:33:34 -0400 Subject: Run camera at 60fps and use state machine to skip every other frame --- README.md | 2 +- decoder.py | 19 ++++++++++++++----- encoder.py | 6 +++--- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index cafe92a..a37c82c 100644 --- a/README.md +++ b/README.md @@ -18,4 +18,4 @@ Copy the flags printed by the encoder and pass them to the decoder: `python deco Formatting: `black -l 120 *.py` -Use phone as webcam for higher quality video: `scrcpy --v4l2-sink=/dev/video4 --video-source=camera --no-video-playback --camera-size 1920x1440` +Use phone as webcam for higher quality video: `scrcpy --v4l2-sink=/dev/video4 --video-source=camera --no-video-playback --camera-size 1920x1080 --camera-fps 60` diff --git a/decoder.py b/decoder.py index 43d06a5..a1c0d51 100644 --- a/decoder.py +++ b/decoder.py @@ -47,13 +47,19 @@ if args.input.isdecimal(): args.input = int(args.input) cap = cv2.VideoCapture(args.input) data = None -start_time = time.time() +start_time = 0 +status = 0 +decoded = 0 while data is None: try: ret, raw_frame = cap.read() if not ret: print("End of stream") break + if isinstance(args.input, int) and (status == 1 or (status == 0 and np.random.rand() < 0.5)): + status = 2 + print("Skipped") + continue # raw_frame is a uint8 BE CAREFUL if type(args.input) == int: # Crop image to reduce camera distortion @@ -98,9 +104,6 @@ while data is None: frame = cv2.warpPerspective(raw_frame, M, (args.width, args.height)) # Convert to new color space frame = (np.squeeze(F @ (frame - origin)[..., np.newaxis]) >= 192).astype(np.uint8) - # import matplotlib.pyplot as pltc - # plt.imshow(frame * 255) - # plt.show() frame = np.packbits( np.concatenate( ( @@ -109,16 +112,22 @@ while data is None: frame[args.height - cheight :, cwidth : args.width - cwidth].flatten(), ) ) - ) + )[:frame_bytes] reshape_len = frame_bytes // 255 * 255 frame[:reshape_len] = np.ravel(frame[:reshape_len].reshape(255, reshape_len // 255), "F") data = decoder.decode(bytes(rsc.decode(bytearray(frame ^ frame_xor))[0][: args.psize])) + decoded += 1 + status = 1 + if start_time == 0: + start_time = time.time() print("Decoded frame") except KeyboardInterrupt: break except Exception as e: + status = 0 print(e) cap.release() +print(decoded) with open(args.output, "wb") as f: f.write(data) print(8 * len(data) / (time.time() - start_time)) diff --git a/encoder.py b/encoder.py index 38d89cb..d71990d 100644 --- a/encoder.py +++ b/encoder.py @@ -29,7 +29,7 @@ with open(args.input, "rb") as f: data = f.read() rsc = RSCodec(int(args.level * 255)) encoder = Encoder.with_defaults(data, rs_bytes) -packets = encoder.get_encoded_packets(int(len(data) / rs_bytes * (1 / (1 - args.level) - 1))) +packets = encoder.get_encoded_packets(int(len(data) / rs_bytes)) # Make corners ones = np.ones((cheight - 1, cwidth - 1)) @@ -51,7 +51,7 @@ def mkframe(packet): frame[:reshape_len] = np.ravel(frame[:reshape_len].reshape(reshape_len // 255, 255), "F") frame = np.unpackbits(frame) # Pad to be multiple of 3 so we can reshape into RGB channels - frame = np.pad(frame, (0, (3 - len(frame)) % 3)) + frame = np.pad(frame, (0, 3 * frame_size - len(frame))) frame = np.reshape(frame, (frame_size, 3)) frame = np.concatenate( ( @@ -90,7 +90,7 @@ if args.mix: vidframe[hscale * (args.height - cheight) :, wscale * (args.width - cwidth) :] = 0 frame = np.repeat(np.repeat(mkframe(packets[i]), hscale, 0), wscale, 1) # Set edges in original video to black - frame[vidframe % 255 != 0] = 0 + frame[(32 <= vidframe) & (vidframe < 224)] = 0 out.write(cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)) i = (i + 1) % len(packets) else: -- cgit v1.2.3-70-g09d2