diff --git a/conf/airframes/BR/bebop_default.xml b/conf/airframes/BR/bebop_default.xml index 45605c57bfd..a52a75cd8dd 100644 --- a/conf/airframes/BR/bebop_default.xml +++ b/conf/airframes/BR/bebop_default.xml @@ -33,11 +33,8 @@ + - - - - diff --git a/conf/airframes/BR/bebop_indi.xml b/conf/airframes/BR/bebop_indi.xml index 58a4961e872..f6741c78904 100644 --- a/conf/airframes/BR/bebop_indi.xml +++ b/conf/airframes/BR/bebop_indi.xml @@ -39,10 +39,7 @@ - - - - + diff --git a/conf/airframes/BR/bebop_indi_frog.xml b/conf/airframes/BR/bebop_indi_frog.xml index 2a3ccaed2da..7c713888f83 100644 --- a/conf/airframes/BR/bebop_indi_frog.xml +++ b/conf/airframes/BR/bebop_indi_frog.xml @@ -38,11 +38,8 @@ + - - - - diff --git a/conf/airframes/BR/bebop_indi_frog_flip.xml b/conf/airframes/BR/bebop_indi_frog_flip.xml index 58d495fda62..e2801ea5bea 100644 --- a/conf/airframes/BR/bebop_indi_frog_flip.xml +++ b/conf/airframes/BR/bebop_indi_frog_flip.xml @@ -38,11 +38,8 @@ + - - - - diff --git a/conf/airframes/CDW/bebop.xml b/conf/airframes/CDW/bebop.xml index 124bd5297e4..d9f1783b656 100644 --- a/conf/airframes/CDW/bebop.xml +++ b/conf/airframes/CDW/bebop.xml @@ -39,10 +39,7 @@ - - - - + diff --git a/conf/airframes/ENAC/quadrotor/ard2_base_digit.xml b/conf/airframes/ENAC/quadrotor/ard2_base_digit.xml index 80de02ddac9..ae0fd8395e6 100644 --- a/conf/airframes/ENAC/quadrotor/ard2_base_digit.xml +++ b/conf/airframes/ENAC/quadrotor/ard2_base_digit.xml @@ -36,7 +36,9 @@ - + + + diff --git a/conf/airframes/ENAC/quadrotor/ard2_base_vision.xml b/conf/airframes/ENAC/quadrotor/ard2_base_vision.xml index 77e4f376586..84bac7c4b12 100644 --- a/conf/airframes/ENAC/quadrotor/ard2_base_vision.xml +++ b/conf/airframes/ENAC/quadrotor/ard2_base_vision.xml @@ -36,7 +36,9 @@ - + + + diff --git a/conf/airframes/examples/ardrone2.xml b/conf/airframes/examples/ardrone2.xml index f901ed2b18b..0a6c2e9ec0c 100644 --- a/conf/airframes/examples/ardrone2.xml +++ b/conf/airframes/examples/ardrone2.xml @@ -32,7 +32,11 @@ - + diff --git a/conf/airframes/examples/bebop.xml b/conf/airframes/examples/bebop.xml index e988d250be7..cb1924ad225 100644 --- a/conf/airframes/examples/bebop.xml +++ b/conf/airframes/examples/bebop.xml @@ -33,10 +33,7 @@ - - - - + diff --git a/conf/modules/video_thread.xml b/conf/modules/video_thread.xml index af08272795e..11dbc2a9da1 100644 --- a/conf/modules/video_thread.xml +++ b/conf/modules/video_thread.xml @@ -3,16 +3,20 @@ - Video streaming for Linux devices + Read video in a thread. + Only for Linux devices. + To be used in other modules for further processing (e.g. opticflow, QR code, streaming). - - Sends a RTP/UDP stream of the camera - Possibility to save an image(shot) on the internal memory (JPEG, full size, best quality) - - - + + + + + + diff --git a/sw/airborne/boards/ardrone/board.c b/sw/airborne/boards/ardrone/board.c index 46b162fdaed..348994a52d0 100644 --- a/sw/airborne/boards/ardrone/board.c +++ b/sw/airborne/boards/ardrone/board.c @@ -36,21 +36,23 @@ #include "peripherals/video_device.h" -struct video_device_t front_camera = { +struct video_config_t front_camera = { .w = 1280, .h = 720, .dev_name = "/dev/video1", .subdev_name = NULL, .format = V4L2_PIX_FMT_UYVY, + .buf_cnt = 10, .filters = NULL }; -struct video_device_t bottom_camera = { +struct video_config_t bottom_camera = { .w = 320, .h = 240, .dev_name = "/dev/video2", .subdev_name = NULL, .format = V4L2_PIX_FMT_UYVY, + .buf_cnt = 10, .filters = NULL }; diff --git a/sw/airborne/boards/ardrone2.h b/sw/airborne/boards/ardrone2.h index 1e1c06d1df3..19b6c8f2bba 100644 --- a/sw/airborne/boards/ardrone2.h +++ b/sw/airborne/boards/ardrone2.h @@ -10,8 +10,8 @@ #endif /* Cameras */ -extern struct video_device_t bottom_camera; -extern struct video_device_t front_camera; +extern struct video_config_t bottom_camera; +extern struct video_config_t front_camera; /* Default actuators driver */ #define DEFAULT_ACTUATORS "boards/ardrone/actuators.h" diff --git a/sw/airborne/boards/bebop.h b/sw/airborne/boards/bebop.h index 3938e23d574..52bcfba76e9 100644 --- a/sw/airborne/boards/bebop.h +++ b/sw/airborne/boards/bebop.h @@ -37,8 +37,8 @@ #define ActuatorsDefaultCommit() ActuatorsBebopCommit() /* Cameras */ -extern struct video_device_t bottom_camera; -extern struct video_device_t front_camera; +extern struct video_config_t bottom_camera; +extern struct video_config_t front_camera; /* by default activate onboard baro */ #ifndef USE_BARO_BOARD diff --git a/sw/airborne/boards/bebop/video.c b/sw/airborne/boards/bebop/video.c index 938ed75a42c..f92c43f7e00 100644 --- a/sw/airborne/boards/bebop/video.c +++ b/sw/airborne/boards/bebop/video.c @@ -39,21 +39,23 @@ #include "boards/bebop.h" -struct video_device_t bottom_camera = { +struct video_config_t bottom_camera = { .w = 640, .h = 480, .dev_name = "/dev/video0", .subdev_name = NULL, .format = V4L2_PIX_FMT_UYVY, + .buf_cnt = 60, .filters = NULL }; -struct video_device_t front_camera = { +struct video_config_t front_camera = { .w = 1408, .h = 2112, .dev_name = "/dev/video1", .subdev_name = "/dev/v4l-subdev1", .format = V4L2_PIX_FMT_SGBRG10, + .buf_cnt = 80, .filters = NULL //{DeMosaic, AEC, ABW} }; diff --git a/sw/airborne/modules/computer_vision/video_thread.c b/sw/airborne/modules/computer_vision/video_thread.c index a2000879912..3d5135159b6 100644 --- a/sw/airborne/modules/computer_vision/video_thread.c +++ b/sw/airborne/modules/computer_vision/video_thread.c @@ -38,6 +38,10 @@ #include "lib/v4l/v4l2.h" #include "lib/vision/image.h" #include "lib/encoding/jpeg.h" +#include "peripherals/video_device.h" + +// include board for bottom_camera and front_camera on ARDrone2 and Bebop +#include BOARD_CONFIG #if JPEG_WITH_EXIF_HEADER #include "lib/exif/exif_module.h" @@ -47,25 +51,32 @@ #include #include "rt_priority.h" -// The video device -#ifndef VIDEO_THREAD_DEVICE -#define VIDEO_THREAD_DEVICE /dev/video1 -#endif -PRINT_CONFIG_VAR(VIDEO_THREAD_DEVICE) - -// The video device size (width, height) -#ifndef VIDEO_THREAD_DEVICE_SIZE -#define VIDEO_THREAD_DEVICE_SIZE 1280,720 -#endif -#define __SIZE_HELPER(x, y) #x", "#y -#define _SIZE_HELPER(x) __SIZE_HELPER(x) -PRINT_CONFIG_MSG("VIDEO_THREAD_DEVICE_SIZE = " _SIZE_HELPER(VIDEO_THREAD_DEVICE_SIZE)) - +/// The camera video config (usually bottom_camera or front_camera) +#ifndef VIDEO_THREAD_CAMERA +#warning "Are you sure you don't want to use the bottom_camera or front_camera?" // The video device buffers (the amount of V4L2 buffers) #ifndef VIDEO_THREAD_DEVICE_BUFFERS #define VIDEO_THREAD_DEVICE_BUFFERS 10 #endif PRINT_CONFIG_VAR(VIDEO_THREAD_DEVICE_BUFFERS) +#ifndef VIDEO_THREAD_SUBDEV +#define VIDEO_THREAD_SUBDEV NULL +#endif +#ifndef VIDEO_THREAD_FILTERS +#define VIDEO_THREAD_FILTERS NULL +#endif +struct video_config_t custom_camera = { + .w = VIDEO_THREAD_VIDEO_WIDTH, + .h = VIDEO_THREAD_VIDEO_HEIGHT, + .dev_name = STRINGIFY(VIDEO_THREAD_DEVICE), + .subdev_name = VIDEO_THREAD_SUBDEV, + .buf_cnt = VIDEO_THREAD_DEVICE_BUFFERS, + .filters = VIDEO_THREAD_FILTERS +}; +#define VIDEO_THREAD_CAMERA custom_camera +#endif +PRINT_CONFIG_VAR(VIDEO_THREAD_CAMERA) + // Frames Per Seconds #ifndef VIDEO_THREAD_FPS @@ -95,8 +106,26 @@ struct video_thread_t video_thread = { * Handles all the video streaming and saving of the image shots * This is a sepereate thread, so it needs to be thread safe! */ -static void *video_thread_function(void *data __attribute__((unused))) +static void *video_thread_function(void *data) { + struct video_config_t *vid = (struct video_config_t *)data; + + // Initialize the V4L2 subdevice if needed + if (vid->subdev_name != NULL) { + if (!v4l2_init_subdev(vid->subdev_name, 0, 1, vid->format, vid->w, vid->h)) { + printf("[video_thread] Could not initialize the %s subdevice.\n", vid->subdev_name); + return 0; + } + } + + // Initialize the V4L2 device + video_thread.dev = v4l2_init(vid->dev_name, vid->w, vid->h, vid->buf_cnt, vid->format); + if (video_thread.dev == NULL) { + printf("[video_thread] Could not initialize the %s V4L2 device.\n", vid->dev_name); + return 0; + } + + // Start the streaming of the V4L2 device if (!v4l2_start_capture(video_thread.dev)) { printf("[video_thread-thread] Could not start capture of %s.\n", video_thread.dev->name); @@ -176,24 +205,6 @@ static void *video_thread_function(void *data __attribute__((unused))) */ void video_thread_init(void) { -#ifdef VIDEO_THREAD_SUBDEV - PRINT_CONFIG_MSG("[video_thread] Configuring a subdevice!") - PRINT_CONFIG_VAR(VIDEO_THREAD_SUBDEV) - - // Initialize the V4L2 subdevice (TODO: fix hardcoded path, which and code) - if (!v4l2_init_subdev(STRINGIFY(VIDEO_THREAD_SUBDEV), 0, 1, V4L2_MBUS_FMT_UYVY8_2X8, VIDEO_THREAD_DEVICE_SIZE)) { - printf("[video_thread] Could not initialize the %s subdevice.\n", STRINGIFY(VIDEO_THREAD_SUBDEV)); - return; - } -#endif - - // Initialize the V4L2 device - video_thread.dev = v4l2_init(STRINGIFY(VIDEO_THREAD_DEVICE), VIDEO_THREAD_DEVICE_SIZE, VIDEO_THREAD_DEVICE_BUFFERS, V4L2_PIX_FMT_UYVY); - if (video_thread.dev == NULL) { - printf("[video_thread] Could not initialize the %s V4L2 device.\n", STRINGIFY(VIDEO_THREAD_DEVICE)); - return; - } - // Create the shot directory char save_name[128]; sprintf(save_name, "mkdir -p %s", STRINGIFY(VIDEO_THREAD_SHOT_PATH)); @@ -215,7 +226,7 @@ void video_thread_start(void) // Start the streaming thread pthread_t tid; - if (pthread_create(&tid, NULL, video_thread_function, NULL) != 0) { + if (pthread_create(&tid, NULL, video_thread_function, (void*)(&VIDEO_THREAD_CAMERA)) != 0) { printf("[vievideo] Could not create streaming thread.\n"); return; } diff --git a/sw/airborne/peripherals/video_device.h b/sw/airborne/peripherals/video_device.h index c45d4245dbd..01304befc60 100644 --- a/sw/airborne/peripherals/video_device.h +++ b/sw/airborne/peripherals/video_device.h @@ -32,12 +32,13 @@ #include "modules/computer_vision/lib/v4l/v4l2.h" /** V4L2 device settings */ -struct video_device_t { +struct video_config_t { int w; ///< Width int h; ///< Height char* dev_name; ///< path to device char* subdev_name; ///< path to sub device uint32_t format; ///< Video format + uint8_t buf_cnt; ///< Amount of V4L2 video device buffers void* filters; ///< filters to use };