smyrgeorge/qrt: QRT: A screen-to-camera data transfer protocol


This project explores data transfer using a screen-to-camera approach. The idea is simple: encode information into a
sequence of QR codes, display them as a video on a screen, and then use a camera to capture and decode the video frames
to retrieve the original data.

This method enables:

  • Air-gapped data transfer between devices
  • One-way communication without network connectivity
  • Visual data encoding that can be recorded and processed later

Warning

This is a proof of concept. The protocol does not include encryption, so it is not secure for transmitting sensitive
data.

The project includes both encoding (generating QR code videos) and decoding (extracting data from captured
videos).

The QR Transfer (QRT) protocol defines how data is structured within each QR code frame. It provides reliable data
transfer with integrity verification and support for out-of-order frame reassembly.

All frames use | as field separator and start with a magic header QRT1 (version 1).

Header Frame (HDR) – First frame, contains transfer metadata:

Field Description
session_id 8-char unique identifier for this transfer
total_chunks Number of data frames to expect
total_size Total payload size in bytes
encoding Character encoding (e.g., utf-8)
checksum CRC32 of complete payload (hex)

Data Frame (DAT) – Contains actual payload chunks:

Field Description
session_id Same as header
sequence Frame number (0001-9999, 1-indexed)
total Total data frames
checksum CRC32 of this chunk’s payload (hex)
payload The actual data chunk

Footer Frame (END) – Last frame, marks end of transfer:

Field Description
session_id Same as header
checksum CRC32 of complete payload for verification

  • Session tracking: Multiple concurrent transfers distinguished by session ID
  • Ordering: Sequence numbers enable out-of-order reassembly
  • Integrity: CRC32 checksums at chunk and message level
  • Completeness: Header declares expected chunks, footer confirms end
  • Versioning: Magic header includes version for future compatibility

Encoder: generate_qr_video.py

Generates a QR code video from text input (single stream):

  1. Text Input: Accepts text directly or generates Lorem Ipsum placeholder text
  2. Protocol Framing: Wraps data in QRT protocol with header, data frames, and footer
  3. QR Generation: Creates a QR code image for each protocol frame
  4. Video Assembly: Uses ffmpeg to combine all QR code frames into a single video file

The output is an MP4 video where each frame displays a QR code containing a protocol-wrapped chunk.

Multi-Stream Encoder: generate_qr_video_multistream.py

Generates a video with multiple QR codes per frame for high-throughput transfer:

  1. Parallel Streams: Displays 1-12 QR codes simultaneously
  2. Grid Layout: Automatic arrangement in optimal grid
  3. Increased Throughput: Up to 400x+ faster than single-stream baseline
  4. Frame Repeat: Optional frame repetition for improved reliability

Supported grid configurations:

  • 1 stream: 1×1 (baseline)
  • 2 streams: 2×1
  • 4 streams: 2×2 (recommended)
  • 5-6 streams: 3×2
  • 7-8 streams: 4×2
  • 9 streams: 3×3
  • 10 streams: 5×2
  • 11-12 streams: 4×3 (maximum)

See BITRATE.md for detailed throughput analysis.

Decoder: decode_qr_video.py

Decodes a captured video and extracts the original message:

  1. Frame Extraction: Reads video frames using OpenCV
  2. QR Detection: Detects and decodes QR codes from each frame using pyzbar
  3. Deduplication: Filters duplicate frames (same QR captured multiple times)
  4. Integrity Check: Verifies CRC32 checksums for each chunk
  5. Reassembly: Orders chunks by sequence number and reconstructs the message
  6. Verification: Validates final message checksum against header/footer

The decoder handles real-world conditions: camera-captured videos with motion blur, duplicates, and potentially missing
frames.

Real-time Decoder: decode_realtime.py

Decodes QR codes directly from a live camera feed:

  1. Camera Selection: Lists available cameras including iPhone (via Continuity Camera on macOS)
  2. Live Detection: Continuously scans for QR codes in the camera feed
  3. Visual Feedback: Displays bounding boxes around detected QR codes with status
  4. Progress Tracking: Shows real-time progress bar and statistics
  5. Session Management: Automatically detects new transfer sessions

Features:

  • Visual overlay showing session ID, progress, and chunk count
  • Color-coded QR detection (green=valid, yellow=header, magenta=footer, red=error)
  • Keyboard controls for reset and save operations
  • Python 3.10+
  • ffmpeg installed and available in PATH
  • zbar library (for QR decoding)

On macOS:

Create Virtual Environment

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Generate a QR video with Lorem Ipsum:

python src/generate_qr_video.py

Generate with custom text:

python src/generate_qr_video.py -t "Your text to encode here"

Encoder options:

Option Description Default
-t, --text Text to encode Lorem Ipsum
-p, --paragraphs Number of Lorem Ipsum paragraphs 3
-c, --chunk-size Characters per QR code payload 100
-f, --fps Frames per second 2
-r, --resolution Video resolution 720×720
-o, --output Output filename output.mp4

Generate a 4-stream (2×2 grid) video:

python src/generate_qr_video_multistream.py

Generate with 8 streams for high throughput:

python src/generate_qr_video_multistream.py -s 8 -c 500 -f 10

Generate with 12 streams for maximum throughput:

python src/generate_qr_video_multistream.py -s 12 -c 400 -f 10 -r 1920x1080

Multi-stream encoder options:

Option Description Default
-t, --text Text to encode Lorem Ipsum
-p, --paragraphs Number of Lorem Ipsum paragraphs 5
-c, --chunk-size Characters per QR code payload 400
-s, --streams Number of parallel streams (1-12) 4
-f, --fps Frames per second 5
-r, --resolution Video resolution 1080×1080
-o, --output Output filename output_multistream.mp4
--repeat Repeat each frame N times 1

Decode a captured video:

python src/decode_qr_video.py captured_video.mov

Save decoded message to file:

python src/decode_qr_video.py captured_video.mov -o decoded.txt

Decoder options:

Option Description Default
-o, --output Save decoded message to file stdout
-s, --sample-rate Process every Nth frame (faster decoding) 1
-v, --verbose Print detailed progress off
--lenient Continue with missing frames/checksum errors off

List available cameras:

python src/decode_realtime.py -l

Start real-time decoder (interactive camera selection):

python src/decode_realtime.py

Use specific camera (e.g., iPhone via Continuity Camera):

python src/decode_realtime.py -c 1

Keyboard controls during real-time decoding:

Key Action
q Quit
r Reset session (clear captured data)
s Save decoded message to file

Real-time decoder options:

Option Description Default
-c, --camera Camera index interactive
-l, --list List cameras and exit
-o, --output Output file for decoded message timestamped filename



Source link

Leave a Reply

Your email address will not be published. Required fields are marked *