mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-05-24 13:55:51 +08:00
remove non used bebop front cam module, fix cropping in pixel skip, fix isp statistics config, fix rtp streaming hanging
This commit is contained in:
@@ -17,9 +17,9 @@
|
||||
<define name="MT9F002_GAIN_GREEN2" value="4"/>
|
||||
<define name="MT9F002_GAIN_RED" value="5"/>
|
||||
<define name="MT9F002_GAIN_BLUE" value="5"/>
|
||||
<define name="MT9F002_OUTPUT_SCALER" value="1."/>
|
||||
<define name="MT9F002_X_ODD_INC_VAL" value="7"/>
|
||||
<define name="MT9F002_Y_ODD_INC_VAL" value="7"/>
|
||||
<define name="MT9F002_OUTPUT_SCALER" value="0.25"/>
|
||||
<define name="MT9F002_X_ODD_INC_VAL" value="1"/>
|
||||
<define name="MT9F002_Y_ODD_INC_VAL" value="1"/>
|
||||
|
||||
<!--define name="USE_SONAR" value="TRUE"/-->
|
||||
|
||||
@@ -50,9 +50,6 @@
|
||||
<define name="VIEWVIDEO_CAMERA2" value="front_camera"/>
|
||||
<define name="VIEWVIDEO_DOWNSIZE_FACTOR" value="2"/>
|
||||
<define name="VIEWVIDEO_QUALITY_FACTOR" value="40"/>
|
||||
|
||||
<configure name="VIEWVIDEO_BROADCAST" value="TRUE"/>
|
||||
<configure name="VIEWVIDEO_HOST" value="192.168.42.98"/>
|
||||
</module>
|
||||
|
||||
<module name="cv_ae_awb"/>
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
<!DOCTYPE module SYSTEM "module.dtd">
|
||||
|
||||
<module name="bebop_front_camera" dir="computer_vision">
|
||||
<doc>
|
||||
<description>
|
||||
Video streaming for the Bebop front camera
|
||||
|
||||
</description>
|
||||
<define name="BEBOP_FRONT_CAMERA_SHOT_PATH" value="/data/ftp/internal_000/images" description="Path where the images should be saved"/>
|
||||
<configure name="BEBOP_FRONT_CAMERA_HOST" value="192.168.1.255" description="GCS IP (default: MODEM_HOST)"/>
|
||||
<configure name="BEBOP_FRONT_CAMERA_PORT_OUT" value="6000" description="Port (default: 5000)"/>
|
||||
<configure name="BEBOP_FRONT_CAMERA_BROADCAST" value="FALSE|TRUE" description="Enable broadcast of image stream (default: TRUE)"/>
|
||||
</doc>
|
||||
<settings>
|
||||
<dl_settings>
|
||||
<dl_settings name="video">
|
||||
<dl_setting var="bebop_front_camera.take_shot" min="0" step="1" max="1" shortname="take_shot" module="computer_vision/bebop_front_camera" handler="take_shot">
|
||||
<strip_button name="Shoot" icon="digital-camera.png" value="1" group="video"/>
|
||||
</dl_setting>
|
||||
</dl_settings>
|
||||
</dl_settings>
|
||||
</settings>
|
||||
|
||||
|
||||
<header>
|
||||
<file name="bebop_front_camera.h"/>
|
||||
</header>
|
||||
|
||||
<init fun="bebop_front_camera_init()"/>
|
||||
<periodic fun="bebop_front_camera_periodic()" freq="1" start="bebop_front_camera_start()" stop="bebop_front_camera_stop()" autorun="TRUE"/>
|
||||
<makefile target="ap">
|
||||
<file name="bebop_front_camera.c"/>
|
||||
|
||||
<!-- Include the needed Computer Vision files -->
|
||||
<include name="modules/computer_vision"/>
|
||||
<file name="image.c" dir="modules/computer_vision/lib/vision"/>
|
||||
<file name="v4l2.c" dir="modules/computer_vision/lib/v4l"/>
|
||||
<file name="jpeg.c" dir="modules/computer_vision/lib/encoding"/>
|
||||
<file name="rtp.c" dir="modules/computer_vision/lib/encoding"/>
|
||||
|
||||
<!-- Random flags -->
|
||||
<define name="__USE_GNU"/>
|
||||
<flag name="LDFLAGS" value="lrt"/>
|
||||
<flag name="LDFLAGS" value="static-libgcc"/>
|
||||
|
||||
<raw>
|
||||
include $(CFG_SHARED)/udp.makefile
|
||||
|
||||
BEBOP_FRONT_CAMERA_HOST ?= $(MODEM_HOST)
|
||||
BEBOP_FRONT_CAMERA_PORT_OUT ?= 6000
|
||||
BEBOP_FRONT_CAMERA_BROADCAST ?= TRUE
|
||||
|
||||
BEBOPVIEWVID_CFLAGS = -DBEBOP_FRONT_CAMERA_HOST=$(BEBOP_FRONT_CAMERA_HOST) -DBEBOP_FRONT_CAMERA_PORT_OUT=$(BEBOP_FRONT_CAMERA_PORT_OUT)
|
||||
ifeq ($(BEBOP_FRONT_CAMERA_USE_NETCAT),)
|
||||
ap.CFLAGS += $(BEBOPVIEWVID_CFLAGS) -DBEBOP_FRONT_CAMERA_BROADCAST=$(BEBOP_FRONT_CAMERA_BROADCAST)
|
||||
else
|
||||
ap.CFLAGS += $(BEBOPVIEWVID_CFLAGS) -DBEBOP_FRONT_CAMERA_USE_NETCAT
|
||||
endif
|
||||
</raw>
|
||||
|
||||
</makefile>
|
||||
<makefile target="nps">
|
||||
<file name="BEBOP_FRONT_CAMERA_nps.c"/>
|
||||
</makefile>
|
||||
</module>
|
||||
|
||||
@@ -29,79 +29,6 @@
|
||||
#include "peripherals/video_device.h"
|
||||
#include "boards/bebop/mt9f002.h"
|
||||
|
||||
/* define required ouput image size */
|
||||
#ifndef MT9F002_OUTPUT_HEIGHT
|
||||
#define MT9F002_OUTPUT_HEIGHT 822 // full resolution 3288
|
||||
#endif
|
||||
|
||||
#ifndef MT9F002_OUTPUT_WIDTH
|
||||
#define MT9F002_OUTPUT_WIDTH 1152 // full resolution 4608
|
||||
#endif
|
||||
|
||||
#ifndef MT9F002_INITIAL_OFFSET_X
|
||||
#define MT9F002_INITIAL_OFFSET_X 0. // signed fractional offset from centre of image of original sensor [-0.5,0.5]
|
||||
#endif
|
||||
|
||||
#ifndef MT9F002_INITIAL_OFFSET_Y
|
||||
#define MT9F002_INITIAL_OFFSET_Y 0. // signed fractional offset from centre of image of original sensor [-0.5,0.5]
|
||||
#endif
|
||||
|
||||
/** Our output is only OUTPUT_SCALER of the pixels we take of the sensor
|
||||
* It is programmable in 1/16 steps determined by ScaleFactor = 16/scale_m.
|
||||
* Legal values for scale_m are 16 through 128, giving you the ability to scale from
|
||||
* 1:1 to 1:8 (with m=128).
|
||||
* Example:
|
||||
* output_width = 512
|
||||
* output_height = 830
|
||||
* output_scaler = 0.25
|
||||
* We now get an image of 512 by 830 which contains a "compressed version"
|
||||
* of what would normally be an image of 2048 by 3320 ISP (4608H x 2592V sensor)
|
||||
*/
|
||||
#ifndef MT9F002_OUTPUT_SCALER
|
||||
#define MT9F002_OUTPUT_SCALER 1.
|
||||
#endif
|
||||
|
||||
/** Exposure of the front camera of the bebop. Experimental values:
|
||||
* Outside: 15
|
||||
* Inside well lit: 30
|
||||
* Inside poorly lit: 60
|
||||
*/
|
||||
#ifndef MT9F002_TARGET_EXPOSURE
|
||||
#define MT9F002_TARGET_EXPOSURE 30
|
||||
#endif
|
||||
|
||||
#ifndef MT9F002_TARGET_FPS
|
||||
#define MT9F002_TARGET_FPS 10
|
||||
#endif
|
||||
|
||||
/* Set the colour balance gains */
|
||||
#ifndef MT9F002_GAIN_GREEN1
|
||||
#define MT9F002_GAIN_GREEN1 3.0
|
||||
#endif
|
||||
|
||||
#ifndef MT9F002_GAIN_GREEN2
|
||||
#define MT9F002_GAIN_GREEN2 3.0
|
||||
#endif
|
||||
|
||||
#ifndef MT9F002_GAIN_RED
|
||||
#define MT9F002_GAIN_RED 3.0
|
||||
#endif
|
||||
|
||||
#ifndef MT9F002_GAIN_BLUE
|
||||
#define MT9F002_GAIN_BLUE 4.0
|
||||
#endif
|
||||
|
||||
/* Set pixel increment value to implement subsampling */
|
||||
/* Supported values for MT9F002_X_ODD_INC_VAL are 3, 7, 15 and 31 */
|
||||
#ifndef MT9F002_X_ODD_INC_VAL
|
||||
#define MT9F002_X_ODD_INC_VAL 1
|
||||
#endif
|
||||
|
||||
/* Supported values for MT9F002_Y_ODD_INC_VAL are 1, 3 and 7 */
|
||||
#ifndef MT9F002_Y_ODD_INC_VAL
|
||||
#define MT9F002_Y_ODD_INC_VAL 1
|
||||
#endif
|
||||
|
||||
/** uart connected to GPS internally */
|
||||
#define UART1_DEV /dev/ttyPA1
|
||||
#define GPS_UBX_ENABLE_NMEA_DATA_MASK 0xff
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "mt9f002_regs.h"
|
||||
#include "math/pprz_algebra_int.h"
|
||||
#include "boards/bebop.h"
|
||||
#include "modules/computer_vision/lib/isp/libisp.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
@@ -38,10 +39,10 @@
|
||||
#include <linux/videodev2.h>
|
||||
#include <linux/v4l2-mediabus.h>
|
||||
|
||||
#define MAX(x,y) (((x) > (y)) ? (x) : (y))
|
||||
#define MT9F002_MAX_WIDTH 4608
|
||||
#define MT9F002_MAX_HEIGHT 3288
|
||||
|
||||
#define MAX_WIDTH 4608
|
||||
#define MAX_HEIGHT 3288
|
||||
extern struct libisp_config isp_config;
|
||||
|
||||
/* Camera structure */
|
||||
struct video_config_t front_camera = {
|
||||
@@ -571,16 +572,16 @@ static void mt9f002_set_blanking(struct mt9f002_t *mt)
|
||||
|
||||
/* Calculate minimum line length */
|
||||
float subsampling_factor = (float)(1 + x_odd_inc) / 2.0f; // See page 52
|
||||
uint16_t min_line_length = MAX(min_line_length_pck,
|
||||
uint16_t min_line_length = Max(min_line_length_pck,
|
||||
mt->scaled_width / subsampling_factor + min_line_blanking_pck); // EQ 9
|
||||
min_line_length = MAX(min_line_length,
|
||||
min_line_length = Max(min_line_length,
|
||||
(mt->scaled_width - 1 + x_odd_inc) / subsampling_factor / 2 + min_line_blanking_pck);
|
||||
if (mt->interface == MT9F002_MIPI ||
|
||||
mt->interface == MT9F002_HiSPi) {
|
||||
min_line_length = MAX(min_line_length,
|
||||
min_line_length = Max(min_line_length,
|
||||
((uint16_t)((float)mt->scaled_width * mt->vt_pix_clk / mt->op_pix_clk) / 2) + 0x005E); // 2 lanes, pll clocks
|
||||
} else {
|
||||
min_line_length = MAX(min_line_length,
|
||||
min_line_length = Max(min_line_length,
|
||||
((uint16_t)((float)mt->scaled_width * mt->vt_pix_clk / mt->op_pix_clk)) + 0x005E); // pll clocks
|
||||
}
|
||||
|
||||
@@ -648,7 +649,6 @@ static void mt9f002_set_blanking(struct mt9f002_t *mt)
|
||||
}
|
||||
}
|
||||
|
||||
printf("line: %d, frame %d\n", mt->line_length, mt->frame_length);
|
||||
/* Actually set the calculated values */
|
||||
write_reg(mt, MT9F002_LINE_LENGTH_PCK, mt->line_length, 2);
|
||||
write_reg(mt, MT9F002_FRAME_LENGTH_LINES, mt->frame_length, 2);
|
||||
@@ -790,33 +790,34 @@ void mt9f002_set_resolution(struct mt9f002_t *mt)
|
||||
mt->output_scaler = (float)MT9F002_SCALER_N / scaleFactor;
|
||||
int x_skip_factor = (mt->x_odd_inc + 1) / 2;
|
||||
int y_skip_factor = (mt->y_odd_inc + 1) / 2;
|
||||
mt->scaled_width = mt->output_width * x_skip_factor / mt->output_scaler - mt->x_odd_inc + 1;
|
||||
mt->scaled_height = mt->output_height * y_skip_factor / mt->output_scaler - mt->y_odd_inc + 1;
|
||||
mt->scaled_width = mt->output_width * x_skip_factor / mt->output_scaler + mt->x_odd_inc - 1;
|
||||
mt->scaled_height = mt->output_height * y_skip_factor / mt->output_scaler + mt->y_odd_inc - 1;
|
||||
|
||||
if (mt->scaled_width % (x_skip_factor * 8) != 0) {
|
||||
mt->scaled_width = round(mt->scaled_width / (x_skip_factor * 8)) * (x_skip_factor * 8);
|
||||
mt->scaled_width = floor(mt->scaled_width / (x_skip_factor * 8)) * (x_skip_factor * 8);
|
||||
printf("[MT9F002] Warning, scaled_width not a multiple of %i, changing to %i\n", 8 * x_skip_factor, mt->scaled_width);
|
||||
}
|
||||
if (mt->scaled_height % (y_skip_factor * 8) != 0) {
|
||||
mt->scaled_height = round(mt->scaled_height / (y_skip_factor * 8)) * (y_skip_factor * 8);
|
||||
mt->scaled_height = floor(mt->scaled_height / (y_skip_factor * 8)) * (y_skip_factor * 8);
|
||||
printf("[MT9F002] Warning, scaled_height not a multiple of %i, changing to %i\n", 8 * y_skip_factor, mt->scaled_height);
|
||||
}
|
||||
if (mt->output_scaler < 1.0) {
|
||||
write_reg(mt, MT9F002_SCALING_MODE, 2, 2); // Vertical and horizontal scaling
|
||||
write_reg(mt, MT9F002_SCALE_M, scaleFactor, 2);
|
||||
}
|
||||
printf("OUTPUT_SIZE: (%i, %i)\tSCALED_SIZE: (%i, %i)\n", mt->output_width, mt->output_height, mt->scaled_width,
|
||||
printf("[MT9F002] OUTPUT_SIZE: (%i, %i)\tSCALED_SIZE: (%i, %i)\n", mt->output_width, mt->output_height,
|
||||
mt->scaled_width,
|
||||
mt->scaled_height);
|
||||
/* bound offsets */
|
||||
if (mt->offset_x * MAX_WIDTH + mt->scaled_width / 2 > MAX_WIDTH){mt->offset_x = 1 - (float)mt->scaled_width / 2 / MAX_WIDTH;}
|
||||
if (-mt->offset_x * MAX_WIDTH > mt->scaled_width){mt->offset_x = -(float)mt->scaled_width/ 2 / MAX_WIDTH;}
|
||||
if (mt->offset_x * MT9F002_MAX_WIDTH + mt->scaled_width / 2 > MT9F002_MAX_WIDTH) {mt->offset_x = 1 - (float)mt->scaled_width / 2 / MT9F002_MAX_WIDTH;}
|
||||
if (-mt->offset_x * MT9F002_MAX_WIDTH > mt->scaled_width) {mt->offset_x = -(float)mt->scaled_width / 2 / MT9F002_MAX_WIDTH;}
|
||||
|
||||
if (mt->offset_y * MAX_HEIGHT + mt->scaled_height / 2 > MAX_HEIGHT){mt->offset_y = 1 - (float)mt->scaled_height/ 2 / MAX_HEIGHT;}
|
||||
if (-mt->offset_y * MAX_HEIGHT > mt->scaled_height / 2){mt->offset_y = -(float)mt->scaled_height/ 2 / MAX_HEIGHT;}
|
||||
if (mt->offset_y * MT9F002_MAX_HEIGHT + mt->scaled_height / 2 > MT9F002_MAX_HEIGHT) {mt->offset_y = 1 - (float)mt->scaled_height / 2 / MT9F002_MAX_HEIGHT;}
|
||||
if (-mt->offset_y * MT9F002_MAX_HEIGHT > mt->scaled_height / 2) {mt->offset_y = -(float)mt->scaled_height / 2 / MT9F002_MAX_HEIGHT;}
|
||||
|
||||
/* Set position (based on offset and subsample increment) */
|
||||
uint16_t start_addr_x = (uint16_t)((MAX_WIDTH - mt->scaled_width) / 2 + mt->offset_x * MAX_WIDTH);
|
||||
uint16_t start_addr_y = (uint16_t)((MAX_HEIGHT - mt->scaled_height) / 2 + mt->offset_y * MAX_HEIGHT);
|
||||
uint16_t start_addr_x = (uint16_t)((MT9F002_MAX_WIDTH - mt->scaled_width) / 2 + mt->offset_x * MT9F002_MAX_WIDTH);
|
||||
uint16_t start_addr_y = (uint16_t)((MT9F002_MAX_HEIGHT - mt->scaled_height) / 2 + mt->offset_y * MT9F002_MAX_HEIGHT);
|
||||
|
||||
if (start_addr_x < 24) {
|
||||
start_addr_x = 24;
|
||||
@@ -837,6 +838,17 @@ void mt9f002_set_resolution(struct mt9f002_t *mt)
|
||||
uint16_t end_addr_y = start_addr_y + mt->scaled_height - 1;
|
||||
write_reg(mt, MT9F002_X_ADDR_END, end_addr_x, 2);
|
||||
write_reg(mt, MT9F002_Y_ADDR_END, end_addr_y, 2);
|
||||
|
||||
// set statistics to correct values
|
||||
isp_config.statistics_bayer.window_x.x_offset = mt->scaled_width - (mt->scaled_width / BAYERSTATS_STATX) / 2;
|
||||
isp_config.statistics_bayer.window_y.y_offset = mt->scaled_height - (mt->scaled_height / BAYERSTATS_STATY) / 2;
|
||||
isp_config.statistics_bayer.window_x.x_width = mt->scaled_width / BAYERSTATS_STATX;
|
||||
isp_config.statistics_bayer.window_y.y_width = mt->scaled_height / BAYERSTATS_STATY;
|
||||
|
||||
isp_config.statistics_yuv.window_pos_x.window_x_end = mt->scaled_width - 1;
|
||||
isp_config.statistics_yuv.window_pos_y.window_y_end = mt->scaled_height - 1;
|
||||
isp_config.statistics_yuv.increments_log2.x_log2_inc = log2(x_skip_factor);
|
||||
isp_config.statistics_yuv.increments_log2.x_log2_inc = log2(y_skip_factor);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,6 +30,79 @@
|
||||
#include "std.h"
|
||||
#include "mcu_periph/i2c.h"
|
||||
|
||||
/* define required ouput image size */
|
||||
#ifndef MT9F002_OUTPUT_HEIGHT
|
||||
#define MT9F002_OUTPUT_HEIGHT 822 // full resolution 3288
|
||||
#endif
|
||||
|
||||
#ifndef MT9F002_OUTPUT_WIDTH
|
||||
#define MT9F002_OUTPUT_WIDTH 1152 // full resolution 4608
|
||||
#endif
|
||||
|
||||
#ifndef MT9F002_INITIAL_OFFSET_X
|
||||
#define MT9F002_INITIAL_OFFSET_X 0. // signed fractional offset from centre of image of original sensor [-0.5,0.5]
|
||||
#endif
|
||||
|
||||
#ifndef MT9F002_INITIAL_OFFSET_Y
|
||||
#define MT9F002_INITIAL_OFFSET_Y 0. // signed fractional offset from centre of image of original sensor [-0.5,0.5]
|
||||
#endif
|
||||
|
||||
/** Our output is only OUTPUT_SCALER of the pixels we take of the sensor
|
||||
* It is programmable in 1/16 steps determined by ScaleFactor = 16/scale_m.
|
||||
* Legal values for scale_m are 16 through 128, giving you the ability to scale from
|
||||
* 1:1 to 1:8 (with m=128).
|
||||
* Example:
|
||||
* output_width = 512
|
||||
* output_height = 830
|
||||
* output_scaler = 0.25
|
||||
* We now get an image of 512 by 830 which contains a "compressed version"
|
||||
* of what would normally be an image of 2048 by 3320 ISP (4608H x 2592V sensor)
|
||||
*/
|
||||
#ifndef MT9F002_OUTPUT_SCALER
|
||||
#define MT9F002_OUTPUT_SCALER 1.
|
||||
#endif
|
||||
|
||||
/** Exposure of the front camera of the bebop. Experimental values:
|
||||
* Outside: 15
|
||||
* Inside well lit: 30
|
||||
* Inside poorly lit: 60
|
||||
*/
|
||||
#ifndef MT9F002_TARGET_EXPOSURE
|
||||
#define MT9F002_TARGET_EXPOSURE 30
|
||||
#endif
|
||||
|
||||
#ifndef MT9F002_TARGET_FPS
|
||||
#define MT9F002_TARGET_FPS 15
|
||||
#endif
|
||||
|
||||
/* Set the colour balance gains */
|
||||
#ifndef MT9F002_GAIN_GREEN1
|
||||
#define MT9F002_GAIN_GREEN1 3.0
|
||||
#endif
|
||||
|
||||
#ifndef MT9F002_GAIN_GREEN2
|
||||
#define MT9F002_GAIN_GREEN2 3.0
|
||||
#endif
|
||||
|
||||
#ifndef MT9F002_GAIN_RED
|
||||
#define MT9F002_GAIN_RED 3.0
|
||||
#endif
|
||||
|
||||
#ifndef MT9F002_GAIN_BLUE
|
||||
#define MT9F002_GAIN_BLUE 4.0
|
||||
#endif
|
||||
|
||||
/* Set pixel increment value to implement subsampling */
|
||||
/* Supported values for MT9F002_X_ODD_INC_VAL are 3, 7, 15 and 31 */
|
||||
#ifndef MT9F002_X_ODD_INC_VAL
|
||||
#define MT9F002_X_ODD_INC_VAL 1
|
||||
#endif
|
||||
|
||||
/* Supported values for MT9F002_Y_ODD_INC_VAL are 1, 3 and 7 */
|
||||
#ifndef MT9F002_Y_ODD_INC_VAL
|
||||
#define MT9F002_Y_ODD_INC_VAL 1
|
||||
#endif
|
||||
|
||||
/* Interface types for the MT9F002 connection */
|
||||
enum mt9f002_interface {
|
||||
MT9F002_MIPI, ///< MIPI type connection
|
||||
|
||||
@@ -1,241 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2012-2014 The Paparazzi Community
|
||||
* 2015 Freek van Tienen <freek.v.tienen@gmail.com>
|
||||
*
|
||||
* This file is part of Paparazzi.
|
||||
*
|
||||
* Paparazzi is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* Paparazzi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with paparazzi; see the file COPYING. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file modules/computer_vision/bebop_front_camera.c
|
||||
*/
|
||||
|
||||
// Own header
|
||||
#include "modules/computer_vision/bebop_front_camera.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <math.h>
|
||||
|
||||
// Video
|
||||
#include "lib/v4l/v4l2.h"
|
||||
#include "lib/vision/image.h"
|
||||
#include "lib/vision/bayer.h"
|
||||
#include "lib/encoding/jpeg.h"
|
||||
#include "lib/encoding/rtp.h"
|
||||
#include "udp_socket.h"
|
||||
|
||||
// Threaded computer vision
|
||||
#include <pthread.h>
|
||||
|
||||
#define MT9F002_WIDTH 1408
|
||||
#define MT9F002_HEIGHT 2112
|
||||
#define BEBOP_FRONT_CAMERA_WIDTH 272
|
||||
#define BEBOP_FRONT_CAMERA_HEIGHT 272
|
||||
|
||||
// The place where the shots are saved (without slash on the end)
|
||||
#ifndef BEBOP_FRONT_CAMERA_SHOT_PATH
|
||||
#define BEBOP_FRONT_CAMERA_SHOT_PATH /data/ftp/internal_000/images
|
||||
#endif
|
||||
PRINT_CONFIG_VAR(BEBOP_FRONT_CAMERA_SHOT_PATH)
|
||||
|
||||
// Main thread
|
||||
static void *bebop_front_camera_thread(void *data);
|
||||
static void bebop_front_camera_save_shot(struct image_t *img_color, struct image_t *img_jpeg, struct image_t *raw_img);
|
||||
void bebop_front_camera_periodic(void) { }
|
||||
|
||||
// Initialize the bebop_front_camera structure with the defaults
|
||||
struct bebopfrontcamera_t bebop_front_camera = {
|
||||
.is_streaming = FALSE,
|
||||
.take_shot = FALSE,
|
||||
.shot_number = 0,
|
||||
.take_shot = FALSE,
|
||||
.shot_number = 0
|
||||
};
|
||||
|
||||
void bebop_front_camera_take_shot(bool take)
|
||||
{
|
||||
bebop_front_camera.take_shot = true;
|
||||
}
|
||||
/**
|
||||
* 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 *bebop_front_camera_thread(void *data __attribute__((unused)))
|
||||
{
|
||||
struct UdpSocket video_sock;
|
||||
udp_socket_create(&video_sock, STRINGIFY(BEBOP_FRONT_CAMERA_HOST), BEBOP_FRONT_CAMERA_PORT_OUT, -1,
|
||||
BEBOP_FRONT_CAMERA_BROADCAST);
|
||||
|
||||
// Create the JPEG encoded image
|
||||
struct image_t img_jpeg;
|
||||
image_create(&img_jpeg, BEBOP_FRONT_CAMERA_WIDTH, BEBOP_FRONT_CAMERA_HEIGHT, IMAGE_JPEG);
|
||||
|
||||
// Create the Color image
|
||||
struct image_t img_color;
|
||||
image_create(&img_color, BEBOP_FRONT_CAMERA_WIDTH, BEBOP_FRONT_CAMERA_HEIGHT, IMAGE_YUV422);
|
||||
|
||||
// Start the streaming of the V4L2 device
|
||||
if (!v4l2_start_capture(bebop_front_camera.dev)) {
|
||||
printf("[bebop_front_camera-thread] Could not start capture of %s.\n", bebop_front_camera.dev->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Start streaming
|
||||
bebop_front_camera.is_streaming = true;
|
||||
while (bebop_front_camera.is_streaming) {
|
||||
// Wait for a new frame (blocking)
|
||||
struct image_t img;
|
||||
v4l2_image_get(bebop_front_camera.dev, &img);
|
||||
|
||||
BayerToYUV(&img, &img_color, 0, 0);
|
||||
|
||||
if (bebop_front_camera.take_shot) {
|
||||
// Save the image
|
||||
bebop_front_camera_save_shot(&img_color, &img_jpeg, &img);
|
||||
bebop_front_camera.take_shot = false;
|
||||
}
|
||||
|
||||
jpeg_encode_image(&img_color, &img_jpeg, 80, 0);
|
||||
|
||||
// Send image with RTP
|
||||
rtp_frame_send(
|
||||
&video_sock, // UDP socket
|
||||
&img_jpeg,
|
||||
0, // Format 422
|
||||
80, // Jpeg-Quality
|
||||
0, // DRI Header
|
||||
0 // 90kHz time increment
|
||||
);
|
||||
|
||||
|
||||
// Free the image
|
||||
v4l2_image_free(bebop_front_camera.dev, &img);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the view video
|
||||
*/
|
||||
void bebop_front_camera_init(void)
|
||||
{
|
||||
// Initialize the V4L2 subdevice (TODO: fix hardcoded path, which and code)
|
||||
if (!v4l2_init_subdev("/dev/v4l-subdev1", 0, 0, V4L2_MBUS_FMT_SGBRG10_1X10, MT9F002_WIDTH, MT9F002_HEIGHT)) {
|
||||
printf("[bebop_front_camera] Could not initialize the v4l-subdev1 subdevice.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize the V4L2 device
|
||||
bebop_front_camera.dev = v4l2_init("/dev/video1", MT9F002_WIDTH, MT9F002_HEIGHT, 10, V4L2_PIX_FMT_SGBRG10);
|
||||
if (bebop_front_camera.dev == NULL) {
|
||||
printf("[bebop_front_camera] Could not initialize the /dev/video1 V4L2 device.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the shot directory
|
||||
char save_name[128];
|
||||
sprintf(save_name, "mkdir -p %s", STRINGIFY(BEBOP_FRONT_CAMERA_SHOT_PATH));
|
||||
if (system(save_name) != 0) {
|
||||
printf("[bebop_front_camera] Could not create shot directory %s.\n", STRINGIFY(BEBOP_FRONT_CAMERA_SHOT_PATH));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Start with streaming
|
||||
*/
|
||||
void bebop_front_camera_start(void)
|
||||
{
|
||||
// Check if we are already running
|
||||
if (bebop_front_camera.is_streaming) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Start the streaming thread
|
||||
pthread_t tid;
|
||||
if (pthread_create(&tid, NULL, bebop_front_camera_thread, NULL) != 0) {
|
||||
printf("[vievideo] Could not create streaming thread.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the streaming
|
||||
* This could take some time, because the thread is stopped asynchronous.
|
||||
*/
|
||||
void bebop_front_camera_stop(void)
|
||||
{
|
||||
// Check if not already stopped streaming
|
||||
if (!bebop_front_camera.is_streaming) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Stop the streaming thread
|
||||
bebop_front_camera.is_streaming = false;
|
||||
|
||||
// Stop the capturing
|
||||
if (!v4l2_stop_capture(bebop_front_camera.dev)) {
|
||||
printf("[bebop_front_camera] Could not stop capture of %s.\n", bebop_front_camera.dev->name);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: wait for the thread to finish to be able to start the thread again!
|
||||
}
|
||||
|
||||
static void bebop_front_camera_save_shot(struct image_t *img, struct image_t *img_jpeg, struct image_t *raw_img)
|
||||
{
|
||||
|
||||
// Search for a file where we can write to
|
||||
char save_name[128];
|
||||
for (; bebop_front_camera.shot_number < 99999; bebop_front_camera.shot_number++) {
|
||||
sprintf(save_name, "%s/img_%05d.pgm", STRINGIFY(BEBOP_FRONT_CAMERA_SHOT_PATH), bebop_front_camera.shot_number);
|
||||
// Check if file exists or not
|
||||
if (access(save_name, F_OK) == -1) {
|
||||
FILE *fp = fopen(save_name, "w");
|
||||
if (fp == NULL) {
|
||||
printf("[bebop_front_camera-thread] Could not write shot %s.\n", save_name);
|
||||
} else {
|
||||
// Save it to the file and close it
|
||||
char pgm_header[] = "P5\n272 272\n255\n";
|
||||
fwrite(pgm_header, sizeof(char), 15, fp);
|
||||
fwrite(img->buf, sizeof(uint8_t), img->buf_size, fp);
|
||||
fclose(fp);
|
||||
|
||||
// JPEG
|
||||
jpeg_encode_image(img, img_jpeg, 99, 1);
|
||||
sprintf(save_name, "%s/img_%05d.jpg", STRINGIFY(BEBOP_FRONT_CAMERA_SHOT_PATH), bebop_front_camera.shot_number);
|
||||
fp = fopen(save_name, "w");
|
||||
fwrite(img_jpeg->buf, sizeof(uint8_t), img_jpeg->buf_size, fp);
|
||||
fclose(fp);
|
||||
|
||||
sprintf(save_name, "%s/img_%05d.raw", STRINGIFY(BEBOP_FRONT_CAMERA_SHOT_PATH), bebop_front_camera.shot_number);
|
||||
fp = fopen(save_name, "w");
|
||||
fwrite(raw_img->buf, sizeof(uint8_t), raw_img->buf_size, fp);
|
||||
fclose(fp);
|
||||
|
||||
}
|
||||
|
||||
// We don't need to seek for a next index anymore
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2012-2014 The Paparazzi Community
|
||||
* 2015 Freek van Tienen <freek.v.tienen@gmail.com>
|
||||
*
|
||||
* This file is part of Paparazzi.
|
||||
*
|
||||
* Paparazzi is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* Paparazzi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with paparazzi; see the file COPYING. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file modules/computer_vision/bebop_front_camera.h
|
||||
*
|
||||
* Get live images from a RTP/UDP stream
|
||||
* and save pictures on internal memory
|
||||
*
|
||||
* Works on Bebop platforms
|
||||
*/
|
||||
|
||||
#ifndef BEBOP_FRONT_CAMERA_H
|
||||
#define BEBOP_FRONT_CAMERA_H
|
||||
|
||||
#include "std.h"
|
||||
|
||||
// Main viewvideo structure
|
||||
struct bebopfrontcamera_t {
|
||||
struct v4l2_device *dev; ///< The V4L2 device that is used for the video stream
|
||||
uint8_t fps; ///< The amount of frames per second
|
||||
volatile bool take_shot; ///< Wether to take an image
|
||||
uint16_t shot_number; ///< The last shot number
|
||||
volatile bool is_streaming; ///< When the device is streaming
|
||||
uint8_t downsize_factor; ///< Downsize factor during the stream
|
||||
uint8_t quality_factor; ///< Quality factor during the stream
|
||||
bool use_rtp; ///< Stream over RTP
|
||||
};
|
||||
extern struct bebopfrontcamera_t bebop_front_camera;
|
||||
|
||||
// Module functions
|
||||
extern void bebop_front_camera_init(void);
|
||||
extern void bebop_front_camera_periodic(void); ///< A dummy for now
|
||||
extern void bebop_front_camera_start(void);
|
||||
extern void bebop_front_camera_stop(void);
|
||||
extern void bebop_front_camera_take_shot(bool take);
|
||||
|
||||
#endif /* BEBOP_FRONT_CAMERA_H */
|
||||
|
||||
@@ -65,10 +65,13 @@ void cv_ae_awb_periodic(void)
|
||||
uint32_t max_saturated_pixels = yuv_stats.nb_valid_Y / 400; // 0.25%
|
||||
float adjustment = 1.0f;
|
||||
|
||||
printf("%d %d\n", bright_pixels, target_bright_pixels);
|
||||
|
||||
// Fix saturated pixels
|
||||
if (saturated_pixels > max_saturated_pixels) {
|
||||
adjustment = 1.0f - ((float)(saturated_pixels - max_saturated_pixels)) / yuv_stats.nb_valid_Y;
|
||||
} else if (bright_pixels + target_bright_pixels / 10 < target_bright_pixels) { // Fix bright pixels if outside of 10% of target
|
||||
} else if (bright_pixels + target_bright_pixels / 10 <
|
||||
target_bright_pixels) { // Fix bright pixels if outside of 10% of target
|
||||
// increase brightness to try and hit the desired number of well exposed pixels
|
||||
int l = MAX_HIST_Y - 11;
|
||||
while (bright_pixels < target_bright_pixels && l > 0) {
|
||||
@@ -78,7 +81,8 @@ void cv_ae_awb_periodic(void)
|
||||
}
|
||||
|
||||
adjustment = (float)(MAX_HIST_Y - 11 + 1) / (l + 1);
|
||||
} else if (bright_pixels - target_bright_pixels / 10 > target_bright_pixels) { // Fix bright pixels if outside of 10% of target
|
||||
} else if (bright_pixels - target_bright_pixels / 10 >
|
||||
target_bright_pixels) { // Fix bright pixels if outside of 10% of target
|
||||
// decrease brightness to try and hit the desired number of well exposed pixels
|
||||
int l = MAX_HIST_Y - 20;
|
||||
while (bright_pixels > target_bright_pixels && l < MAX_HIST_Y) {
|
||||
@@ -105,16 +109,16 @@ void cv_ae_awb_periodic(void)
|
||||
float gain = 1.;
|
||||
bool changed = false;
|
||||
|
||||
if (fabs(avgU) > threshold){
|
||||
if (fabs(avgU) > threshold) {
|
||||
mt9f002.gain_blue -= gain * avgU;
|
||||
changed = true;
|
||||
}
|
||||
if (fabs(avgV) > threshold){
|
||||
if (fabs(avgV) > threshold) {
|
||||
mt9f002.gain_red -= gain * avgV;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed){
|
||||
if (changed) {
|
||||
Bound(mt9f002.gain_blue, 2, 75);
|
||||
Bound(mt9f002.gain_red, 2, 75);
|
||||
mt9f002_set_gains(&mt9f002);
|
||||
|
||||
@@ -92,24 +92,21 @@ void rtp_frame_test(struct UdpSocket *udp)
|
||||
* @param[in] format_code 0 for YUV422 and 1 for YUV421
|
||||
* @param[in] quality_code The JPEG encoding quality
|
||||
* @param[in] has_dri_header Whether we have an DRI header or not
|
||||
* @param[in] delta_t Time between images (if set to 0 or less it is calculated)
|
||||
* @param[in] delta_t Time between images in usec (if set to 0 or less it is calculated)
|
||||
*/
|
||||
void rtp_frame_send(struct UdpSocket *udp, struct image_t *img, uint8_t format_code,
|
||||
uint8_t quality_code, uint8_t has_dri_header, uint32_t delta_t)
|
||||
uint8_t quality_code, uint8_t has_dri_header, uint32_t frame_time, uint32_t *packet_number)
|
||||
{
|
||||
static uint32_t packetcounter = 0;
|
||||
static uint32_t timecounter = 0;
|
||||
uint32_t offset = 0;
|
||||
uint32_t jpeg_size = img->buf_size;
|
||||
uint8_t *jpeg_ptr = img->buf;
|
||||
|
||||
#define MAX_PACKET_SIZE 1400
|
||||
|
||||
if (delta_t <= 0) {
|
||||
if (frame_time <= 0) {
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, 0);
|
||||
uint32_t t = (tv.tv_sec % (256 * 256)) * 90000 + tv.tv_usec * 9 / 100;
|
||||
timecounter = t;
|
||||
frame_time = (tv.tv_sec % (256 * 256)) + tv.tv_usec;
|
||||
}
|
||||
|
||||
// Split frame into packets
|
||||
@@ -122,31 +119,29 @@ void rtp_frame_send(struct UdpSocket *udp, struct image_t *img, uint8_t format_c
|
||||
len = jpeg_size;
|
||||
}
|
||||
|
||||
rtp_packet_send(udp, jpeg_ptr, len, packetcounter, timecounter, offset, lastpacket, img->w, img->h, format_code,
|
||||
rtp_packet_send(udp, jpeg_ptr, len, (*packet_number)++, frame_time, offset, lastpacket, img->w, img->h, format_code,
|
||||
quality_code, has_dri_header);
|
||||
|
||||
jpeg_size -= len;
|
||||
jpeg_ptr += len;
|
||||
offset += len;
|
||||
packetcounter++;
|
||||
}
|
||||
|
||||
|
||||
if (delta_t > 0) {
|
||||
// timestamp = 1 / 90 000 seconds
|
||||
timecounter += delta_t;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The RTP timestamp is in units of 90000Hz. The same timestamp MUST
|
||||
appear in each fragment of a given frame. The RTP marker bit MUST be
|
||||
set in the last packet of a frame.
|
||||
* The same timestamp MUST appear in each fragment of a given frame.
|
||||
* The RTP marker bit MUST be set in the last packet of a frame.
|
||||
* Extra note: When the time difference between frames is non-constant,
|
||||
there seems to introduce some lag or jitter in the video streaming.
|
||||
One way to solve this is to send the timestamp in units of 90000Hz
|
||||
rather than 100000 (when the frame is received the timestamp is always
|
||||
"late" so the frame is displayed immediately). (1 = 1/90000 s) which
|
||||
is probably stupid but is actually working.
|
||||
* @param[in] *udp The UDP socket to send the RTP packet over
|
||||
* @param[in] *Jpeg JPEG encoded image byte buffer
|
||||
* @param[in] JpegLen The length of the byte buffer
|
||||
* @param[in] m_SequenceNumber RTP sequence number
|
||||
* @param[in] m_Timestamp Timestamp of the image
|
||||
* @param[in] m_Timestamp Timestamp of the image in usec
|
||||
* @param[in] m_offset 3 byte fragmentation offset for fragmented images
|
||||
* @param[in] marker_bit RTP marker bit
|
||||
* @param[in] w The width of the JPEG image
|
||||
@@ -190,6 +185,7 @@ static void rtp_packet_send(
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* */
|
||||
|
||||
m_Timestamp *= 9 / 100; // convert timestamp to units of 1 / 90000 Hz
|
||||
// Prepare the 12 byte RTP header
|
||||
RtpBuf[0] = 0x80; // RTP version
|
||||
RtpBuf[1] = 0x1a + (marker_bit << 7); // JPEG payload (26) and marker bit
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#include "udp_socket.h"
|
||||
|
||||
void rtp_frame_send(struct UdpSocket *udp, struct image_t *img, uint8_t format_code, uint8_t quality_code,
|
||||
uint8_t has_dri_header, uint32_t delta_t);
|
||||
uint8_t has_dri_header, uint32_t frame_time, uint32_t *packet_number);
|
||||
void rtp_frame_test(struct UdpSocket *udp);
|
||||
|
||||
#endif /* _CV_ENCODING_RTP_H */
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <sys/mman.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include "libisp.h"
|
||||
//#include "libisp.h"
|
||||
#include "libisp_config.h"
|
||||
|
||||
#define AVI_BASE 0x400000
|
||||
@@ -194,10 +194,6 @@ int configure_isp(struct v4l2_device *dev)
|
||||
avi_isp_gamma_corrector_gu_lut_set_registers(&isp_ctx, &isp_config.gc_gu_lut);
|
||||
avi_isp_gamma_corrector_bv_lut_set_registers(&isp_ctx, &isp_config.gc_bv_lut);
|
||||
avi_isp_chroma_set_registers(&isp_ctx, &isp_config.chroma);
|
||||
|
||||
isp_config.statistics_yuv.increments_log2.x_log2_inc = log2(MT9F002_X_ODD_INC_VAL);
|
||||
isp_config.statistics_yuv.increments_log2.x_log2_inc = log2(MT9F002_Y_ODD_INC_VAL);
|
||||
|
||||
avi_isp_statistics_yuv_set_registers(&isp_ctx, &isp_config.statistics_yuv);
|
||||
avi_isp_edge_enhancement_color_reduction_filter_set_registers(&isp_ctx, &isp_config.eecrf);
|
||||
avi_isp_edge_enhancement_color_reduction_filter_ee_lut_set_registers(&isp_ctx, &isp_config.eecrf_lut);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef _LIBISP_CONFIG_H
|
||||
#define _LIBISP_CONFIG_H
|
||||
|
||||
#include "boards/bebop.h"
|
||||
#include "boards/bebop/mt9f002.h"
|
||||
#include "libisp.h"
|
||||
|
||||
struct libisp_config isp_config = {
|
||||
@@ -433,8 +433,8 @@ struct libisp_config isp_config = {
|
||||
.statistics_yuv = {
|
||||
.measure_req = {{1, 1}},
|
||||
.measure_status = {{0, 0}},
|
||||
.window_pos_x = {{ .window_x_start = 0, .window_x_end = MT9F002_OUTPUT_WIDTH }},
|
||||
.window_pos_y = {{ .window_y_start = 0, .window_y_end = MT9F002_OUTPUT_HEIGHT }},
|
||||
.window_pos_x = {{ .window_x_start = 0, .window_x_end = MT9F002_OUTPUT_WIDTH - 1 }},
|
||||
.window_pos_y = {{ .window_y_start = 0, .window_y_end = MT9F002_OUTPUT_HEIGHT - 1 }},
|
||||
.circle_pos_x_center = {{ 1088 }},
|
||||
.circle_pos_x_squared = {{ 1183744 }},
|
||||
.circle_pos_y_center = {{ 1078 }},
|
||||
|
||||
@@ -68,7 +68,7 @@ PRINT_CONFIG_VAR(VIEWVIDEO_RTP_TIME_INC)
|
||||
|
||||
// Define stream framerate
|
||||
#ifndef VIEWVIDEO_FPS
|
||||
#define VIEWVIDEO_FPS 10
|
||||
#define VIEWVIDEO_FPS 5
|
||||
#endif
|
||||
PRINT_CONFIG_VAR(VIEWVIDEO_FPS)
|
||||
|
||||
@@ -112,16 +112,11 @@ struct viewvideo_t viewvideo = {
|
||||
#endif
|
||||
};
|
||||
|
||||
#if defined(VIEWVIDEO_CAMERA) && defined(VIEWVIDEO_CAMERA2) && VIEWVIDEO_BROADCAST == true
|
||||
#warning Broadcasting dual video stream causes too much udp overhead resulting in unstable streaming
|
||||
#warning We recomment using a static VIEWVIDEO_HOST address and VIEWVIDEO_BROADCAST to false
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Handles all the video streaming and saving of the image shots
|
||||
* This is a separate thread, so it needs to be thread safe!
|
||||
*/
|
||||
static struct image_t *viewvideo_function(struct UdpSocket *socket, struct image_t *img)
|
||||
static struct image_t *viewvideo_function(struct UdpSocket *socket, struct image_t *img, uint32_t *rtp_frame_nr)
|
||||
{
|
||||
// Resize image if needed
|
||||
struct image_t img_small;
|
||||
@@ -180,19 +175,11 @@ static struct image_t *viewvideo_function(struct UdpSocket *socket, struct image
|
||||
0, // Format 422
|
||||
VIEWVIDEO_QUALITY_FACTOR, // Jpeg-Quality
|
||||
0, // DRI Header
|
||||
VIEWVIDEO_RTP_TIME_INC // 90kHz time increment
|
||||
(img->ts.tv_sec * 1000000 + img->ts.tv_usec),
|
||||
rtp_frame_nr
|
||||
);
|
||||
// Extra note: when the time increment is set to 0,
|
||||
// it is automaticaly calculated by the send_rtp_frame function
|
||||
// based on gettimeofday value. This seems to introduce some lag or jitter.
|
||||
// An other way is to compute the time increment and set the correct value.
|
||||
// It seems that a lower value is also working (when the frame is received
|
||||
// the timestamp is always "late" so the frame is displayed immediately).
|
||||
// Here, we set the time increment to the lowest possible value
|
||||
// (1 = 1/90000 s) which is probably stupid but is actually working.
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
// Free all buffers
|
||||
@@ -204,14 +191,16 @@ static struct image_t *viewvideo_function(struct UdpSocket *socket, struct image
|
||||
#ifdef VIEWVIDEO_CAMERA
|
||||
static struct image_t *viewvideo_function1(struct image_t *img)
|
||||
{
|
||||
return viewvideo_function(&video_sock1, img);
|
||||
static uint32_t rtp_frame_nr = 0;
|
||||
return viewvideo_function(&video_sock1, img, &rtp_frame_nr);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef VIEWVIDEO_CAMERA2
|
||||
static struct image_t *viewvideo_function2(struct image_t *img)
|
||||
{
|
||||
return viewvideo_function(&video_sock2, img);
|
||||
static uint32_t rtp_frame_nr = 0;
|
||||
return viewvideo_function(&video_sock2, img, &rtp_frame_nr);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user