- image command and python script rolled in from webcam_dev branch
- further WIP on SSDV buffer full handling (more to do)
Development
bob 2018-09-30 14:00:31 +10:00
rodzic 50091cbe78
commit eb0aad1f70
6 zmienionych plików z 72 dodań i 68 usunięć

Wyświetl plik

@ -30,9 +30,9 @@ with serial.Serial(port='/dev/ttyACM1') as ser:
i=0
while True:
line = ser.readline()
m = re.search("\[(.*)\]\[(.*)\] DATA \> image\/jpeg\,(.*)", line)
m = re.search("DATA \> image\/jpeg\,(.*)", line)
try:
size = m.group(3)
size = m.group(1)
except:
print line.strip()
continue

Wyświetl plik

@ -50,7 +50,7 @@ const conf_t conf_flash_default = {
.cca = 0x4F
},
// App identity
.call = "VK2GJ-11",
.call = "VK2GJ-2",
.path = "WIDE2-1",
.symbol = SYM_ANTENNA,
.aprs_msg = false, // Enable APRS message reception on this app
@ -86,9 +86,9 @@ const conf_t conf_flash_default = {
.img_sec = {
.svc_conf = {
.active = true,
.cycle = TIME_S2I(60 * 15),
.cycle = TIME_S2I(60 * 2),
.init_delay = TIME_S2I(10),
.send_spacing = TIME_S2I(2)
.send_spacing = TIME_S2I(5)
},
.radio_conf = {
.pwr = 0x7F,
@ -97,7 +97,7 @@ const conf_t conf_flash_default = {
.cca = 0x5F
},
// App identity
.call = "VK2GJ-11",
.call = "VK2GJ-2",
.path = "",
// Image settings
@ -138,7 +138,7 @@ const conf_t conf_flash_default = {
// If there is no cycle time or interval then run continuously.
// If there is a duration only then it is a run once setup.
// The APRS schedule thread terminates and leaves the radio active.
// If duration is TIME_INFINITE then the radio stay active while the thread waits forever.
// If duration is TIME_INFINITE then the radio stays active while the thread waits forever.
.active = true,
.init_delay = TIME_S2I(20),
.cycle = TIME_S2I(60 * 10),

Wyświetl plik

@ -124,8 +124,8 @@ void usb_cmd_set_trace_level(BaseSequentialStream *chp, int argc, char *argv[])
void usb_cmd_printPicture(BaseSequentialStream *chp, int argc, char *argv[])
{
(void)argc;
(void)argv;
(void)argc;
(void)argv;
/*
* Take picture.
@ -134,40 +134,40 @@ void usb_cmd_printPicture(BaseSequentialStream *chp, int argc, char *argv[])
* MSG_RESET = no camera found
* MSG_TIMEOUT = capture failed.
*/
size_t size_sampled;
msg_t msg = takePicture(usb_buffer, sizeof(usb_buffer), RES_QVGA,
&size_sampled, false);
size_t size_sampled;
msg_t msg = takePicture(usb_buffer, sizeof(usb_buffer), RES_QVGA,
&size_sampled, false);
// Transmit image via USB
if(size_sampled && msg == MSG_OK)
{
bool start_detected = false;
for(uint32_t i=0; i<size_sampled; i++)
{
// Look for APP0 instead of SOI because SOI is lost sometimes, but we can add SOI easily later on
if(!start_detected && usb_buffer[i] == 0xFF && usb_buffer[i+1] == 0xE0) {
start_detected = true;
TRACE_INFO("DATA > image/jpeg,%d", size_sampled-i+2); // Flag the data on serial output
streamPut(chp, 0xFF);
streamPut(chp, 0xD8);
}
if(start_detected)
streamPut(chp, usb_buffer[i]);
}
if(!start_detected)
{
TRACE_INFO("DATA > image/jpeg,0");
TRACE_INFO("DATA > text/trace,no SOI flag found");
return;
}
// Transmit image via USB
if(size_sampled)
{
bool start_detected = false;
for(uint32_t i=0; i<size_sampled; i++)
{
// Look for APP0 instead of SOI because SOI is lost sometimes, but we can add SOI easily later on
if(!start_detected && usb_buffer[i] == 0xFF && usb_buffer[i+1] == 0xE0) {
start_detected = true;
chprintf(chp, "DATA > image/jpeg,%d\r\n", size_sampled-i+2); // Flag the data on serial output
streamPut(chp, 0xFF);
streamPut(chp, 0xD8);
}
if(start_detected)
streamPut(chp, usb_buffer[i]);
}
if(!start_detected)
{
chprintf(chp, "DATA > image/jpeg,0\r\n");
chprintf(chp, "DATA > text/trace,no SOI flag found\r\n");
return;
}
} else if(msg == MSG_RESET) { // Camera error
TRACE_INFO("DATA > image,jpeg,0");
TRACE_INFO("DATA > error,no camera found");
return;
} /* MSG_TIMEOUT. */
TRACE_INFO("DATA > image,jpeg,0");
TRACE_INFO("DATA > error,capture failed");
} else if(msg == MSG_RESET) { // Camera error
chprintf(chp, "DATA > image,jpeg,0\r\n");
chprintf(chp, "DATA > error,no camera found\r\n");
return;
} /* MSG_TIMEOUT. */
chprintf(chp, "DATA > image,jpeg,0\r\n");
chprintf(chp, "DATA > error,capture failed\r\n");
return;
}

Wyświetl plik

@ -386,7 +386,7 @@ static char ssdv_outbits(ssdv_t *s, uint16_t bits, uint8_t length)
/* Insert stuffing byte if needed */
if(s->out_stuff && b == 0xFF)
{
s->outbits &= (1 << s->outlen) - 1;
s->outbits <<= 8;
s->outlen += 8;
}
}
@ -413,13 +413,14 @@ static char ssdv_out_jpeg_int(ssdv_t *s, uint8_t rle, int value)
if(r != SSDV_OK) {
TRACE_ERROR("SSDV > jpeg_dht_lookup_symbol: %i (%i:%i)", r, value, rle);
return SSDV_ERROR;
return(SSDV_ERROR);
}
ssdv_outbits(s, huffbits, hufflen);
if(intlen) ssdv_outbits(s, intbits, intlen);
return(SSDV_OK);
r = ssdv_outbits(s, huffbits, hufflen);
if(intlen && r == SSDV_OK) {
r = ssdv_outbits(s, intbits, intlen);
}
return(r);
}
static char ssdv_process(ssdv_t *s)
@ -461,7 +462,6 @@ static char ssdv_process(ssdv_t *s)
else r = ssdv_out_jpeg_int(s, 0, 0);
/* skip to the next AC part immediately */
s->acpart++;
if(r != SSDV_OK) return(r);
}
else
{
@ -494,10 +494,10 @@ static char ssdv_process(ssdv_t *s)
s->needbits = symbol & 0x0F;
}
}
/* Clear processed bits */
s->worklen -= width;
s->workbits &= (1 << s->worklen) - 1;
if(r != SSDV_OK) return(r);
break;
}
@ -528,7 +528,6 @@ static char ssdv_process(ssdv_t *s)
r = ssdv_out_jpeg_int(s, 0, i - s->dc[s->component]);
s->dc[s->component] = i;
}
if(r != SSDV_OK) return(r);
}
else
{
@ -547,7 +546,6 @@ static char ssdv_process(ssdv_t *s)
r = ssdv_out_jpeg_int(s, 0, i - s->adc[s->component]);
s->adc[s->component] = i;
}
if(r != SSDV_OK) return(r);
}
}
else /* AC */
@ -559,11 +557,9 @@ static char ssdv_process(ssdv_t *s)
{
r = ssdv_out_jpeg_int(s, 15, 0);
s->accrle -= 16;
if(r != SSDV_OK) return(r);
}
r = ssdv_out_jpeg_int(s, s->accrle, i);
s->accrle = 0;
if(r != SSDV_OK) return(r);
}
else
{
@ -572,7 +568,6 @@ static char ssdv_process(ssdv_t *s)
{
r = ssdv_out_jpeg_int(s, 0, 0);
s->accrle = 0;
if(r != SSDV_OK) return(r);
}
else s->accrle += s->acrle + 1;
}
@ -589,8 +584,10 @@ static char ssdv_process(ssdv_t *s)
s->workbits &= (1 << s->worklen) - 1;
break;
}
default:
break;
} /* End switch on state. */
if(s->acpart >= 64)
{
@ -603,9 +600,8 @@ static char ssdv_process(ssdv_t *s)
{
s->component = s->mcupart - s->ycparts + 1;
s->acpart = 0; r = ssdv_out_jpeg_int(s, 0, 0); /* DC */
if(r != SSDV_OK) return(SSDV_ERROR);
/* Should handle buffer full but doesn't. */
s->acpart = 1; r = ssdv_out_jpeg_int(s, 0, 0); /* AC */
if(r != SSDV_OK) return(SSDV_ERROR);
}
}
@ -999,7 +995,7 @@ char ssdv_enc_get_packet(ssdv_t *s)
/* Skip bytes if necessary */
if(s->in_skip) { s->in_skip--; continue; }
r = SSDV_OK;
switch(s->state)
{
case S_MARKER:
@ -1116,6 +1112,7 @@ char ssdv_enc_get_packet(ssdv_t *s)
/* Have we reached the end of the image data? */
if(r == SSDV_EOI) s->state = S_EOI;
/* Return SSDV_EOI or SSDV_BUFFER_FULL */
return(r);
}
else if(r != SSDV_FEED_ME)
@ -1129,8 +1126,9 @@ char ssdv_enc_get_packet(ssdv_t *s)
case S_EOI:
/* Shouldn't reach this point */
break;
}
}
} /* End switch on state */
if(r == SSDV_BUFFER_FULL) return(r);
} /* End while in_len */
/* Need more data */
return(SSDV_FEED_ME);
@ -1145,14 +1143,19 @@ char ssdv_enc_feed(ssdv_t *s, const uint8_t *buffer, size_t length)
/*****************************************************************************/
static void ssdv_write_marker(ssdv_t *s, uint16_t id, uint16_t length, const uint8_t *data)
static char ssdv_write_marker(ssdv_t *s, uint16_t id, uint16_t length, const uint8_t *data)
{
ssdv_outbits(s, id, 16);
if(length > 0)
int r;
r = ssdv_outbits(s, id, 16);
if(length > 0 && r == SSDV_OK)
{
ssdv_outbits(s, length + 2, 16);
while(length--) ssdv_outbits(s, *(data++), 8);
if(ssdv_outbits(s, length + 2, 16) != SSDV_OK)
return(SSDV_ERROR);
do {
r = ssdv_outbits(s, *(data++), 8);
} while(--length && r == SSDV_OK);
}
return(length == 0 ? r : SSDV_ERROR);
}
static void ssdv_out_headers(ssdv_t *s)
@ -1350,6 +1353,7 @@ char ssdv_dec_feed(ssdv_t *s, uint8_t *packet)
/* Fill the gap left by the missing packet */
ssdv_fill_gap(s, s->packet_mcu_id);
/* Skip the bytes of the lost MCU */
i = s->packet_mcu_offset;

Wyświetl plik

@ -625,7 +625,7 @@ THD_FUNCTION(collectorThread, arg) {
TRACE_TAB, time.year, time.month, time.day, time.hour, time.minute, time.day,
TRACE_TAB, tp->gps_lat/10000000, (tp->gps_lat > 0 ? 1:-1)*(tp->gps_lat/100)%100000, tp->gps_lon/10000000, (tp->gps_lon > 0 ? 1:-1)*(tp->gps_lon/100)%100000, tp->gps_alt,
TRACE_TAB, tp->gps_sats, tp->gps_ttff,
TRACE_TAB, tp->adc_vbat/1000, (tp->adc_vbat%1000), tp->adc_vsol/1000, (tp->adc_vsol%1000), tp->pac_pbat,
TRACE_TAB, tp->adc_vbat/1000, (tp->adc_vbat%1000), tp->adc_vsol/1000, (tp->adc_vsol%1000), tp->pac_pbat / 10,
TRACE_TAB, tp->sen_i1_press/10, tp->sen_i1_press%10, tp->sen_i1_temp/100, tp->sen_i1_temp%100, tp->sen_i1_hum/10, tp->sen_i1_hum%10,
TRACE_TAB, tp->gpio & 1, (tp->gpio >> 1) & 1, (tp->gpio >> 2) & 1, (tp->gpio >> 3) & 1,
TRACE_TAB, config->call

Wyświetl plik

@ -1000,7 +1000,6 @@ static bool send_image_packets(const uint8_t *image,
case SSDV_EOI:
case SSDV_BUFFER_FULL: {
//bi += sizeof(pkt);
/*
* Have a full SSDV buffer to encode and send or an EOI.
* Sync byte, CRC and FEC of SSDV not transmitted.
@ -1036,6 +1035,7 @@ static bool send_image_packets(const uint8_t *image,
}
default: {
/* TODO: Check c and handle case of SSDV_ERROR versus other states. */
TRACE_ERROR("CAM > Error in image (ssdv_enc_get_packet failed:"
" %d at %d of %d)",
c, (image_len - ssdv.in_len), image_len);
@ -1096,7 +1096,7 @@ static bool send_image_packets(const uint8_t *image,
&& conf->redundantTx) {
/* Wait for packet to be available. */
if(chSemWait(&tx_complete) == MSG_RESET)
return false;
return false;
packet_t packet = aprs_encode_data_packet(conf->call, conf->path,
'I', pkt_base91);
if(packet == NULL) {
@ -1402,7 +1402,7 @@ THD_FUNCTION(imgThread, arg) {
void start_image_thread(img_app_conf_t *conf, const char *name)
{
thread_t *th = chThdCreateFromHeap(NULL,
THD_WORKING_AREA_SIZE(8 * 1024),
THD_WORKING_AREA_SIZE(9 * 1024),
name, LOWPRIO, imgThread, conf);
if(!th) {
// Print startup error, do not start watchdog for this thread