RadioLib
Universal wireless communication library for Arduino
Loading...
Searching...
No Matches
SSDV.h
1#if !defined(RADIOLIB_SSDV_H)
2#define RADIOLIB_SSDV_H
3
4#include "../../TypeDef.h"
5
6#if !RADIOLIB_EXCLUDE_SSDV
7
8#include "../PhysicalLayer/PhysicalLayer.h"
9
10/*
11 SSDV (Slow Scan Digital Video) packet layout, see https://ukhas.org.uk/doku.php?id=guides:ssdv
12
13 Byte Normal (FEC) No-FEC Content
14 0 0x55 0x55 sync
15 1 0x66 0x67 packet type
16 2-5 callsign, base-40 encoded, MSB first
17 6 image ID
18 7-8 packet ID, MSB first
19 9 image width / 16
20 10 image height / 16
21 11 [7:6] 0, [5:3] quality XOR 4, [2] EOI, [1:0] MCU mode
22 12 offset of first MCU in payload (0xFF = none)
23 13-14 index of first MCU, MSB first (0xFFFF = none)
24 15-... 205 B payload 237 B payload re-encoded JPEG scan data
25 ... CRC-32 CRC-32 over bytes 1 to end of payload
26 224-255 RS(255,223) parity - over bytes 1-223
27*/
28
29#ifndef RADIOLIB_SSDV_MAX_PACKETS
30#define RADIOLIB_SSDV_MAX_PACKETS (512)
31#endif
32
33// packet sizes in bytes
34#define RADIOLIB_SSDV_PACKET_LEN (256)
35#define RADIOLIB_SSDV_HEADER_LEN (15)
36#define RADIOLIB_SSDV_CRC_LEN (4)
37#define RADIOLIB_SSDV_RS_LEN (32)
38#define RADIOLIB_SSDV_PAYLOAD_LEN_FEC (RADIOLIB_SSDV_PACKET_LEN - RADIOLIB_SSDV_HEADER_LEN - RADIOLIB_SSDV_CRC_LEN - RADIOLIB_SSDV_RS_LEN)
39#define RADIOLIB_SSDV_PAYLOAD_LEN_NOFEC (RADIOLIB_SSDV_PACKET_LEN - RADIOLIB_SSDV_HEADER_LEN - RADIOLIB_SSDV_CRC_LEN)
40
41// packet fields
42#define RADIOLIB_SSDV_SYNC_WORD (0x55)
43#define RADIOLIB_SSDV_TYPE_OFFSET (0x66)
44#define RADIOLIB_SSDV_TYPE_NORMAL (0x00)
45#define RADIOLIB_SSDV_TYPE_NOFEC (0x01)
46#define RADIOLIB_SSDV_TYPE_INVALID (0xFF)
47#define RADIOLIB_SSDV_MCU_NONE (0xFFFF)
48
49// maximum callsign length in characters
50#define RADIOLIB_SSDV_CALLSIGN_MAX_LEN (6)
51
52// maximum quality level
53#define RADIOLIB_SSDV_QUALITY_MAX (7)
54
58#define RADIOLIB_SSDV_EOI (1)
59
66 uint8_t type;
67
69 uint32_t callsignCode;
70
72 char callsign[RADIOLIB_SSDV_CALLSIGN_MAX_LEN + 1];
73
75 uint8_t imageId;
76
78 uint16_t packetId;
79
81 uint16_t width;
82
84 uint16_t height;
85
87 bool eoi;
88
90 uint8_t quality;
91
93 uint8_t mcuMode;
94
96 uint8_t mcuOffset;
97
99 uint16_t mcuId;
100
102 uint16_t mcuCount;
103};
104
105// internal encoder/decoder state
106// maximum size of the DQT and DHT tables, plus room for marker data
107#define RADIOLIB_SSDV_TBL_LEN (546)
108#define RADIOLIB_SSDV_HBUFF_LEN (16)
109
111 // packet configuration
112 uint8_t type;
113 uint16_t payloadLen;
114 uint16_t crcDataLen;
115
116 // image information
117 uint16_t width;
118 uint16_t height;
119 uint32_t callsign;
120 uint8_t imageId;
121 uint16_t packetId;
122 uint8_t mcuMode;
123 uint16_t mcuId;
124 uint16_t mcuCount;
125 uint8_t quality;
126 uint16_t packetMcuId;
127 uint8_t packetMcuOffset;
128
129 // input bytes and bits
130 const uint8_t* inp;
131 size_t inLen;
132 size_t inSkip;
133 uint32_t workBits;
134 uint8_t workLen;
135
136 // output bytes and bits
137 uint8_t* out;
138 uint8_t* outp;
139 size_t outLen;
140 bool outStuff;
141 uint64_t outBits;
142 uint8_t outBitsLen;
143 bool outOverflow; // bits were dropped because the output buffer was full
144
145 // JPEG state machine
146 uint8_t state;
147 bool encoding;
148 uint16_t marker;
149 uint16_t markerLen;
150 uint8_t* markerData;
151 uint16_t markerDataLen;
152 bool greyscale;
153 uint8_t component; // 0 = Y, 1 = Cb, 2 = Cr
154 uint8_t ycParts; // number of Y blocks per MCU
155 uint8_t mcuPart; // 0 - 3 = Y, then Cb, Cr
156 uint8_t acPart; // 0 = DC, 1 - 63 = AC
157 int32_t dc[3];
158 int32_t adc[3];
159 uint8_t acRle;
160 uint8_t acAccRle;
161 uint16_t dri;
162 uint32_t resetMcu;
163 uint32_t nextResetMcu;
164 uint8_t needBits;
165
166 // source (input) and destination (output) Huffman and quantisation tables
167 uint8_t srcTbls[RADIOLIB_SSDV_TBL_LEN + RADIOLIB_SSDV_HBUFF_LEN];
168 uint8_t* srcDht[2][2];
169 uint8_t* srcDqt[2];
170 uint16_t srcTblLen;
171 uint8_t dstTbls[RADIOLIB_SSDV_TBL_LEN];
172 uint8_t* dstDht[2][2];
173 uint8_t* dstDqt[2];
174 uint16_t dstTblLen;
175};
176
185 public:
192 explicit SSDVClient(PhysicalLayer* phy, bool fec = true);
193
197 ~SSDVClient();
198
204 int16_t begin(const char* callsign);
205
206 // transmit methods
207
220 int16_t setImage(const uint8_t* jpegData, size_t jpegLen, uint8_t quality = 4, int16_t imageId = -1);
221
226 uint16_t numPackets();
227
232 bool isDone();
233
238 uint16_t currentPacketIndex();
239
246 int16_t transmit(uint16_t* packetId = NULL);
247
251 void clearImage();
252
253 // receive methods
254
261 int16_t read(uint8_t* packet);
262
270 static int16_t isValidPacket(uint8_t* packet, int16_t* errors = NULL);
271
277 static void parseHeader(const uint8_t* packet, SSDVPacketInfo_t* info);
278
286 int16_t beginDecoder(uint8_t* jpegBuf, size_t jpegBufLen);
287
294 int16_t feedPacket(const uint8_t* packet);
295
302 int16_t getJpeg(uint8_t** jpegPtr, size_t* jpegLen);
303
308 int16_t resetDecoder();
309
313 void endDecoder();
314
315#if !RADIOLIB_GODMODE
316 private:
317#endif
318 PhysicalLayer* phyLayer;
319 bool fec;
320 bool initialized;
321 char callsign[RADIOLIB_SSDV_CALLSIGN_MAX_LEN + 1];
322 uint8_t imageId;
323
324 // transmitter, the packet buffer is owned by this instance
325 SSDVState_t encoder;
326 uint8_t* txBuf;
327 uint16_t packetCount;
328 uint16_t packetIndex;
329
330 // receiver, the JPEG buffer is owned by the caller
331 SSDVState_t decoder;
332 uint8_t* rxBuf;
333 size_t jpegBufLen;
334 size_t jpegLen;
335 bool jpegReady;
336
337 SSDVClient(const SSDVClient&);
338 SSDVClient& operator=(const SSDVClient&);
339
340 int32_t encode(const uint8_t* jpegData, size_t jpegLen, uint8_t quality, uint8_t* dst, uint16_t maxPackets);
341};
342
343#endif
344
345#endif
Provides common interface for protocols that run on LoRa/FSK modules, such as RTTY or LoRaWAN....
Definition PhysicalLayer.h:402
int16_t transmit(uint16_t *packetId=NULL)
Transmit the next packet. The sync word is redundant with the radio's own packet framing,...
Definition SSDV.cpp:1200
int16_t begin(const char *callsign)
Initialization method.
Definition SSDV.cpp:1069
int16_t beginDecoder(uint8_t *jpegBuf, size_t jpegBufLen)
Initialize the JPEG decoder. A safe output buffer size is (number of packets) * (payload length) + 20...
Definition SSDV.cpp:1316
void endDecoder()
Detach the decoder from its output buffer. The buffer is owned by the caller and is not released.
Definition SSDV.cpp:1326
int16_t getJpeg(uint8_t **jpegPtr, size_t *jpegLen)
Get the reconstructed JPEG after feedPacket() returned RADIOLIB_SSDV_EOI.
Definition SSDV.cpp:1348
uint16_t currentPacketIndex()
Get the index of the next packet to be transmitted.
Definition SSDV.cpp:1196
static void parseHeader(const uint8_t *packet, SSDVPacketInfo_t *info)
Parse the header of a validated packet.
Definition SSDV.cpp:1293
int16_t feedPacket(const uint8_t *packet)
Feed a validated packet to the decoder. Packets must arrive in ascending order; missing packets are r...
Definition SSDV.cpp:1332
uint16_t numPackets()
Get the number of packets of the current image.
Definition SSDV.cpp:1188
void clearImage()
Discard the current image and release the packet buffer.
Definition SSDV.cpp:1223
~SSDVClient()
Destructor, releases the packet buffer and decoder state.
Definition SSDV.cpp:1065
static int16_t isValidPacket(uint8_t *packet, int16_t *errors=NULL)
Validate a packet by its CRC. If that fails, Reed-Solomon correction is attempted (up to 16 symbol er...
Definition SSDV.cpp:1252
int16_t read(uint8_t *packet)
Read a received packet from the radio and restore its sync word. The packet is not validated,...
Definition SSDV.cpp:1237
int16_t resetDecoder()
Reset the decoder to receive a new image into the same output buffer.
Definition SSDV.cpp:1379
int16_t setImage(const uint8_t *jpegData, size_t jpegLen, uint8_t quality=4, int16_t imageId=-1)
Encode a JPEG image into SSDV packets. Any previously loaded image is discarded. The packets are stor...
Definition SSDV.cpp:1142
bool isDone()
Check whether all packets of the current image have been sent.
Definition SSDV.cpp:1192
SSDVClient(PhysicalLayer *phy, bool fec=true)
Default constructor.
Definition SSDV.cpp:1055
Header fields of an SSDV packet, filled by SSDVClient::parseHeader.
Definition SSDV.h:64
uint16_t width
Image width in pixels.
Definition SSDV.h:81
uint8_t mcuOffset
Offset of the first MCU in the payload.
Definition SSDV.h:96
uint8_t type
Packet type, RADIOLIB_SSDV_TYPE_NORMAL or RADIOLIB_SSDV_TYPE_NOFEC.
Definition SSDV.h:66
uint32_t callsignCode
Base-40 encoded callsign.
Definition SSDV.h:69
uint16_t mcuCount
Total number of MCU blocks in the image.
Definition SSDV.h:102
char callsign[RADIOLIB_SSDV_CALLSIGN_MAX_LEN+1]
Decoded, null-terminated callsign.
Definition SSDV.h:72
uint16_t height
Image height in pixels.
Definition SSDV.h:84
uint16_t mcuId
Index of the first MCU in this packet, RADIOLIB_SSDV_MCU_NONE if no MCU starts here.
Definition SSDV.h:99
uint16_t packetId
Packet ID, starting from 0.
Definition SSDV.h:78
uint8_t imageId
Image ID.
Definition SSDV.h:75
uint8_t quality
Quality level, 0 - 7.
Definition SSDV.h:90
uint8_t mcuMode
Chroma subsampling mode: 0 = 2x2, 1 = 1x2, 2 = 2x1, 3 = 1x1.
Definition SSDV.h:93
bool eoi
Whether this is the last packet of the image.
Definition SSDV.h:87
Definition SSDV.h:110