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
245 int16_t transmit(uint16_t* packetId = NULL);
246
252 int16_t transmitLoRa(uint16_t* packetId = NULL);
253
257 void clearImage();
258
259 // receive methods
260
267 int16_t read(uint8_t* packet);
268
276 static int16_t isValidPacket(uint8_t* packet, int16_t* errors = NULL);
277
283 static void parseHeader(const uint8_t* packet, SSDVPacketInfo_t* info);
284
292 int16_t beginDecoder(uint8_t* jpegBuf, size_t jpegBufLen);
293
300 int16_t feedPacket(const uint8_t* packet);
301
308 int16_t getJpeg(uint8_t** jpegPtr, size_t* jpegLen);
309
314 int16_t resetDecoder();
315
319 void endDecoder();
320
321#if !RADIOLIB_GODMODE
322 private:
323#endif
324 PhysicalLayer* phyLayer;
325 bool fec;
326 bool initialized;
327 char callsign[RADIOLIB_SSDV_CALLSIGN_MAX_LEN + 1];
328 uint8_t imageId;
329
330 // transmitter, the packet buffer is owned by this instance
331 SSDVState_t encoder;
332 uint8_t* txBuf;
333 uint16_t packetCount;
334 uint16_t packetIndex;
335
336 // receiver, the JPEG buffer is owned by the caller
337 SSDVState_t decoder;
338 uint8_t* rxBuf;
339 size_t jpegBufLen;
340 size_t jpegLen;
341 bool jpegReady;
342
343 SSDVClient(const SSDVClient&);
344 SSDVClient& operator=(const SSDVClient&);
345
346 int32_t encode(const uint8_t* jpegData, size_t jpegLen, uint8_t quality, uint8_t* dst, uint16_t maxPackets);
347 int16_t transmitPacket(uint8_t offset, uint16_t* packetId);
348};
349
350#endif
351
352#endif
Provides common interface for protocols that run on LoRa/FSK modules, such as RTTY or LoRaWAN....
Definition PhysicalLayer.h:390
int16_t transmit(uint16_t *packetId=NULL)
Transmit the next packet, all 256 bytes including sync word. Intended for RTTY/FSK.
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:1325
void endDecoder()
Detach the decoder from its output buffer. The buffer is owned by the caller and is not released.
Definition SSDV.cpp:1335
int16_t getJpeg(uint8_t **jpegPtr, size_t *jpegLen)
Get the reconstructed JPEG after feedPacket() returned RADIOLIB_SSDV_EOI.
Definition SSDV.cpp:1357
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:1302
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:1341
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:1230
~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:1261
int16_t read(uint8_t *packet)
Read a received packet from the radio. The packet is not validated, call isValidPacket() on it.
Definition SSDV.cpp:1244
int16_t resetDecoder()
Reset the decoder to receive a new image into the same output buffer.
Definition SSDV.cpp:1388
int16_t transmitLoRa(uint16_t *packetId=NULL)
Transmit the next packet without the sync word (255 bytes), to fit the LoRa payload limit.
Definition SSDV.cpp:1204
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