Make the non-FEC packets 256 bytes long, same length as normal packets.
Non-FEC packets now have a packet type of 0x67.
This commit is contained in:
parent
22d912f7de
commit
278004fb0c
17
main.c
17
main.c
|
@ -35,7 +35,7 @@ int main(int argc, char *argv[])
|
|||
FILE *fin = stdin;
|
||||
FILE *fout = stdout;
|
||||
char encode = -1;
|
||||
char fec = -1;
|
||||
char type = SSDV_TYPE_NORMAL;
|
||||
int droptest = 0;
|
||||
char callsign[7];
|
||||
uint8_t image_id = 0;
|
||||
|
@ -53,7 +53,7 @@ int main(int argc, char *argv[])
|
|||
{
|
||||
case 'e': encode = 1; break;
|
||||
case 'd': encode = 0; break;
|
||||
case 'n': fec = 0; break;
|
||||
case 'n': type = SSDV_TYPE_NOFEC; break;
|
||||
case 'c':
|
||||
if(strlen(optarg) > 6)
|
||||
fprintf(stderr, "Warning: callsign is longer than 6 characters.\n");
|
||||
|
@ -101,22 +101,20 @@ int main(int argc, char *argv[])
|
|||
case 0: /* Decode */
|
||||
if(droptest > 0) fprintf(stderr, "*** NOTE: Drop test enabled: %i ***\n", droptest);
|
||||
|
||||
ssdv_dec_init(&ssdv);
|
||||
ssdv_dec_init(&ssdv, type);
|
||||
|
||||
jpeg_length = 1024 * 1024 * 4;
|
||||
jpeg = malloc(jpeg_length);
|
||||
ssdv_dec_set_buffer(&ssdv, jpeg, jpeg_length);
|
||||
|
||||
ssdv_set_fec(&ssdv, (fec ? 1 : 0));
|
||||
|
||||
i = 0;
|
||||
while(fread(pkt, 1, (fec ? SSDV_PKT_SIZE : SSDV_PKT_SIZE - SSDV_PKT_SIZE_RSCODES), fin) > 0)
|
||||
while(fread(pkt, 1, SSDV_PKT_SIZE, fin) > 0)
|
||||
{
|
||||
/* Drop % of packets */
|
||||
if(droptest && (rand() / (RAND_MAX / 100) < droptest)) continue;
|
||||
|
||||
/* Test the packet is valid */
|
||||
if(ssdv_dec_is_packet(pkt, NULL, (fec ? 1 : 0)) != 0) continue;
|
||||
if(ssdv_dec_is_packet(pkt, NULL, type) != 0) continue;
|
||||
|
||||
/* Feed it to the decoder */
|
||||
ssdv_dec_feed(&ssdv, pkt);
|
||||
|
@ -132,9 +130,8 @@ int main(int argc, char *argv[])
|
|||
break;
|
||||
|
||||
case 1: /* Encode */
|
||||
ssdv_enc_init(&ssdv, callsign, image_id);
|
||||
ssdv_enc_init(&ssdv, type, callsign, image_id);
|
||||
ssdv_enc_set_buffer(&ssdv, pkt);
|
||||
ssdv_set_fec(&ssdv, (fec ? 1 : 0));
|
||||
|
||||
i = 0;
|
||||
|
||||
|
@ -163,7 +160,7 @@ int main(int argc, char *argv[])
|
|||
return(-1);
|
||||
}
|
||||
|
||||
fwrite(pkt, 1, (fec ? SSDV_PKT_SIZE : SSDV_PKT_SIZE - SSDV_PKT_SIZE_RSCODES), fout);
|
||||
fwrite(pkt, 1, SSDV_PKT_SIZE, fout);
|
||||
i++;
|
||||
}
|
||||
|
||||
|
|
92
ssdv.c
92
ssdv.c
|
@ -531,7 +531,7 @@ static char ssdv_process(ssdv_t *s)
|
|||
|
||||
s->reset_mcu = s->mcu_id;
|
||||
s->packet_mcu_id = s->mcu_id;
|
||||
s->packet_mcu_offset = SSDV_PKT_SIZE_PAYLOAD - s->out_len;
|
||||
s->packet_mcu_offset = s->pkt_size_payload - s->out_len;
|
||||
}
|
||||
|
||||
if(s->mode == S_DECODING && s->mcu_id == s->reset_mcu)
|
||||
|
@ -557,6 +557,23 @@ static char ssdv_process(ssdv_t *s)
|
|||
return(SSDV_OK);
|
||||
}
|
||||
|
||||
static void ssdv_set_packet_conf(ssdv_t *s)
|
||||
{
|
||||
/* Configure the payload size and CRC position */
|
||||
switch(s->type)
|
||||
{
|
||||
case SSDV_TYPE_NORMAL:
|
||||
s->pkt_size_payload = SSDV_PKT_SIZE - SSDV_PKT_SIZE_HEADER - SSDV_PKT_SIZE_CRC - SSDV_PKT_SIZE_RSCODES;
|
||||
s->pkt_size_crcdata = SSDV_PKT_SIZE_HEADER + s->pkt_size_payload - 1;
|
||||
break;
|
||||
|
||||
case SSDV_TYPE_NOFEC:
|
||||
s->pkt_size_payload = SSDV_PKT_SIZE - SSDV_PKT_SIZE_HEADER - SSDV_PKT_SIZE_CRC;
|
||||
s->pkt_size_crcdata = SSDV_PKT_SIZE_HEADER + s->pkt_size_payload - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void ssdv_memset_prng(uint8_t *s, size_t n)
|
||||
|
@ -814,13 +831,14 @@ static char ssdv_have_marker_data(ssdv_t *s)
|
|||
return(SSDV_OK);
|
||||
}
|
||||
|
||||
char ssdv_enc_init(ssdv_t *s, char *callsign, uint8_t image_id)
|
||||
char ssdv_enc_init(ssdv_t *s, uint8_t type, char *callsign, uint8_t image_id)
|
||||
{
|
||||
memset(s, 0, sizeof(ssdv_t));
|
||||
s->image_id = image_id;
|
||||
s->callsign = encode_callsign(callsign);
|
||||
s->mode = S_ENCODING;
|
||||
s->fec = 1;
|
||||
s->type = type;
|
||||
ssdv_set_packet_conf(s);
|
||||
|
||||
/* Prepare the output JPEG tables */
|
||||
s->ddqt[0] = dtblcpy(s, std_dqt0, sizeof(std_dqt0));
|
||||
|
@ -837,7 +855,7 @@ char ssdv_enc_set_buffer(ssdv_t *s, uint8_t *buffer)
|
|||
{
|
||||
s->out = buffer;
|
||||
s->outp = buffer + SSDV_PKT_SIZE_HEADER;
|
||||
s->out_len = SSDV_PKT_SIZE_PAYLOAD;
|
||||
s->out_len = s->pkt_size_payload;
|
||||
|
||||
/* Zero the payload memory */
|
||||
memset(s->out, 0, SSDV_PKT_SIZE);
|
||||
|
@ -927,12 +945,12 @@ char ssdv_enc_get_packet(ssdv_t *s)
|
|||
uint8_t i, mcu_offset = s->packet_mcu_offset;
|
||||
uint32_t x;
|
||||
|
||||
if(mcu_offset != 0xFF && mcu_offset >= SSDV_PKT_SIZE_PAYLOAD)
|
||||
if(mcu_offset != 0xFF && mcu_offset >= s->pkt_size_payload)
|
||||
{
|
||||
/* The first MCU begins in the next packet, not this one */
|
||||
mcu_id = 0xFFFF;
|
||||
mcu_offset = 0xFF;
|
||||
s->packet_mcu_offset -= SSDV_PKT_SIZE_PAYLOAD;
|
||||
s->packet_mcu_offset -= s->pkt_size_payload;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -943,7 +961,7 @@ char ssdv_enc_get_packet(ssdv_t *s)
|
|||
|
||||
/* A packet is ready, create the headers */
|
||||
s->out[0] = 0x55; /* Sync */
|
||||
s->out[1] = 0x66; /* Type */
|
||||
s->out[1] = 0x66 + s->type; /* Type */
|
||||
s->out[2] = s->callsign >> 24;
|
||||
s->out[3] = s->callsign >> 16;
|
||||
s->out[4] = s->callsign >> 8;
|
||||
|
@ -962,16 +980,17 @@ char ssdv_enc_get_packet(ssdv_t *s)
|
|||
if(s->out_len > 0) ssdv_memset_prng(s->outp, s->out_len);
|
||||
|
||||
/* Calculate the CRC codes */
|
||||
x = crc32(&s->out[1], SSDV_PKT_SIZE_CRCDATA);
|
||||
x = crc32(&s->out[1], s->pkt_size_crcdata);
|
||||
|
||||
i = 1 + SSDV_PKT_SIZE_CRCDATA;
|
||||
i = 1 + s->pkt_size_crcdata;
|
||||
s->out[i++] = (x >> 24) & 0xFF;
|
||||
s->out[i++] = (x >> 16) & 0xFF;
|
||||
s->out[i++] = (x >> 8) & 0xFF;
|
||||
s->out[i++] = x & 0xFF;
|
||||
|
||||
/* Generate the RS codes */
|
||||
if(s->fec == 1) encode_rs_8(&s->out[1], &s->out[i], 0);
|
||||
if(s->type == SSDV_TYPE_NORMAL)
|
||||
encode_rs_8(&s->out[1], &s->out[i], 0);
|
||||
|
||||
s->packet_id++;
|
||||
|
||||
|
@ -1094,14 +1113,15 @@ static void ssdv_fill_gap(ssdv_t *s, uint16_t next_mcu)
|
|||
}
|
||||
}
|
||||
|
||||
char ssdv_dec_init(ssdv_t *s)
|
||||
char ssdv_dec_init(ssdv_t *s, uint8_t type)
|
||||
{
|
||||
memset(s, 0, sizeof(ssdv_t));
|
||||
|
||||
/* The packet data should contain only scan data, no headers */
|
||||
s->state = S_HUFF;
|
||||
s->mode = S_DECODING;
|
||||
s->fec = 1;
|
||||
s->type = type;
|
||||
ssdv_set_packet_conf(s);
|
||||
|
||||
/* Prepare the source JPEG tables */
|
||||
s->sdqt[0] = stblcpy(s, std_dqt0, sizeof(std_dqt0));
|
||||
|
@ -1212,7 +1232,7 @@ char ssdv_dec_feed(ssdv_t *s, uint8_t *packet)
|
|||
}
|
||||
|
||||
/* Feed the JPEG data into the processor */
|
||||
for(; i < SSDV_PKT_SIZE_PAYLOAD; i++)
|
||||
for(; i < s->pkt_size_payload; i++)
|
||||
{
|
||||
b = packet[SSDV_PKT_SIZE_HEADER + i];
|
||||
|
||||
|
@ -1262,9 +1282,11 @@ char ssdv_dec_get_jpeg(ssdv_t *s, uint8_t **jpeg, size_t *length)
|
|||
return(SSDV_OK);
|
||||
}
|
||||
|
||||
char ssdv_dec_is_packet(uint8_t *packet, int *errors, uint8_t fec)
|
||||
char ssdv_dec_is_packet(uint8_t *packet, int *errors, uint8_t type)
|
||||
{
|
||||
uint8_t pkt[SSDV_PKT_SIZE];
|
||||
uint16_t pkt_size_payload;
|
||||
uint16_t pkt_size_crcdata;
|
||||
ssdv_packet_info_t p;
|
||||
uint32_t x;
|
||||
int i;
|
||||
|
@ -1272,35 +1294,48 @@ char ssdv_dec_is_packet(uint8_t *packet, int *errors, uint8_t fec)
|
|||
/* Testing is destructive, work on a copy */
|
||||
memcpy(pkt, packet, SSDV_PKT_SIZE);
|
||||
pkt[0] = 0x55;
|
||||
pkt[1] = 0x66;
|
||||
pkt[1] = 0x66 + type;
|
||||
|
||||
if(fec == 0)
|
||||
{
|
||||
if(errors) *errors = 0;
|
||||
}
|
||||
else if(fec == 1)
|
||||
switch(type)
|
||||
{
|
||||
case SSDV_TYPE_NORMAL:
|
||||
pkt_size_payload = SSDV_PKT_SIZE - SSDV_PKT_SIZE_HEADER - SSDV_PKT_SIZE_CRC - SSDV_PKT_SIZE_RSCODES;
|
||||
pkt_size_crcdata = SSDV_PKT_SIZE_HEADER + pkt_size_payload - 1;
|
||||
|
||||
/* Run the reed-solomon decoder */
|
||||
i = decode_rs_8(&pkt[1], 0, 0, 0);
|
||||
if(i < 0) return(-1); /* Reed-solomon decoder failed */
|
||||
if(errors) *errors = i;
|
||||
if(errors) *errors = 0;
|
||||
|
||||
break;
|
||||
|
||||
case SSDV_TYPE_NOFEC:
|
||||
pkt_size_payload = SSDV_PKT_SIZE - SSDV_PKT_SIZE_HEADER - SSDV_PKT_SIZE_CRC;
|
||||
pkt_size_crcdata = SSDV_PKT_SIZE_HEADER + pkt_size_payload - 1;
|
||||
|
||||
if(errors) *errors = 0;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "Invalid packet type\n");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* Sanity checks */
|
||||
if(pkt[1] != 0x66) return(-1);
|
||||
if(pkt[1] != 0x66 + type) return(-1);
|
||||
|
||||
ssdv_dec_header(&p, pkt);
|
||||
if(p.width == 0 || p.height == 0) return(-1);
|
||||
if(p.mcu_id != 0xFFFF)
|
||||
{
|
||||
if(p.mcu_id >= p.mcu_count) return(-1);
|
||||
if(p.mcu_offset >= SSDV_PKT_SIZE_PAYLOAD) return(-1);
|
||||
if(p.mcu_offset >= pkt_size_payload) return(-1);
|
||||
}
|
||||
|
||||
/* Test the checksum */
|
||||
x = crc32(&pkt[1], SSDV_PKT_SIZE_CRCDATA);
|
||||
x = crc32(&pkt[1], pkt_size_crcdata);
|
||||
|
||||
i = 1 + SSDV_PKT_SIZE_CRCDATA;
|
||||
i = 1 + pkt_size_crcdata;
|
||||
if(pkt[i++] != ((x >> 24) & 0xFF)) return(-1);
|
||||
if(pkt[i++] != ((x >> 16) & 0xFF)) return(-1);
|
||||
if(pkt[i++] != ((x >> 8) & 0xFF)) return(-1);
|
||||
|
@ -1329,8 +1364,3 @@ void ssdv_dec_header(ssdv_packet_info_t *info, uint8_t *packet)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
void ssdv_set_fec(ssdv_t *s, uint8_t fec)
|
||||
{
|
||||
s->fec = fec;
|
||||
}
|
||||
|
||||
|
|
19
ssdv.h
19
ssdv.h
|
@ -36,17 +36,21 @@ extern "C" {
|
|||
#define SSDV_PKT_SIZE_HEADER (0x0F)
|
||||
#define SSDV_PKT_SIZE_CRC (0x04)
|
||||
#define SSDV_PKT_SIZE_RSCODES (0x20)
|
||||
#define SSDV_PKT_SIZE_PAYLOAD (SSDV_PKT_SIZE - SSDV_PKT_SIZE_HEADER - SSDV_PKT_SIZE_CRC - SSDV_PKT_SIZE_RSCODES)
|
||||
#define SSDV_PKT_SIZE_CRCDATA (SSDV_PKT_SIZE_HEADER + SSDV_PKT_SIZE_PAYLOAD - 1)
|
||||
|
||||
#define TBL_LEN (546) /* Maximum size of the DQT and DHT tables */
|
||||
#define HBUFF_LEN (16) /* Extra space for reading marker data */
|
||||
//#define COMPONENTS (3)
|
||||
|
||||
#define SSDV_TYPE_NORMAL (0)
|
||||
#define SSDV_TYPE_NOFEC (1)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* Flags */
|
||||
uint8_t fec; /* 0 == None, 1 = RS8 */
|
||||
/* Packet type configuration */
|
||||
uint8_t type; /* 0 = Normal mode (224 byte packet + 32 bytes FEC),
|
||||
1 = No-FEC mode (256 byte packet) */
|
||||
uint16_t pkt_size_payload;
|
||||
uint16_t pkt_size_crcdata;
|
||||
|
||||
/* Image information */
|
||||
uint16_t width;
|
||||
|
@ -133,13 +137,13 @@ typedef struct {
|
|||
} ssdv_packet_info_t;
|
||||
|
||||
/* Encoding */
|
||||
extern char ssdv_enc_init(ssdv_t *s, char *callsign, uint8_t image_id);
|
||||
extern char ssdv_enc_init(ssdv_t *s, uint8_t type, char *callsign, uint8_t image_id);
|
||||
extern char ssdv_enc_set_buffer(ssdv_t *s, uint8_t *buffer);
|
||||
extern char ssdv_enc_get_packet(ssdv_t *s);
|
||||
extern char ssdv_enc_feed(ssdv_t *s, uint8_t *buffer, size_t length);
|
||||
|
||||
/* Decoding */
|
||||
extern char ssdv_dec_init(ssdv_t *s);
|
||||
extern char ssdv_dec_init(ssdv_t *s, uint8_t type);
|
||||
extern char ssdv_dec_set_buffer(ssdv_t *s, uint8_t *buffer, size_t length);
|
||||
extern char ssdv_dec_feed(ssdv_t *s, uint8_t *packet);
|
||||
extern char ssdv_dec_get_jpeg(ssdv_t *s, uint8_t **jpeg, size_t *length);
|
||||
|
@ -147,9 +151,6 @@ extern char ssdv_dec_get_jpeg(ssdv_t *s, uint8_t **jpeg, size_t *length);
|
|||
extern char ssdv_dec_is_packet(uint8_t *packet, int *errors, uint8_t fec);
|
||||
extern void ssdv_dec_header(ssdv_packet_info_t *info, uint8_t *packet);
|
||||
|
||||
/* Common */
|
||||
extern void ssdv_set_fec(ssdv_t *s, uint8_t fec);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue