From 22d912f7de5c1369cce51b925258555eea1c804b Mon Sep 17 00:00:00 2001 From: Philip Heron Date: Wed, 27 Aug 2014 23:49:25 +0100 Subject: [PATCH] Add an option to encode/decode without FEC --- main.c | 15 ++++++++++----- ssdv.c | 26 ++++++++++++++++++++------ ssdv.h | 8 +++++++- 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/main.c b/main.c index f42f43b..4629b44 100644 --- a/main.c +++ b/main.c @@ -25,7 +25,7 @@ void exit_usage() { - fprintf(stderr, "Usage: ssdv [-e|-d] [-t ] [-c ] [-i ] [] []\n"); + fprintf(stderr, "Usage: ssdv [-e|-d] [-n] [-t ] [-c ] [-i ] [] []\n"); exit(-1); } @@ -35,6 +35,7 @@ int main(int argc, char *argv[]) FILE *fin = stdin; FILE *fout = stdout; char encode = -1; + char fec = -1; int droptest = 0; char callsign[7]; uint8_t image_id = 0; @@ -46,12 +47,13 @@ int main(int argc, char *argv[]) callsign[0] = '\0'; opterr = 0; - while((c = getopt(argc, argv, "edc:i:t:")) != -1) + while((c = getopt(argc, argv, "ednc:i:t:")) != -1) { switch(c) { case 'e': encode = 1; break; case 'd': encode = 0; break; + case 'n': fec = 0; break; case 'c': if(strlen(optarg) > 6) fprintf(stderr, "Warning: callsign is longer than 6 characters.\n"); @@ -105,14 +107,16 @@ int main(int argc, char *argv[]) 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, SSDV_PKT_SIZE, fin) > 0) + while(fread(pkt, 1, (fec ? SSDV_PKT_SIZE : SSDV_PKT_SIZE - SSDV_PKT_SIZE_RSCODES), 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) != 0) continue; + if(ssdv_dec_is_packet(pkt, NULL, (fec ? 1 : 0)) != 0) continue; /* Feed it to the decoder */ ssdv_dec_feed(&ssdv, pkt); @@ -130,6 +134,7 @@ int main(int argc, char *argv[]) case 1: /* Encode */ ssdv_enc_init(&ssdv, callsign, image_id); ssdv_enc_set_buffer(&ssdv, pkt); + ssdv_set_fec(&ssdv, (fec ? 1 : 0)); i = 0; @@ -158,7 +163,7 @@ int main(int argc, char *argv[]) return(-1); } - fwrite(pkt, 1, SSDV_PKT_SIZE, fout); + fwrite(pkt, 1, (fec ? SSDV_PKT_SIZE : SSDV_PKT_SIZE - SSDV_PKT_SIZE_RSCODES), fout); i++; } diff --git a/ssdv.c b/ssdv.c index eb044df..bc7ccef 100644 --- a/ssdv.c +++ b/ssdv.c @@ -820,6 +820,7 @@ char ssdv_enc_init(ssdv_t *s, char *callsign, uint8_t image_id) s->image_id = image_id; s->callsign = encode_callsign(callsign); s->mode = S_ENCODING; + s->fec = 1; /* Prepare the output JPEG tables */ s->ddqt[0] = dtblcpy(s, std_dqt0, sizeof(std_dqt0)); @@ -970,7 +971,7 @@ char ssdv_enc_get_packet(ssdv_t *s) s->out[i++] = x & 0xFF; /* Generate the RS codes */ - encode_rs_8(&s->out[1], &s->out[i], 0); + if(s->fec == 1) encode_rs_8(&s->out[1], &s->out[i], 0); s->packet_id++; @@ -1100,6 +1101,7 @@ char ssdv_dec_init(ssdv_t *s) /* The packet data should contain only scan data, no headers */ s->state = S_HUFF; s->mode = S_DECODING; + s->fec = 1; /* Prepare the source JPEG tables */ s->sdqt[0] = stblcpy(s, std_dqt0, sizeof(std_dqt0)); @@ -1260,7 +1262,7 @@ 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) +char ssdv_dec_is_packet(uint8_t *packet, int *errors, uint8_t fec) { uint8_t pkt[SSDV_PKT_SIZE]; ssdv_packet_info_t p; @@ -1272,10 +1274,17 @@ char ssdv_dec_is_packet(uint8_t *packet, int *errors) pkt[0] = 0x55; pkt[1] = 0x66; - /* 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(fec == 0) + { + if(errors) *errors = 0; + } + else if(fec == 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; + } /* Sanity checks */ if(pkt[1] != 0x66) return(-1); @@ -1320,3 +1329,8 @@ 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; +} + diff --git a/ssdv.h b/ssdv.h index e0462e5..e10d5d9 100644 --- a/ssdv.h +++ b/ssdv.h @@ -45,6 +45,9 @@ extern "C" { typedef struct { + /* Flags */ + uint8_t fec; /* 0 == None, 1 = RS8 */ + /* Image information */ uint16_t width; uint16_t height; @@ -141,9 +144,12 @@ 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); -extern char ssdv_dec_is_packet(uint8_t *packet, int *errors); +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