diff --git a/conf/modules/video_rtp_stream.xml b/conf/modules/video_rtp_stream.xml
index cc82f6f2020..8f0241807d4 100644
--- a/conf/modules/video_rtp_stream.xml
+++ b/conf/modules/video_rtp_stream.xml
@@ -15,6 +15,7 @@
+
diff --git a/sw/airborne/modules/computer_vision/viewvideo.c b/sw/airborne/modules/computer_vision/viewvideo.c
index 25f43fec33b..45b1d397a49 100644
--- a/sw/airborne/modules/computer_vision/viewvideo.c
+++ b/sw/airborne/modules/computer_vision/viewvideo.c
@@ -94,10 +94,12 @@ PRINT_CONFIG_VAR(VIEWVIDEO_FPS);
PRINT_CONFIG_VAR(VIEWVIDEO_SHOT_PATH);
// Check if we are using netcat instead of RTP/UDP
-#ifdef VIEWVIDEO_USE_NC
+#ifndef VIEWVIDEO_USE_NETCAT
+#define VIEWVIDEO_USE_NETCAT FALSE
+#endif
+#if VIEWVIDEO_USE_NETCAT
PRINT_CONFIG_MSG("[viewvideo] Using netcat.");
#else
-#define VIEWVIDEO_USE_NC FALSE
PRINT_CONFIG_MSG("[viewvideo] Using RTP/UDP stream.");
PRINT_CONFIG_VAR(VIEWVIDEO_DEV);
#endif
@@ -143,14 +145,19 @@ static void *viewvideo_thread(void *data __attribute__((unused)))
small.buf = NULL;
}
- // JPEG compression (8.25 bits are required for a 100% quality image)
- uint8_t *jpegbuf = (uint8_t *)malloc(ceil(small.w * small.h * (8.25 / 8.)));
+ // JPEG compression (8.25 bits are required for a 100% quality image, margin of ~0.55)
+ uint8_t *jpegbuf = (uint8_t *)malloc(ceil(small.w * small.h * 1.1));
// time
uint32_t microsleep = (uint32_t)(1000000. / (float)viewvideo.fps);
struct timeval last_time;
gettimeofday(&last_time, NULL);
+#if VIEWVIDEO_USE_NETCAT
+ char nc_cmd[64];
+ sprintf(nc_cmd, "nc %s %d 2>/dev/null", VIEWVIDEO_HOST, VIEWVIDEO_PORT_OUT);
+#endif
+
// Start streaming
viewvideo.is_streaming = TRUE;
while (viewvideo.is_streaming) {
@@ -167,7 +174,7 @@ static void *viewvideo_thread(void *data __attribute__((unused)))
// Check if we need to take a shot
if (viewvideo.take_shot) {
// Create a high quality image (99% JPEG encoded)
- uint8_t *jpegbuf_hr = (uint8_t *)malloc(ceil(viewvideo.dev->w * viewvideo.dev->h * (8.25 / 8.)));
+ uint8_t *jpegbuf_hr = (uint8_t *)malloc(ceil(viewvideo.dev->w * viewvideo.dev->h * 1.1));
uint8_t *end = jpeg_encode_image(img->buf, jpegbuf_hr, 99, FOUR_TWO_TWO, viewvideo.dev->w, viewvideo.dev->h, TRUE);
uint32_t size = end - (jpegbuf_hr);
@@ -208,19 +215,32 @@ static void *viewvideo_thread(void *data __attribute__((unused)))
}
// JPEG encode the image:
- uint8_t *end = jpeg_encode_image(small.buf, jpegbuf, VIEWVIDEO_QUALITY_FACTOR, FOUR_TWO_TWO, small.w, small.h, VIEWVIDEO_USE_NC);
+ uint8_t *end = jpeg_encode_image(small.buf, jpegbuf, VIEWVIDEO_QUALITY_FACTOR, FOUR_TWO_TWO, small.w, small.h, VIEWVIDEO_USE_NETCAT);
uint32_t size = end - (jpegbuf);
-#if VIEWVIDEO_USE_NC
- // Open process to send using netcat
- char nc_cmd[64];
- sprintf(nc_cmd, "nc %s %d 2>/dev/null", VIEWVIDEO_HOST, VIEWVIDEO_PORT_OUT);
- FILE *netcat = popen(nc_cmd, "w");
- if (netcat != NULL) {
- fwrite(jpegbuf, sizeof(uint8_t), size, netcat);
- pclose(netcat); // Ignore output, because it is too much when not connected
- } else {
- printf("[viewvideo] Failed to open netcat process.\n");
+#if VIEWVIDEO_USE_NETCAT
+ // Open process to send using netcat (in a fork because sometimes kills itself???)
+ pid_t pid = fork();
+
+ if(pid < 0) {
+ printf("[viewvideo] Could not create netcat fork.\n");
+ }
+ else if(pid ==0) {
+ // We are the child and want to send the image
+ FILE *netcat = popen(nc_cmd, "w");
+ if (netcat != NULL) {
+ fwrite(jpegbuf, sizeof(uint8_t), size, netcat);
+ pclose(netcat); // Ignore output, because it is too much when not connected
+ } else {
+ printf("[viewvideo] Failed to open netcat process.\n");
+ }
+
+ // Exit the program since we don't want to continue after transmitting
+ exit(0);
+ }
+ else {
+ // We want to wait until the child is finished
+ wait(NULL);
}
#else
// Send image with RTP
@@ -246,6 +266,11 @@ static void *viewvideo_thread(void *data __attribute__((unused)))
// Free the image
v4l2_image_free(viewvideo.dev, img);
}
+
+ // Free all buffers
+ free(jpegbuf);
+ if (viewvideo.downsize_factor != 1)
+ free(small.buf);
return 0;
}
@@ -280,7 +305,7 @@ void viewvideo_init(void)
return;
}
-#ifdef VIEWVIDEO_USE_NC
+#if VIEWVIDEO_USE_NETCAT
// Create an Netcat receiver file for the streaming
sprintf(save_name, "%s/netcat-recv.sh", VIEWVIDEO_SHOT_PATH);
FILE *fp = fopen(save_name, "w");