Comparar commits
152 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| bba002865b | |||
| 4eed6021b3 | |||
| d5d9a5d2e5 | |||
| ecec423f04 | |||
| 8c46987feb | |||
| ec87053f36 | |||
| afa3bd2ecc | |||
| a3f9cff1a6 | |||
| 3e8a369938 | |||
| e8c4648e73 | |||
| 6699b18a39 | |||
| 102aef9d99 | |||
| d0e54a56d0 | |||
| e8b9794190 | |||
| 8245e9d544 | |||
| 7edb356730 | |||
| 5eb4df45d4 | |||
| 166e197b20 | |||
| cd4e81fc19 | |||
| 9349c53045 | |||
| 7fcac1ae88 | |||
| 40c41efafe | |||
| ed13986a63 | |||
| 069f492a92 | |||
| 60dd3eee67 | |||
| 78f971d19a | |||
| ead051af89 | |||
| 59690640d8 | |||
| c1bff2008b | |||
| 7b8a651067 | |||
| 9297e938c7 | |||
| 7fdf268969 | |||
| c96e7d262f | |||
| 140f55e323 | |||
| af03f2536e | |||
| d3249e151e | |||
| 4bfa20b278 | |||
| 30dc1b0feb | |||
| 1ae6d4843f | |||
| 3a4c7da6c7 | |||
| cf1cd64d8e | |||
| 2cc4fd9696 | |||
| 784df9925e | |||
| 8edc093b96 | |||
| 39b5580296 | |||
| 837c4bcfb3 | |||
| b3ef0f186d | |||
| 01185e9788 | |||
| 8766a2a1ea | |||
| c68b96f390 | |||
| a3fc39b0d2 | |||
| 6a80eefdb1 | |||
| cb4179f2f7 | |||
| 08aa3189d5 | |||
| 4057b6e821 | |||
| 96a7a480a3 | |||
| 0c42f257ba | |||
| 1b7074de37 | |||
| 24529cd596 | |||
| 54d6fff7bf | |||
| ca5fadf778 | |||
| 2fc267c869 | |||
| f46a7adf89 | |||
| efaa64c047 | |||
| 13145dc1ba | |||
| 5d48b4d0ef | |||
| 13bb31ff12 | |||
| 73e9a53a67 | |||
| 712a24bb3e | |||
| d1de36328d | |||
| b72793b89f | |||
| 699fa5a3b6 | |||
| 3ec0db04aa | |||
| 0dc6a2a84b | |||
| 0b58364a5c | |||
| b5c57a3849 | |||
| 4f568c100c | |||
| d1d4cd1532 | |||
| 99d0436d1e | |||
| 6bab013d70 | |||
| 23c29727fd | |||
| fec6fc0723 | |||
| acc441ec98 | |||
| 9efbd40019 | |||
| 60f858e36f | |||
| 295f2795d9 | |||
| de2834bf0c | |||
| 27008cc5b5 | |||
| 25ac4a9f8a | |||
| 337555f43b | |||
| 4e4da04e1a | |||
| dddaeb7b1f | |||
| 18d80c97ee | |||
| 370cdc2bcb | |||
| f3d23c8d4f | |||
| 997ab0acaa | |||
| 794121c07b | |||
| d0f58fea33 | |||
| a2b0b4c0f4 | |||
| 604d93b569 | |||
| c25403e4f2 | |||
| 6059cacd3a | |||
| 974a7115d8 | |||
| 1797e84c1f | |||
| 277526a567 | |||
| 71bc9d0279 | |||
| 5c6cc2fedb | |||
| 2b7d488e6c | |||
| c3d263dfae | |||
| 8da82d5780 | |||
| 91918819b9 | |||
| df465580d6 | |||
| 909ee16d96 | |||
| ef81277061 | |||
| 10bea4190f | |||
| 0a3a9086ec | |||
| 3ef38ccd60 | |||
| 3f19a8d04a | |||
| e7233dcfce | |||
| d0f3502d94 | |||
| cb746ed9f6 | |||
| b1841cdd91 | |||
| 019f1b7411 | |||
| 2f91026bbc | |||
| eaee5ab16d | |||
| c34f24f785 | |||
| 68f7c8cd20 | |||
| e278393948 | |||
| 375df03b1c | |||
| 7f6d4746d9 | |||
| cdf41f304c | |||
| cd28497b88 | |||
| 1ba71f1916 | |||
| 58d20cdbde | |||
| 89e5765e50 | |||
| be7000a2aa | |||
| bae9bf4f67 | |||
| 4ab9d1278f | |||
| 7fd389291a | |||
| a8ea6d5be6 | |||
| 7e3b5d6b40 | |||
| 34f18b1367 | |||
| b49d23d65f | |||
| 3553e234a7 | |||
| 87aff14f2e | |||
| 0d6146fbe0 | |||
| 609bf100ae | |||
| f5c28b2fe2 | |||
| b1a7b08ab2 | |||
| 598376a75b | |||
| d9cc2a22a6 | |||
| f2d0a1b0d5 |
+19
-1
@@ -3,6 +3,10 @@
|
||||
*.lo
|
||||
*.o
|
||||
|
||||
# Project Files
|
||||
*.sublime-workspace
|
||||
*.sublime-project
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
|
||||
@@ -10,4 +14,18 @@
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
/nbproject/private/
|
||||
/nbproject/private/
|
||||
Makefile
|
||||
/build/CMakeFiles/
|
||||
|
||||
# Build results
|
||||
/ARDroneLib/FFMPEG/Includes
|
||||
/ARDroneLib/FFMPEG/FFMPEG
|
||||
/ARDroneLib/Soft/Build/
|
||||
/ARDroneLib/Soft/Common/generated_custom.h
|
||||
/bin
|
||||
/build/
|
||||
/msg_gen
|
||||
/srv_gen
|
||||
/src/ardrone_autonomy
|
||||
scripts/cache/DEBS_avail
|
||||
|
||||
@@ -13,7 +13,7 @@ else
|
||||
RELEASE_OPT="debug"
|
||||
endif
|
||||
|
||||
FFMPEG_CONFIG=decoder
|
||||
FFMPEG_CONFIG=both
|
||||
|
||||
|
||||
FFMPEG_DIR_EXIST=$(shell bash -c "if [ -d ffmpeg ]; then echo \"YES\"; else echo \"NO\"; fi")
|
||||
|
||||
Arquivo binário não exibido.
@@ -65,10 +65,10 @@ ifdef PC_TARGET
|
||||
OS_DEFINE=GNU_LINUX
|
||||
else
|
||||
ifeq ("$(USE_LINUX)","yes")
|
||||
OS_DEFINE=GNU_LINUX
|
||||
else
|
||||
TARGET:=$(TARGET).exe
|
||||
OS_DEFINE=WINDOW
|
||||
OS_DEFINE=GNU_LINUX
|
||||
else
|
||||
TARGET:=$(TARGET).exe
|
||||
OS_DEFINE=WINDOW
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -110,8 +110,8 @@ ifdef PC_TARGET
|
||||
|
||||
ifeq ("$(IPHONE_MODE)","yes")
|
||||
SDK_FLAGS+="USE_IPHONE=yes"
|
||||
SDK_FLAGS+="FFMPEG_SUPPORT=no"
|
||||
SDK_FLAGS+="ITTIAM_SUPPORT=yes"
|
||||
SDK_FLAGS+="FFMPEG_SUPPORT=yes"
|
||||
SDK_FLAGS+="ITTIAM_SUPPORT=no"
|
||||
SDK_FLAGS+="USE_VIDEO_TCP=yes"
|
||||
SDK_FLAGS+="USE_VIDEO_HD=no"
|
||||
else
|
||||
@@ -127,10 +127,10 @@ ifdef PC_TARGET
|
||||
|
||||
ifeq ("$(USE_ANDROID)","yes")
|
||||
SDK_FLAGS+="USE_ANDROID=yes"
|
||||
SDK_FLAGS+="TOOLCHAIN_VERSION=arm-linux-androideabi-4.4.3"
|
||||
SDK_FLAGS+="TOOLCHAIN_VERSION=arm-linux-androideabi-4.6"
|
||||
SDK_FLAGS+="NDK_PLATFORM_VERSION=android-8"
|
||||
SDK_FLAGS+="FFMPEG_SUPPORT=yes"
|
||||
SDK_FLAGS+="ITTIAM_SUPPORT=yes"
|
||||
SDK_FLAGS+="ITTIAM_SUPPORT=no"
|
||||
SDK_FLAGS+="USE_VIDEO_TCP=yes"
|
||||
SDK_FLAGS+="USE_VIDEO_HD=no"
|
||||
else
|
||||
|
||||
@@ -14,7 +14,7 @@ ifndef USE_ANDROID
|
||||
USE_ANDROID = no
|
||||
endif
|
||||
ifndef USE_LINUX
|
||||
USE_LINUX = yes
|
||||
USE_LINUX = no
|
||||
endif
|
||||
ifndef PROJECT
|
||||
# set default to ardrone2 for video TCP com.
|
||||
|
||||
@@ -44,6 +44,6 @@ typedef struct _academy_user_t_
|
||||
} academy_user_t;
|
||||
|
||||
typedef void (*academy_callback)(academy_state_t state);
|
||||
typedef void (*academy_download_new_media)(const char *mediaPath);
|
||||
typedef void (*academy_download_new_media)(const char *mediaPath, bool_t addToQueue);
|
||||
|
||||
#endif // _ACADEMY_COMMON_H_
|
||||
|
||||
@@ -359,22 +359,6 @@ typedef enum
|
||||
FLYING_MODE_HOVER_ON_TOP_OF_ORIENTED_ROUNDEL = 1 << 1, /**< Commands are disabled, drones hovers on top of an oriented roundel - oriented roundel detection MUST be activated by the user with 'detect_type' configuration. */
|
||||
} FLYING_MODE;
|
||||
|
||||
/*
|
||||
* @enum TRAVELLING_MODE
|
||||
* @brief Values for the CONTROL:travelling_mode configuration.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
TRAVELLING_MODE_TRANSLATION = 0, /**< Travelling translation mode */
|
||||
TRAVELLING_MODE_CIRCULAR, /**< Travelling circular mode */
|
||||
TRAVELLING_MODE_SWING, /**/
|
||||
TRAVELLING_MODE_WHEEL_FRONT, /**/
|
||||
TRAVELLING_MODE_WHEEL_SIDE, /**/
|
||||
TRAVELLING_MODE_GUSH, /**/
|
||||
TRAVELLING_MODE_PLANAR_WHEEL,/**/
|
||||
TRAVELLING_MODE_NUM,
|
||||
} TRAVELLING_MODE;
|
||||
|
||||
/**
|
||||
* @enum WIFI_MODE
|
||||
* @brief Values for the NETWORK:wifi_mode configuration, who set the wifi mode when drone start
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Automatically generated C config: don't edit
|
||||
* Linux kernel version:
|
||||
* Thu Nov 5 18:06:01 2009
|
||||
*/
|
||||
#define AUTOCONF_INCLUDED
|
||||
#define PAL_TRACE_THREAD_VAL 0
|
||||
#define PAL_ASSERT 1
|
||||
#define MODIF_VERSION_NUMBER 0
|
||||
#define PAL_BUTTON_LONG_PRESS_TIME 2000
|
||||
#define PAL_BUTTON_DRIVER 1
|
||||
#define PAL_I2C_DRIVER 1
|
||||
#define MAJOR_VERSION_NUMBER 1
|
||||
#define PAL_TRACE_SEM_VAL 0
|
||||
#define MINOR_VERSION_NUMBER 0
|
||||
#define PAL_TRACE_SYS_VAL 0
|
||||
#define PAL_SUP_NB_TIMERS 18
|
||||
#define PAL_TRACE_HWALARM_VAL 0
|
||||
#define PAL_PWM_DRIVER 1
|
||||
#define PAL_I2C_DEVICES 1
|
||||
#define EXTENDED_VERSION_INFO RC0
|
||||
#define PAL_SUP_NB_MOD 32
|
||||
#define PAL_TRACE_FLAG_VAL 0
|
||||
#define PAL_TRACE_COND_VAL 0
|
||||
#define PAL_DEBUG_LEVEL 1
|
||||
#define PAL_TRACE_GPIO_VAL 0
|
||||
#define PAL_TRACE_TIME_VAL 0
|
||||
#define PAL_TRACE_MBOX_VAL 0
|
||||
#define PAL_TRACE_UART_VAL 0
|
||||
#define PAL_GPIO_DRIVER 1
|
||||
#define PAL_P6MU_ADC_DEVICE 1
|
||||
#define PAL_P6MU_CODEC_DEVICE 1
|
||||
#define BUILD_PAL 1
|
||||
#define PAL_SUP_PRIO_P1 18
|
||||
#define PAL_SUP_PRIO_P2 20
|
||||
#define PAL_SUP_PRIO_P3 22
|
||||
#define PAL_SUP_PRIO_P4 24
|
||||
#define PAL_SUP_PRIO_P5 26
|
||||
#define PAL_UARTS_COUNT 4
|
||||
#define PAL_LINUX_NOSMP 1
|
||||
#define PAL_TRACE_ALARM_VAL 0
|
||||
#define PAL_SUP_MAX_MES 60
|
||||
#define CONFIG_PAL_USER_ASSERT 1
|
||||
#define TRUC_POURRI_YMM 1
|
||||
#define UNAME_RELEASE 2.6.28-16-generic
|
||||
#define PAL_BUTTON_MAX_HW_DRIVERS 1
|
||||
#define PAL_TRACE_MUTEX_VAL 0
|
||||
#define PAL_BUTTON_MAX_BUTTONS 32
|
||||
#define PAL_STACKSIZE 6144
|
||||
#define PAL_POSIX_MIX_PRIO 1
|
||||
#define PAL_POSIX_RT_PRIO_THRESHOLD 10
|
||||
@@ -14,7 +14,6 @@
|
||||
#include <win32_custom.h>
|
||||
#else
|
||||
#include <generated_custom.h>
|
||||
#include <autoconf.h>
|
||||
#endif
|
||||
|
||||
#undef ARDRONE_PIC_VERSION
|
||||
|
||||
@@ -157,8 +157,6 @@ extern const float32_t default_magneto_radius;
|
||||
|
||||
#define ARDRONE_DEFAULT_DATE "19700101_000000"
|
||||
#define ARDRONE_EMPTY_STRING ""
|
||||
#define ARDRONE_DEFAULT_TRAVELLING_MODE "0,10,1500,0,1000"
|
||||
|
||||
|
||||
#define CUSTOM_CONFIGURATION_DELETE_ALL_CMD "all"
|
||||
|
||||
@@ -283,8 +281,6 @@ ARDRONE_CONFIG_KEY_IMM_a10("control", outdoor_control_yaw, INI_FLOAT,
|
||||
ARDRONE_CONFIG_KEY_IMM_a10("control", flying_mode, INI_INT, int32_t, int32_t*, (K_READ|K_WRITE|K_NOBIND|K_SHALLOW), (K_READ|K_WRITE), 0, flying_mode_config_callback,CAT_SESSION)
|
||||
ARDRONE_CONFIG_KEY_IMM_a10("control", hovering_range, INI_INT, int32_t, int32_t*, (K_READ|K_WRITE|K_NOBIND|K_SHALLOW), (K_READ|K_WRITE), 1000, default_config_callback, CAT_SESSION)
|
||||
ARDRONE_CONFIG_KEY_STR_a10("control", flight_anim, INI_STRING, string_t, char*, (K_READ|K_WRITE|K_NOBIND|K_SHALLOW), 0, "0,0", flight_animation_selection_callback,CAT_COMMON)
|
||||
ARDRONE_CONFIG_KEY_STR_a10("control", travelling_mode, INI_STRING, string_t, char*, (K_READ|K_WRITE), (K_READ|K_WRITE), ARDRONE_DEFAULT_TRAVELLING_MODE, travelling_mode_selection_callback,CAT_USER)
|
||||
ARDRONE_CONFIG_KEY_IMM_a10("control", travelling_enable, INI_BOOLEAN, bool_t, bool_t*, (K_READ|K_WRITE|K_NOBIND|K_SHALLOW), 0, FALSE, travelling_enable_callback, CAT_COMMON)
|
||||
|
||||
ARDRONE_CONFIG_KEY_STR_a10("network", ssid_single_player, INI_STRING, string_t, char*, (K_READ|K_WRITE), 0, WIFI_NETWORK_NAME, default_config_callback, CAT_COMMON)
|
||||
ARDRONE_CONFIG_KEY_STR_a10("network", ssid_multi_player, INI_STRING, string_t, char*, (K_READ|K_WRITE), 0, WIFI_NETWORK_NAME, default_config_callback, CAT_COMMON)
|
||||
|
||||
@@ -72,7 +72,7 @@ typedef enum {
|
||||
CVAR( FLYING_ALT_OUT_ZONE ),
|
||||
CVAR( FLYING_COMBINED_YAW ),
|
||||
CVAR( FLYING_BRAKE ),
|
||||
CVAR( FLYING_NO_VISION )
|
||||
CVAR( FLYING_NO_VISION ),
|
||||
#ifndef CTRL_STATES_STRING
|
||||
} FLYING_STATES;
|
||||
#else
|
||||
|
||||
@@ -210,7 +210,7 @@ static const int32_t MAYDAY_TIMEOUT[ARDRONE_NB_ANIM_MAYDAY] = {
|
||||
|
||||
#define NAVDATA_HEADER 0x55667788
|
||||
|
||||
#define NAVDATA_MAX_SIZE 2048
|
||||
#define NAVDATA_MAX_SIZE 4096
|
||||
#define NAVDATA_MAX_CUSTOM_TIME_SAVE 20
|
||||
|
||||
/* !!! Warning !!! - changing the value below would break compatibility with older applications
|
||||
@@ -355,7 +355,6 @@ typedef struct _navdata_raw_measures_t {
|
||||
uint16_t nb_echo;
|
||||
uint32_t sum_echo;
|
||||
int32_t alt_temp_raw;
|
||||
|
||||
int16_t gradient;
|
||||
}_ATTRIBUTE_PACKED_ navdata_raw_measures_t;
|
||||
|
||||
@@ -395,8 +394,8 @@ typedef struct _navdata_wind_speed_t {
|
||||
uint16_t tag;
|
||||
uint16_t size;
|
||||
|
||||
float32_t wind_speed;
|
||||
float32_t wind_angle;
|
||||
float32_t wind_speed; // estimated wind speed [m/s]
|
||||
float32_t wind_angle; // estimated wind direction in North-East frame [rad] e.g. if wind_angle is pi/4, wind is from South-West to North-East
|
||||
float32_t wind_compensation_theta;
|
||||
float32_t wind_compensation_phi;
|
||||
float32_t state_x1;
|
||||
|
||||
@@ -77,6 +77,10 @@ GENERIC_LIBRARY_SOURCE_FILES+= \
|
||||
$(ARDRONE_TOOL_DIR)/Video/video_stage_decoder.c \
|
||||
$(ARDRONE_TOOL_DIR)/Video/video_recorder_pipeline.c \
|
||||
$(ARDRONE_TOOL_DIR)/Video/video_stage.c
|
||||
ifeq ($(USE_ANDROID),yes)
|
||||
GENERIC_LIBRARY_SOURCE_FILES+= \
|
||||
$(UTILS_DIR)/AR_Ftw.c
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(CONTROL_DLL),yes)
|
||||
@@ -165,7 +169,7 @@ export GENERIC_BINARIES_SOURCE_ENTRYPOINTS=
|
||||
all $(MAKECMDGOALS):
|
||||
@if [ '$(MAKECMDGOALS)' != 'clean' ]; then echo "$(OK_COLOR)Building ARDroneTool/Lib$(NO_COLOR)"; fi
|
||||
@$(MAKE) -C ../../../VP_SDK/Build $(TMP_SDK_FLAGS) $(SDK_FLAGS) $(MAKECMDGOALS)
|
||||
|
||||
|
||||
makefileverbose:
|
||||
@echo "Dump compilation flags:"
|
||||
@echo "GENERIC_CFLAGS : $(GENERIC_CFLAGS)"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <VP_Os/vp_os_assert.h>
|
||||
#include <VP_Os/vp_os_print.h>
|
||||
#include <VP_Os/vp_os_malloc.h>
|
||||
|
||||
#include <Maths/matrices.h>
|
||||
@@ -223,12 +224,12 @@ bool_t normalize_vec( vector31_t* v )
|
||||
|
||||
void display_matrix33(matrix33_t *m1)
|
||||
{
|
||||
printf("( %f\t%f\t%f )\n( %f\t%f\t%f )\n( %f\t%f\t%f )\n",m1->m11,m1->m12,m1->m13,m1->m21,m1->m22,m1->m23,m1->m31,m1->m32,m1->m33);
|
||||
PRINT("( %f\t%f\t%f )\n( %f\t%f\t%f )\n( %f\t%f\t%f )\n",m1->m11,m1->m12,m1->m13,m1->m21,m1->m22,m1->m23,m1->m31,m1->m32,m1->m33);
|
||||
}
|
||||
|
||||
void display_vector31(vector31_t *v1)
|
||||
{
|
||||
printf("( %f\t%f\t%f )\n", v1->x ,v1->y, v1->z);
|
||||
PRINT("( %f\t%f\t%f )\n", v1->x ,v1->y, v1->z);
|
||||
}
|
||||
|
||||
// matrix of size 4
|
||||
@@ -408,12 +409,12 @@ void inv_mat44(matrix44_t *out, matrix44_t* m1)
|
||||
|
||||
void display_matrix44(matrix44_t *m1)
|
||||
{
|
||||
printf("( %f\t%f\t%f\t%f )\n( %f\t%f\t%f\t%f )\n( %f\t%f\t%f\t%f )\n( %f\t%f\t%f\t%f )\n",m1->m11,m1->m12,m1->m13,m1->m14,m1->m21,m1->m22,m1->m23,m1->m24,m1->m31,m1->m32,m1->m33,m1->m34,m1->m41,m1->m42,m1->m43,m1->m44);
|
||||
PRINT("( %f\t%f\t%f\t%f )\n( %f\t%f\t%f\t%f )\n( %f\t%f\t%f\t%f )\n( %f\t%f\t%f\t%f )\n",m1->m11,m1->m12,m1->m13,m1->m14,m1->m21,m1->m22,m1->m23,m1->m24,m1->m31,m1->m32,m1->m33,m1->m34,m1->m41,m1->m42,m1->m43,m1->m44);
|
||||
}
|
||||
|
||||
void display_vector41(vector41_t *v1)
|
||||
{
|
||||
printf("( %f\t%f\t%f\t%f )\n", v1->x1 ,v1->x2, v1->x3, v1->x4);
|
||||
PRINT("( %f\t%f\t%f\t%f )\n", v1->x1 ,v1->x2, v1->x3, v1->x4);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -146,7 +146,7 @@ C_RESULT matrix3d_orientation(matrix3d_t* m, const vector31_t* pos, const vector
|
||||
return C_OK;
|
||||
}
|
||||
|
||||
#define MATRIX_EXCHANGE( out, in ) temp = out; out = in; in = out
|
||||
#define MATRIX_EXCHANGE( out, in ) temp = out; out = in; in = temp
|
||||
|
||||
C_RESULT matrix3d_transpose(matrix3d_t* out, matrix3d_t* in)
|
||||
{
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <VP_Os/vp_os_print.h>
|
||||
#include <ardrone_tool/Com/config_com.h>
|
||||
#include <ardrone_tool/ardrone_tool.h>
|
||||
#include <ardrone_tool/ardrone_version.h>
|
||||
|
||||
//Common
|
||||
#include <ardrone_api.h>
|
||||
@@ -160,16 +161,27 @@ AT_CODEC_ERROR_CODE host_open( void )
|
||||
PRINT ("Error setting SND_BUF for AT socket\n");
|
||||
}
|
||||
|
||||
int opt = IPTOS_PREC_NETCONTROL;
|
||||
int res = setsockopt((int)at_socket.priv, IPPROTO_IP, IP_TOS, &opt, (socklen_t)sizeof(opt));
|
||||
if (res)
|
||||
/*
|
||||
* On android, with IP_TOS set, certain devices can't connect to AR.Drone 1
|
||||
* So we just disable this functionnality to avoid these cases.
|
||||
*/
|
||||
#ifdef USE_ANDROID
|
||||
if (IS_ARDRONE2)
|
||||
{
|
||||
perror("AT stage - setting Live video socket IP Type Of Service : ");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("Set IP_TOS ok\n");
|
||||
#endif
|
||||
int opt = IPTOS_PREC_NETCONTROL;
|
||||
int res = setsockopt((int)at_socket.priv, IPPROTO_IP, IP_TOS, &opt, (socklen_t)sizeof(opt));
|
||||
if (res)
|
||||
{
|
||||
perror("AT stage - setting Live video socket IP Type Of Service : ");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("Set IP_TOS ok\n");
|
||||
}
|
||||
#ifdef USE_ANDROID
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -306,6 +318,7 @@ void ardrone_at_set_flat_trim(void)
|
||||
{
|
||||
if (!at_init)
|
||||
return;
|
||||
|
||||
vp_os_mutex_lock(&at_mutex);
|
||||
ATcodec_Queue_Message_valist( ids.AT_MSG_ATCMD_FTRIM_EXE,
|
||||
++nb_sequence );
|
||||
|
||||
@@ -219,7 +219,7 @@ DEFINE_THREAD_ROUTINE(academy, data)
|
||||
academy.flight_sum = 0;
|
||||
academy.flight_oldest_date[0] = '\0';
|
||||
|
||||
if(!ftw(flight_dir, &academy_compute_memory_used, 1))
|
||||
if(!ftw(flight_dir, &academy_compute_memory_used, ACADEMY_MAX_FD_FOR_FTW))
|
||||
{
|
||||
if(academy.flight_sum > MBYTE_TO_BYTE(academy.flight_max_storing_size))
|
||||
{
|
||||
@@ -229,17 +229,21 @@ DEFINE_THREAD_ROUTINE(academy, data)
|
||||
// remove oldest flight
|
||||
PA_WARNING("Too much memory used %d MB > %d MB, removing oldest flight %s...", BYTE_TO_MBYTE(academy.flight_sum), academy.flight_max_storing_size, remove_dir);
|
||||
|
||||
if(!ftw(remove_dir, &academy_remove, 1))
|
||||
if(!ftw(remove_dir, &academy_remove, ACADEMY_MAX_FD_FOR_FTW))
|
||||
{
|
||||
rmdir(remove_dir);
|
||||
PA_WARNING("OK.\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
needToCheckMemory = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
needToCheckMemory = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,11 +17,17 @@
|
||||
#include <utils/ardrone_ftp.h>
|
||||
#include <VP_Os/vp_os_delay.h>
|
||||
#include <VP_Os/vp_os_thread.h>
|
||||
#include <VP_Os/vp_os_print.h>
|
||||
#include <VP_Os/vp_os_malloc.h>
|
||||
#include <VP_Os/vp_os_signal.h>
|
||||
#include <stdio.h>
|
||||
#include <dirent.h>
|
||||
#ifndef USE_ANDROID
|
||||
#include <ftw.h>
|
||||
#else
|
||||
#include <utils/AR_Ftw.h>
|
||||
#endif
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
@@ -40,6 +46,7 @@
|
||||
#define ACADEMY_MAX_LIST 1024
|
||||
#define ACADEMY_MAX_LINE 128
|
||||
#define ACADEMY_MAX_FILENAME 256
|
||||
#define ACADEMY_MAX_FD_FOR_FTW 20
|
||||
|
||||
#define PA_PREFIX "PA : "
|
||||
|
||||
@@ -47,26 +54,26 @@
|
||||
#define PA_DEBUG(...) \
|
||||
do \
|
||||
{ \
|
||||
printf (PA_PREFIX); \
|
||||
printf (__VA_ARGS__); \
|
||||
PRINT (PA_PREFIX); \
|
||||
PRINT (__VA_ARGS__); \
|
||||
} while (0)
|
||||
#define PA_WARNING(...) \
|
||||
do \
|
||||
{ \
|
||||
printf (PA_PREFIX); \
|
||||
printf (__VA_ARGS__); \
|
||||
PRINT (PA_PREFIX); \
|
||||
PRINT (__VA_ARGS__); \
|
||||
} while (0)
|
||||
#else
|
||||
#define PA_DEBUG(...)
|
||||
#define PA_WARNING(...) \
|
||||
do \
|
||||
{ \
|
||||
printf (PA_PREFIX); \
|
||||
printf (__VA_ARGS__); \
|
||||
PRINT (PA_PREFIX); \
|
||||
PRINT (__VA_ARGS__); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#define ACADEMY_SERVERNAME ""
|
||||
#define ACADEMY_SERVERNAME "parrot01.nyx.emencia.net"
|
||||
#define ACADEMY_PORT 21
|
||||
#define BYTE_TO_MBYTE(a) (a / 1048576)
|
||||
#define MBYTE_TO_BYTE(a) (a * 1048576)
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
typedef struct _academy_download_t_
|
||||
{
|
||||
academy_callback callback;
|
||||
academy_download_new_media new_media_callback;
|
||||
academy_state_t state;
|
||||
academy_download_new_media new_media_callback;
|
||||
academy_state_t state;
|
||||
} academy_download_t;
|
||||
|
||||
PROTO_THREAD_ROUTINE(academy_download, data);
|
||||
@@ -27,120 +27,120 @@ static vp_os_cond_t academy_download_cond;
|
||||
static void academy_download_private_callback(academy_state_t state)
|
||||
{
|
||||
static char msg[DISPLAY_STRING_LENGTH] = { 0 };
|
||||
switch(state.result)
|
||||
{
|
||||
case ACADEMY_RESULT_NONE:
|
||||
switch(state.state)
|
||||
{
|
||||
case ACADEMY_STATE_CONNECTION:
|
||||
snprintf (msg, DISPLAY_STRING_LENGTH, "Connecting to %s...", &wifi_ardrone_ip[0]);
|
||||
break;
|
||||
switch(state.result)
|
||||
{
|
||||
case ACADEMY_RESULT_NONE:
|
||||
switch(state.state)
|
||||
{
|
||||
case ACADEMY_STATE_CONNECTION:
|
||||
snprintf (msg, DISPLAY_STRING_LENGTH, "Connecting to %s...", &wifi_ardrone_ip[0]);
|
||||
break;
|
||||
|
||||
case ACADEMY_STATE_PREPARE_PROCESS:
|
||||
snprintf (msg, DISPLAY_STRING_LENGTH, "Preparing download from %s to local directory...", &wifi_ardrone_ip[0]);
|
||||
break;
|
||||
case ACADEMY_STATE_PREPARE_PROCESS:
|
||||
snprintf (msg, DISPLAY_STRING_LENGTH, "Preparing download from %s to local directory...", &wifi_ardrone_ip[0]);
|
||||
break;
|
||||
|
||||
case ACADEMY_STATE_PROCESS:
|
||||
snprintf (msg, DISPLAY_STRING_LENGTH, "Downloading from %s to local directory...", &wifi_ardrone_ip[0]);
|
||||
break;
|
||||
case ACADEMY_STATE_PROCESS:
|
||||
snprintf (msg, DISPLAY_STRING_LENGTH, "Downloading from %s to local directory...", &wifi_ardrone_ip[0]);
|
||||
break;
|
||||
|
||||
case ACADEMY_STATE_FINISH_PROCESS:
|
||||
snprintf (msg, DISPLAY_STRING_LENGTH, "Finishing download from %s to local directory...", &wifi_ardrone_ip[0]);
|
||||
break;
|
||||
case ACADEMY_STATE_FINISH_PROCESS:
|
||||
snprintf (msg, DISPLAY_STRING_LENGTH, "Finishing download from %s to local directory...", &wifi_ardrone_ip[0]);
|
||||
break;
|
||||
|
||||
case ACADEMY_STATE_DISCONNECTION:
|
||||
snprintf (msg, DISPLAY_STRING_LENGTH, "Disconnection to %s...", &wifi_ardrone_ip[0]);
|
||||
break;
|
||||
case ACADEMY_STATE_DISCONNECTION:
|
||||
snprintf (msg, DISPLAY_STRING_LENGTH, "Disconnection to %s...", &wifi_ardrone_ip[0]);
|
||||
break;
|
||||
|
||||
case ACADEMY_STATE_NONE:
|
||||
strncpy(msg, "", DISPLAY_STRING_LENGTH);
|
||||
break;
|
||||
case ACADEMY_STATE_NONE:
|
||||
strncpy(msg, "", DISPLAY_STRING_LENGTH);
|
||||
break;
|
||||
|
||||
default:
|
||||
strncpy(msg, "", DISPLAY_STRING_LENGTH);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
strncpy(msg, "", DISPLAY_STRING_LENGTH);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ACADEMY_RESULT_OK:
|
||||
strncat(msg, "OK", DISPLAY_STRING_LENGTH - strlen (msg));
|
||||
break;
|
||||
case ACADEMY_RESULT_OK:
|
||||
strncat(msg, "OK", DISPLAY_STRING_LENGTH - strlen (msg));
|
||||
break;
|
||||
|
||||
case ACADEMY_RESULT_FAILED:
|
||||
strncat(msg, "FAILED", DISPLAY_STRING_LENGTH - strlen (msg));
|
||||
break;
|
||||
}
|
||||
|
||||
if(strlen(msg) != 0)
|
||||
PA_DEBUG("===========> %s\n", msg);
|
||||
case ACADEMY_RESULT_FAILED:
|
||||
strncat(msg, "FAILED", DISPLAY_STRING_LENGTH - strlen (msg));
|
||||
break;
|
||||
}
|
||||
|
||||
if(strlen(msg) != 0)
|
||||
PA_DEBUG("===========> %s\n", msg);
|
||||
}
|
||||
|
||||
static void academy_download_resetState(academy_download_t *academy)
|
||||
{
|
||||
academy_resetState(&academy->state);
|
||||
if(academy->callback)
|
||||
academy->callback(academy->state);
|
||||
academy_resetState(&academy->state);
|
||||
if(academy->callback)
|
||||
academy->callback(academy->state);
|
||||
}
|
||||
|
||||
static void academy_download_nextState(academy_download_t *academy)
|
||||
{
|
||||
academy_nextState(&academy->state);
|
||||
if(academy->callback)
|
||||
academy->callback(academy->state);
|
||||
academy_nextState(&academy->state);
|
||||
if(academy->callback)
|
||||
academy->callback(academy->state);
|
||||
}
|
||||
|
||||
static void academy_download_stateOK(academy_download_t *academy)
|
||||
{
|
||||
academy_stateOK(&academy->state);
|
||||
if(academy->callback)
|
||||
academy->callback(academy->state);
|
||||
academy_stateOK(&academy->state);
|
||||
if(academy->callback)
|
||||
academy->callback(academy->state);
|
||||
}
|
||||
|
||||
static void academy_download_stateERROR(academy_download_t *academy)
|
||||
{
|
||||
academy_stateERROR(&academy->state);
|
||||
if(academy->callback)
|
||||
academy->callback(academy->state);
|
||||
academy_download_resetState(academy);
|
||||
academy_stateERROR(&academy->state);
|
||||
if(academy->callback)
|
||||
academy->callback(academy->state);
|
||||
academy_download_resetState(academy);
|
||||
}
|
||||
|
||||
void academy_download_init(academy_download_new_media academy_download_callback_func)
|
||||
{
|
||||
if(!academy_download_started)
|
||||
{
|
||||
if(!academy_download_started)
|
||||
{
|
||||
vp_os_mutex_init (&academy_download_mutex);
|
||||
vp_os_cond_init (&academy_download_cond, &academy_download_mutex);
|
||||
academy_download_started = TRUE;
|
||||
vp_os_thread_create(thread_academy_download, (THREAD_PARAMS)academy_download_callback_func, &academy_download_thread);
|
||||
}
|
||||
academy_download_started = TRUE;
|
||||
vp_os_thread_create(thread_academy_download, (THREAD_PARAMS)academy_download_callback_func, &academy_download_thread);
|
||||
}
|
||||
}
|
||||
|
||||
void academy_download_shutdown(void)
|
||||
{
|
||||
if(academy_download_started)
|
||||
{
|
||||
academy_download_started = FALSE;
|
||||
if(academy_download_started)
|
||||
{
|
||||
academy_download_started = FALSE;
|
||||
academy_download_resume ();
|
||||
vp_os_thread_join(academy_download_thread);
|
||||
}
|
||||
vp_os_thread_join(academy_download_thread);
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_THREAD_ROUTINE(academy_download, data)
|
||||
{
|
||||
char *directoryList = NULL;
|
||||
char *directoryList = NULL;
|
||||
bool_t shouldGoInPause = FALSE;
|
||||
char *fileList = NULL;
|
||||
char process_dirname[ACADEMY_MAX_FILENAME];
|
||||
_ftp_t *academy_ftp = NULL;
|
||||
_ftp_status academy_status;
|
||||
struct stat statbuf;
|
||||
char *ptr = NULL;
|
||||
academy_download_t academy;
|
||||
|
||||
char *fileList = NULL;
|
||||
char process_dirname[ACADEMY_MAX_FILENAME];
|
||||
_ftp_t *academy_ftp = NULL;
|
||||
_ftp_status academy_status;
|
||||
struct stat statbuf;
|
||||
char *ptr = NULL;
|
||||
academy_download_t academy;
|
||||
|
||||
academy.new_media_callback = (academy_download_new_media)data;
|
||||
academy.callback = academy_download_private_callback;
|
||||
|
||||
printf("Start thread %s \n", __FUNCTION__);
|
||||
|
||||
PRINT("Start thread %s \n", __FUNCTION__);
|
||||
do
|
||||
{
|
||||
academy_download_resetState(&academy);
|
||||
@@ -148,257 +148,264 @@ DEFINE_THREAD_ROUTINE(academy_download, data)
|
||||
if (TRUE == academy_download_in_pause)
|
||||
{
|
||||
vp_os_mutex_lock (&academy_download_mutex);
|
||||
printf ("Academy download stage paused\n");
|
||||
PRINT ("Academy download stage paused\n");
|
||||
vp_os_cond_wait (&academy_download_cond);
|
||||
vp_os_mutex_unlock (&academy_download_mutex);
|
||||
}
|
||||
academy_download_pause();
|
||||
printf ("Academy download stage resumed\n");
|
||||
PRINT ("Academy download stage resumed\n");
|
||||
academy_download_nextState(&academy);
|
||||
|
||||
while( academy_download_started && !shouldGoInPause)
|
||||
{
|
||||
academy_status = FTP_FAIL;
|
||||
|
||||
switch(academy.state.state)
|
||||
while( academy_download_started && !shouldGoInPause)
|
||||
{
|
||||
academy_status = FTP_FAIL;
|
||||
|
||||
switch(academy.state.state)
|
||||
{
|
||||
case ACADEMY_STATE_NONE:
|
||||
case ACADEMY_STATE_NONE:
|
||||
academy_status = FTP_SUCCESS;
|
||||
break;
|
||||
|
||||
case ACADEMY_STATE_CONNECTION:
|
||||
if(academy_ftp == NULL)
|
||||
academy_ftp = ftpConnect(&wifi_ardrone_ip[0], ACADEMY_PORT, "anonymous", "", &academy_status);
|
||||
|
||||
if(academy_ftp != NULL)
|
||||
academy_status = FTP_SUCCESS;
|
||||
break;
|
||||
|
||||
case ACADEMY_STATE_CONNECTION:
|
||||
if(academy_ftp == NULL)
|
||||
academy_ftp = ftpConnect(&wifi_ardrone_ip[0], ACADEMY_PORT, "anonymous", "", &academy_status);
|
||||
break;
|
||||
|
||||
if(academy_ftp != NULL)
|
||||
academy_status = FTP_SUCCESS;
|
||||
break;
|
||||
case ACADEMY_STATE_PREPARE_PROCESS:
|
||||
academy_status = ftpCd(academy_ftp, "/boxes");
|
||||
if(FTP_SUCCEDED(academy_status))
|
||||
{
|
||||
char *next_dir = NULL;
|
||||
PA_DEBUG("Enter to boxes directory\n");
|
||||
academy_status = ftpList(academy_ftp, &directoryList, NULL);
|
||||
|
||||
case ACADEMY_STATE_PREPARE_PROCESS:
|
||||
academy_status = ftpCd(academy_ftp, "/boxes");
|
||||
if(FTP_SUCCEDED(academy_status))
|
||||
{
|
||||
char *next_dir = NULL;
|
||||
PA_DEBUG("Enter to boxes directory\n");
|
||||
academy_status = ftpList(academy_ftp, &directoryList, NULL);
|
||||
// If directory is empty, we consider that it is an error
|
||||
if(academy_status == FTP_SAMESIZE)
|
||||
academy_status = FTP_FAIL;
|
||||
|
||||
// If directory is empty, we consider that it is an error
|
||||
if(academy_status == FTP_SAMESIZE)
|
||||
academy_status = FTP_FAIL;
|
||||
|
||||
if(FTP_SUCCEDED(academy_status))
|
||||
{
|
||||
char local_dir[ACADEMY_MAX_FILENAME];
|
||||
// Search if it stay ftpremove_* directories to continue removing
|
||||
PA_DEBUG("Get directory list :\n%s", directoryList);
|
||||
while(FTP_SUCCEDED(academy_status) && (ptr = academy_get_next_item_with_prefix(directoryList, &next_dir, "ftpremove_downloading_", TRUE)))
|
||||
{
|
||||
char remove_dirname[ACADEMY_MAX_FILENAME];
|
||||
if(FTP_SUCCEDED(academy_status))
|
||||
{
|
||||
char local_dir[ACADEMY_MAX_FILENAME];
|
||||
// Search if it stay ftpremove_* directories to continue removing
|
||||
PA_DEBUG("Get directory list :\n%s", directoryList);
|
||||
while(FTP_SUCCEDED(academy_status) && (ptr = academy_get_next_item_with_prefix(directoryList, &next_dir, "ftpremove_downloading_", TRUE)))
|
||||
{
|
||||
char remove_dirname[ACADEMY_MAX_FILENAME];
|
||||
strncpy(remove_dirname, ptr, ACADEMY_MAX_FILENAME);
|
||||
academy_status = academy_remove_ftp_directory(academy_ftp, remove_dirname);
|
||||
}
|
||||
academy_status = academy_remove_ftp_directory(academy_ftp, remove_dirname);
|
||||
}
|
||||
|
||||
academy_status = FTP_FAIL;
|
||||
next_dir = NULL;
|
||||
// Search if it stay downloading_flight_* file to continue downloading.
|
||||
ptr = academy_get_next_item_with_prefix(directoryList, &next_dir, "downloading_flight_", TRUE);
|
||||
// Check if transfer was in progress
|
||||
if(ptr != NULL)
|
||||
{
|
||||
// Transfer was in progress
|
||||
PA_DEBUG("Transfer was in progress\n");
|
||||
strncpy(process_dirname, ptr, ACADEMY_MAX_FILENAME);
|
||||
snprintf(local_dir, ACADEMY_MAX_FILENAME, "%s/%s", flight_dir, process_dirname);
|
||||
if((stat(local_dir, &statbuf) == 0) && S_ISDIR(statbuf.st_mode))
|
||||
{
|
||||
// Transfer was in progress by current device
|
||||
PA_DEBUG("Transfer was in progress by current device\n");
|
||||
academy_status = FTP_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Transfer was in progress by an other device => Create local directory
|
||||
PA_DEBUG("Transfer was in progress by an other device\n");
|
||||
printf("Creating local directory %s\n", local_dir);
|
||||
if(mkdir(local_dir, 0777) >= 0)
|
||||
{
|
||||
PA_DEBUG("Create local directory %s\n", local_dir);
|
||||
academy_status = FTP_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PA_DEBUG(" Transfer was not in progress\n");
|
||||
// Transfer was not in progress => Get oldest flight, rename remote directory and create local directory
|
||||
next_dir = NULL;
|
||||
ptr = academy_get_next_item_with_prefix(directoryList, &next_dir, "flight_", TRUE);
|
||||
if(ptr != NULL)
|
||||
{
|
||||
// Prepare to process new transfer
|
||||
PA_DEBUG("Prepare to process new transfer\n");
|
||||
snprintf(process_dirname, ACADEMY_MAX_FILENAME, "downloading_%s", ptr);
|
||||
academy_status = ftpRename(academy_ftp, ptr, process_dirname);
|
||||
if(FTP_SUCCEDED(academy_status))
|
||||
{
|
||||
PA_DEBUG("Rename %s to %s directory\n", ptr, process_dirname);
|
||||
academy_status = FTP_FAIL;
|
||||
next_dir = NULL;
|
||||
// Search if it stay downloading_flight_* file to continue downloading.
|
||||
ptr = academy_get_next_item_with_prefix(directoryList, &next_dir, "downloading_flight_", TRUE);
|
||||
// Check if transfer was in progress
|
||||
if(ptr != NULL)
|
||||
{
|
||||
// Transfer was in progress
|
||||
PA_DEBUG("Transfer was in progress\n");
|
||||
strncpy(process_dirname, ptr, ACADEMY_MAX_FILENAME);
|
||||
snprintf(local_dir, ACADEMY_MAX_FILENAME, "%s/%s", flight_dir, process_dirname);
|
||||
if((stat(local_dir, &statbuf) == 0) && S_ISDIR(statbuf.st_mode))
|
||||
{
|
||||
// Transfer was in progress by current device
|
||||
PA_DEBUG("Transfer was in progress by current device\n");
|
||||
academy_status = FTP_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Transfer was in progress by an other device => Create local directory
|
||||
PA_DEBUG("Transfer was in progress by an other device\n");
|
||||
PRINT("Creating local directory %s\n", local_dir);
|
||||
if(mkdir(local_dir, 0777) >= 0)
|
||||
{
|
||||
PA_DEBUG("Create local directory %s\n", local_dir);
|
||||
academy_status = FTP_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PA_DEBUG(" Transfer was not in progress\n");
|
||||
// Transfer was not in progress => Get oldest flight, rename remote directory and create local directory
|
||||
next_dir = NULL;
|
||||
ptr = academy_get_next_item_with_prefix(directoryList, &next_dir, "flight_", TRUE);
|
||||
if(ptr != NULL)
|
||||
{
|
||||
// Prepare to process new transfer
|
||||
PA_DEBUG("Prepare to process new transfer\n");
|
||||
snprintf(process_dirname, ACADEMY_MAX_FILENAME, "downloading_%s", ptr);
|
||||
academy_status = ftpRename(academy_ftp, ptr, process_dirname);
|
||||
if(FTP_SUCCEDED(academy_status))
|
||||
{
|
||||
PA_DEBUG("Rename %s to %s directory\n", ptr, process_dirname);
|
||||
snprintf(local_dir, ACADEMY_MAX_FILENAME, "%s/%s", flight_dir, process_dirname);
|
||||
if((stat(local_dir, &statbuf) != 0) && (mkdir(local_dir, 0777) >= 0))
|
||||
PA_DEBUG("Create local directory %s if not exist\n", local_dir);
|
||||
academy_status = FTP_SUCCESS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
shouldGoInPause = TRUE;
|
||||
if((stat(local_dir, &statbuf) != 0) && (mkdir(local_dir, 0777) >= 0))
|
||||
PA_DEBUG("Create local directory %s if not exist\n", local_dir);
|
||||
academy_status = FTP_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
shouldGoInPause = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if(directoryList != NULL)
|
||||
{
|
||||
vp_os_free(directoryList);
|
||||
directoryList = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
if(directoryList != NULL)
|
||||
{
|
||||
vp_os_free(directoryList);
|
||||
directoryList = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ACADEMY_STATE_PROCESS:
|
||||
academy_status = ftpCd(academy_ftp, process_dirname);
|
||||
if(FTP_SUCCEDED(academy_status))
|
||||
{
|
||||
PA_DEBUG("Enter to %s directory\n", process_dirname);
|
||||
academy_status = ftpList(academy_ftp, &fileList, NULL);
|
||||
if(FTP_SUCCEDED(academy_status))
|
||||
{
|
||||
char *next_file = NULL;
|
||||
char media_dirname[ACADEMY_MAX_FILENAME];
|
||||
char local_filename[ACADEMY_MAX_FILENAME];
|
||||
bool_t userbox_ready = FALSE;
|
||||
case ACADEMY_STATE_PROCESS:
|
||||
academy_status = ftpCd(academy_ftp, process_dirname);
|
||||
if(FTP_SUCCEDED(academy_status))
|
||||
{
|
||||
PA_DEBUG("Enter to %s directory\n", process_dirname);
|
||||
academy_status = ftpList(academy_ftp, &fileList, NULL);
|
||||
if(FTP_SUCCEDED(academy_status))
|
||||
{
|
||||
char *next_file = NULL;
|
||||
char media_dirname[ACADEMY_MAX_FILENAME];
|
||||
char local_filename[ACADEMY_MAX_FILENAME];
|
||||
bool_t userbox_ready = FALSE;
|
||||
|
||||
PA_DEBUG("Get file list :\n%s", fileList);
|
||||
ptr = academy_get_next_item_with_prefix(fileList, &next_file, "userbox_", FALSE);
|
||||
if(ptr != NULL)
|
||||
{
|
||||
snprintf(local_filename, ACADEMY_MAX_FILENAME, "%s/%s/%s", flight_dir, process_dirname, ptr);
|
||||
PA_DEBUG("Get %s from drone to local directory...", local_filename);
|
||||
academy_status = ftpGet (academy_ftp, ptr, local_filename, 1, NULL);
|
||||
if(FTP_SUCCEDED(academy_status))
|
||||
{
|
||||
userbox_ready = TRUE;
|
||||
PA_DEBUG("OK\n");
|
||||
}
|
||||
else
|
||||
PA_DEBUG("ERROR\n");
|
||||
}
|
||||
PA_DEBUG("Get file list :\n%s", fileList);
|
||||
ptr = academy_get_next_item_with_prefix(fileList, &next_file, "userbox_", FALSE);
|
||||
if(ptr != NULL)
|
||||
{
|
||||
snprintf(local_filename, ACADEMY_MAX_FILENAME, "%s/%s/%s", flight_dir, process_dirname, ptr);
|
||||
PA_DEBUG("Get %s from drone to local directory...", local_filename);
|
||||
academy_status = ftpGet (academy_ftp, ptr, local_filename, 1, NULL);
|
||||
if(FTP_SUCCEDED(academy_status))
|
||||
{
|
||||
userbox_ready = TRUE;
|
||||
PA_DEBUG("OK\n");
|
||||
}
|
||||
else
|
||||
PA_DEBUG("ERROR\n");
|
||||
}
|
||||
|
||||
snprintf(media_dirname, ACADEMY_MAX_FILENAME, "%s/media_%s", flight_dir, process_dirname + (strlen("downloading_flight_")));
|
||||
//printf("medias directory : %s\n", media_dirname);
|
||||
next_file = NULL;
|
||||
while(FTP_SUCCEDED(academy_status) && (ptr = academy_get_next_item_with_prefix(fileList, &next_file, "picture_", FALSE)))
|
||||
{
|
||||
if((stat(media_dirname, &statbuf) != 0) && (mkdir(media_dirname, 0777) >= 0))
|
||||
PA_DEBUG("Create local media directory %s if not exist\n", media_dirname);
|
||||
snprintf(media_dirname, ACADEMY_MAX_FILENAME, "%s/media_%s", flight_dir, process_dirname + (strlen("downloading_flight_")));
|
||||
//PRINT("medias directory : %s\n", media_dirname);
|
||||
next_file = NULL;
|
||||
while(FTP_SUCCEDED(academy_status) && (ptr = academy_get_next_item_with_prefix(fileList, &next_file, "picture_", FALSE)))
|
||||
{
|
||||
if((stat(media_dirname, &statbuf) != 0) && (mkdir(media_dirname, 0777) >= 0))
|
||||
PA_DEBUG("Create local media directory %s if not exist\n", media_dirname);
|
||||
|
||||
sprintf(local_filename, "%s/%s", media_dirname, ptr);
|
||||
PA_DEBUG("Get %s from drone to local directory...", local_filename);
|
||||
academy_status = ftpGet (academy_ftp, ptr, local_filename, 1, NULL);
|
||||
if(FTP_SUCCEDED(academy_status))
|
||||
{
|
||||
academy.new_media_callback((const char *)local_filename);
|
||||
PA_DEBUG("OK\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
PA_DEBUG("ERROR\n");
|
||||
}
|
||||
}
|
||||
sprintf(local_filename, "%s/%s", media_dirname, ptr);
|
||||
PA_DEBUG("Get %s from drone to local directory...", local_filename);
|
||||
academy_status = ftpGet (academy_ftp, ptr, local_filename, 1, NULL);
|
||||
if(FTP_SUCCEDED(academy_status))
|
||||
{
|
||||
if (NULL != academy.new_media_callback)
|
||||
{
|
||||
academy.new_media_callback((const char *)local_filename, TRUE);
|
||||
}
|
||||
PA_DEBUG("OK\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
PA_DEBUG("ERROR\n");
|
||||
}
|
||||
}
|
||||
if (NULL != academy.new_media_callback)
|
||||
{
|
||||
academy.new_media_callback((const char *)NULL, FALSE);
|
||||
}
|
||||
|
||||
if(FTP_SUCCEDED(academy_status) && !userbox_ready)
|
||||
{
|
||||
char local_dirname[ACADEMY_MAX_FILENAME];
|
||||
snprintf(local_dirname, ACADEMY_MAX_FILENAME, "%s/%s", flight_dir, process_dirname);
|
||||
remove(local_dirname);
|
||||
}
|
||||
}
|
||||
if(FTP_SUCCEDED(academy_status) && !userbox_ready)
|
||||
{
|
||||
char local_dirname[ACADEMY_MAX_FILENAME];
|
||||
snprintf(local_dirname, ACADEMY_MAX_FILENAME, "%s/%s", flight_dir, process_dirname);
|
||||
remove(local_dirname);
|
||||
}
|
||||
}
|
||||
|
||||
if(FTP_SUCCEDED(academy_status))
|
||||
ftpCd(academy_ftp, "..");
|
||||
}
|
||||
break;
|
||||
if(FTP_SUCCEDED(academy_status))
|
||||
ftpCd(academy_ftp, "..");
|
||||
}
|
||||
break;
|
||||
|
||||
case ACADEMY_STATE_FINISH_PROCESS:
|
||||
{
|
||||
char remove_dirname[ACADEMY_MAX_FILENAME];
|
||||
char src[ACADEMY_MAX_FILENAME];
|
||||
char dest[ACADEMY_MAX_FILENAME];
|
||||
case ACADEMY_STATE_FINISH_PROCESS:
|
||||
{
|
||||
char remove_dirname[ACADEMY_MAX_FILENAME];
|
||||
char src[ACADEMY_MAX_FILENAME];
|
||||
char dest[ACADEMY_MAX_FILENAME];
|
||||
|
||||
// Rename local directory from downloading_flight_* to flight_*
|
||||
snprintf(src, ACADEMY_MAX_FILENAME, "%s/%s", flight_dir, process_dirname);
|
||||
snprintf(dest, ACADEMY_MAX_FILENAME, "%s/%s", flight_dir, process_dirname + strlen("downloading_"));
|
||||
rename(src, dest);
|
||||
// Rename local directory from downloading_flight_* to flight_*
|
||||
snprintf(src, ACADEMY_MAX_FILENAME, "%s/%s", flight_dir, process_dirname);
|
||||
snprintf(dest, ACADEMY_MAX_FILENAME, "%s/%s", flight_dir, process_dirname + strlen("downloading_"));
|
||||
rename(src, dest);
|
||||
|
||||
// Rename ftp remote directory from downloading_flight_* to ftpremove_downloading_flight_*
|
||||
snprintf(remove_dirname, ACADEMY_MAX_FILENAME, "ftpremove_%s", process_dirname);
|
||||
academy_status = ftpRename(academy_ftp, process_dirname, remove_dirname);
|
||||
// Rename ftp remote directory from downloading_flight_* to ftpremove_downloading_flight_*
|
||||
snprintf(remove_dirname, ACADEMY_MAX_FILENAME, "ftpremove_%s", process_dirname);
|
||||
academy_status = ftpRename(academy_ftp, process_dirname, remove_dirname);
|
||||
|
||||
// Delete ftpremove_downloading_flight_*
|
||||
if(FTP_SUCCEDED(academy_status))
|
||||
academy_status = academy_remove_ftp_directory(academy_ftp, remove_dirname);
|
||||
}
|
||||
break;
|
||||
// Delete ftpremove_downloading_flight_*
|
||||
if(FTP_SUCCEDED(academy_status))
|
||||
academy_status = academy_remove_ftp_directory(academy_ftp, remove_dirname);
|
||||
}
|
||||
break;
|
||||
|
||||
case ACADEMY_STATE_DISCONNECTION:
|
||||
if(academy_ftp != NULL)
|
||||
ftpClose(&academy_ftp);
|
||||
academy_check_memory();
|
||||
academy_status = FTP_SUCCESS;
|
||||
break;
|
||||
case ACADEMY_STATE_DISCONNECTION:
|
||||
if(academy_ftp != NULL)
|
||||
ftpClose(&academy_ftp);
|
||||
academy_check_memory();
|
||||
academy_status = FTP_SUCCESS;
|
||||
break;
|
||||
|
||||
default:
|
||||
// Nothing to do
|
||||
PA_DEBUG("THIS CASE SHOULD NOT HAPPEN\n");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// Nothing to do
|
||||
PA_DEBUG("THIS CASE SHOULD NOT HAPPEN\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if(FTP_SUCCEDED(academy_status))
|
||||
{
|
||||
PA_DEBUG("continue state from %d to %d\n", academy.state.state, (academy.state.state + 1) % ACADEMY_STATE_MAX);
|
||||
academy_download_stateOK(&academy);
|
||||
if(FTP_SUCCEDED(academy_status))
|
||||
{
|
||||
PA_DEBUG("continue state from %d to %d\n", academy.state.state, (academy.state.state + 1) % ACADEMY_STATE_MAX);
|
||||
academy_download_stateOK(&academy);
|
||||
academy_download_nextState(&academy);
|
||||
}
|
||||
else
|
||||
{
|
||||
PA_DEBUG("stop\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
PA_DEBUG("stop\n");
|
||||
shouldGoInPause = TRUE;
|
||||
academy_download_stateERROR(&academy);
|
||||
|
||||
if(fileList != NULL)
|
||||
{
|
||||
vp_os_free(fileList);
|
||||
fileList = NULL;
|
||||
}
|
||||
|
||||
if(academy_ftp)
|
||||
ftpClose(&academy_ftp);
|
||||
}
|
||||
}
|
||||
if(fileList != NULL)
|
||||
{
|
||||
vp_os_free(fileList);
|
||||
fileList = NULL;
|
||||
}
|
||||
|
||||
if(fileList != NULL)
|
||||
{
|
||||
vp_os_free(fileList);
|
||||
fileList = NULL;
|
||||
}
|
||||
if(academy_ftp)
|
||||
ftpClose(&academy_ftp);
|
||||
}
|
||||
}
|
||||
|
||||
if(academy_ftp)
|
||||
ftpClose(&academy_ftp);
|
||||
|
||||
}
|
||||
if(fileList != NULL)
|
||||
{
|
||||
vp_os_free(fileList);
|
||||
fileList = NULL;
|
||||
}
|
||||
|
||||
if(academy_ftp)
|
||||
ftpClose(&academy_ftp);
|
||||
|
||||
}
|
||||
while(academy_download_started && !ardrone_tool_exit());
|
||||
|
||||
vp_os_cond_destroy(&academy_download_cond);
|
||||
vp_os_mutex_destroy(&academy_download_mutex);
|
||||
THREAD_RETURN(C_OK);
|
||||
THREAD_RETURN(C_OK);
|
||||
}
|
||||
|
||||
void academy_download_pause (void)
|
||||
|
||||
@@ -20,6 +20,10 @@
|
||||
extern char flight_dir[];
|
||||
#endif
|
||||
|
||||
#define ACADEMY_MEDIA_DIRPATH_FORMAT "%s/media_%s"
|
||||
#define ACADEMY_MEDIA_VIDEO_FILEPATH_FORMAT "%s/video_%s.%s"
|
||||
#define ACADEMY_MEDIA_DIR_ACCESS_RIGHT 0777
|
||||
|
||||
static void ardrone_academy_stage_recorder_internal_close(ardrone_academy_stage_recorder_config_t *cfg);
|
||||
|
||||
ardrone_academy_stage_recorder_config_t ardrone_academy_stage_recorder_config;
|
||||
@@ -53,14 +57,15 @@ ardrone_academy_stage_recorder_handle (ardrone_academy_stage_recorder_config_t *
|
||||
char media_dirname[ACADEMY_MAX_FILENAME];
|
||||
struct stat statbuf;
|
||||
|
||||
sprintf(media_dirname, "%s/media_%s", ACADEMY_FILE_DEFAULT_PATH, date);
|
||||
if((stat(media_dirname, &statbuf) != 0) && (mkdir(media_dirname, 0777) >= 0))
|
||||
sprintf(media_dirname, ACADEMY_MEDIA_DIRPATH_FORMAT, ACADEMY_FILE_DEFAULT_PATH, date);
|
||||
if((stat(media_dirname, &statbuf) != 0) && (mkdir(media_dirname, ACADEMY_MEDIA_DIR_ACCESS_RIGHT) >= 0))
|
||||
PA_DEBUG("Create local media directory %s if not exist\n", media_dirname);
|
||||
// NO ELSE, the local directory already exists
|
||||
|
||||
t = time(NULL);
|
||||
ardrone_time2date(t, ARDRONE_FILE_DATE_FORMAT, date);
|
||||
|
||||
sprintf(cfg->video_filename, "%s/video_%s.%s",
|
||||
sprintf(cfg->video_filename, ACADEMY_MEDIA_VIDEO_FILEPATH_FORMAT,
|
||||
media_dirname,
|
||||
date,
|
||||
ACADEMY_RECORD_FILE_EXTENSION);
|
||||
@@ -81,6 +86,7 @@ ardrone_academy_stage_recorder_handle (ardrone_academy_stage_recorder_config_t *
|
||||
printf ("Can't open file %s\n", video_filename);
|
||||
}
|
||||
}
|
||||
// NO ELSE - The record is already started or is starting
|
||||
break;
|
||||
|
||||
case PIPELINE_MSG_STOP:
|
||||
@@ -89,14 +95,16 @@ ardrone_academy_stage_recorder_handle (ardrone_academy_stage_recorder_config_t *
|
||||
cfg->startRec = ACADEMY_RECORD_STOP;
|
||||
printf("Stop recording %s\n", cfg->video_filename);
|
||||
ardrone_academy_stage_recorder_internal_close(cfg);
|
||||
result = C_OK;
|
||||
}
|
||||
// NO ELSE - Record is already stopped.
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return (VP_SUCCESS);
|
||||
return (result);
|
||||
}
|
||||
|
||||
void ardrone_academy_stage_recorder_enable(bool_t enable, uint32_t timestamp)
|
||||
@@ -136,7 +144,7 @@ C_RESULT ardrone_academy_stage_recorder_transform(ardrone_academy_stage_recorder
|
||||
out->indexBuffer = 0;
|
||||
out->lineSize = NULL;
|
||||
}
|
||||
|
||||
// NO ELSE - We need to initialize the number of buffers and the index of buffer in first.
|
||||
out->size = in->size;
|
||||
out->status = in->status;
|
||||
out->buffers = in->buffers;
|
||||
@@ -159,6 +167,11 @@ C_RESULT ardrone_academy_stage_recorder_transform(ardrone_academy_stage_recorder
|
||||
fwrite(&in->size, 1, sizeof(int32_t), cfg->fp);
|
||||
fwrite(in->buffers[in->indexBuffer], 1, in->size, cfg->fp);
|
||||
}
|
||||
// NO ELSE because :
|
||||
// If the descriptor file is NULL, we can't to write data.
|
||||
// If data size to write is 0, we don't have data to write.
|
||||
// If the status is not processing, it means the record is stopping.
|
||||
// If startRec is not start, it means the record is stopping or is starting.
|
||||
|
||||
vp_os_mutex_unlock( &out->lock );
|
||||
#endif
|
||||
@@ -171,5 +184,8 @@ C_RESULT ardrone_academy_stage_recorder_close(ardrone_academy_stage_recorder_con
|
||||
{
|
||||
ardrone_academy_stage_recorder_internal_close(cfg);
|
||||
}
|
||||
// NO ELSE because :
|
||||
// If the descriptor file is NULL, we can't to write data.
|
||||
|
||||
return C_OK;
|
||||
}
|
||||
|
||||
@@ -117,18 +117,9 @@ static void academy_upload_private_callback(academy_state_t state)
|
||||
|
||||
case ACADEMY_RESULT_OK:
|
||||
strcat(msg, "OK");
|
||||
// time_to_process += state.time_in_ms;
|
||||
// if(state.state == ACADEMY_STATE_DRONE_DISCONNECTION)
|
||||
// {
|
||||
// sprintf(msg, "%s in %d ms\n", msg, time_to_process);
|
||||
// time_to_process = 0;
|
||||
// }
|
||||
break;
|
||||
|
||||
case ACADEMY_RESULT_FAILED:
|
||||
// if(state.state == ACADEMY_STATE_DRONE_PREPARE_DOWNLOAD)
|
||||
// time_to_process = 0;
|
||||
|
||||
strcat(msg, "FAILED");
|
||||
break;
|
||||
}
|
||||
@@ -231,7 +222,6 @@ DEFINE_THREAD_ROUTINE(academy_upload, data)
|
||||
struct dirent *dirent = NULL;
|
||||
DIR *dir = NULL;
|
||||
academy_status = FTP_FAIL;
|
||||
|
||||
// Check if flight_* directory exist in local dir
|
||||
if((dir = opendir(flight_dir)) != NULL)
|
||||
{
|
||||
@@ -350,7 +340,7 @@ DEFINE_THREAD_ROUTINE(academy_upload, data)
|
||||
// Penser à supprimer le fichier local
|
||||
academy_status = FTP_FAIL;
|
||||
sprintf(local_dir, "%s/%s", flight_dir, dirname);
|
||||
if(!ftw(local_dir, &academy_remove, 1))
|
||||
if(!ftw(local_dir, &academy_remove, ACADEMY_MAX_FD_FOR_FTW))
|
||||
{
|
||||
rmdir(local_dir);
|
||||
academy_status = FTP_SUCCESS;
|
||||
|
||||
@@ -38,74 +38,69 @@ static vp_os_mutex_t event_queue_mutex;
|
||||
|
||||
C_RESULT ardrone_control_init(void)
|
||||
{
|
||||
COM_CONFIG_SOCKET_CONTROL(&control_socket, VP_COM_CLIENT, CONTROL_PORT, wifi_ardrone_ip);
|
||||
COM_CONFIG_SOCKET_CONTROL(&control_socket, VP_COM_CLIENT, CONTROL_PORT, wifi_ardrone_ip);
|
||||
|
||||
control_waited = FALSE;
|
||||
ardrone_state = 0;
|
||||
|
||||
control_waited = FALSE;
|
||||
ardrone_state = 0;
|
||||
vp_os_mutex_init(&control_mutex);
|
||||
vp_os_cond_init(&control_cond, &control_mutex);
|
||||
|
||||
vp_os_mutex_init(&control_mutex);
|
||||
vp_os_cond_init(&control_cond, &control_mutex);
|
||||
vp_os_mutex_init(&event_queue_mutex);
|
||||
|
||||
vp_os_mutex_init(&event_queue_mutex);
|
||||
start_index_in_queue = 0;
|
||||
end_index_in_queue = (start_index_in_queue - 1) & (ARDRONE_CONTROL_MAX_NUM_EVENTS_IN_QUEUE - 1);
|
||||
|
||||
start_index_in_queue = 0;
|
||||
end_index_in_queue = (start_index_in_queue - 1) & (ARDRONE_CONTROL_MAX_NUM_EVENTS_IN_QUEUE - 1);
|
||||
|
||||
return C_OK;
|
||||
return C_OK;
|
||||
}
|
||||
|
||||
C_RESULT ardrone_control_shutdown(void)
|
||||
{
|
||||
ardrone_control_resume_on_navdata_received(0);
|
||||
/*BUG FIX : Dont destroy the mutexes here,
|
||||
they are still being used by the ardrone_control thread,
|
||||
while this function is called by another thread.*/
|
||||
#ifdef THIS_IS_A_BUG
|
||||
vp_os_mutex_destroy(&event_queue_mutex);
|
||||
vp_os_cond_destroy(&control_cond);
|
||||
vp_os_mutex_destroy(&control_mutex);*/
|
||||
#endif
|
||||
ardrone_control_resume_on_navdata_received(0);
|
||||
/*BUG FIX : Dont destroy the mutexes here,
|
||||
they are still being used by the ardrone_control thread,
|
||||
while this function is called by another thread.*/
|
||||
|
||||
bContinue = FALSE;
|
||||
bContinue = FALSE;
|
||||
|
||||
return C_OK;
|
||||
return C_OK;
|
||||
}
|
||||
|
||||
C_RESULT ardrone_control_connect_to_drone()
|
||||
{
|
||||
int res_open_socket;
|
||||
int res_open_socket;
|
||||
|
||||
#ifdef _WIN32
|
||||
int timeout_windows=1000;/*milliseconds*/
|
||||
int timeout_windows=1000;/*milliseconds*/
|
||||
#else
|
||||
struct timeval tv;
|
||||
struct timeval tv;
|
||||
#endif
|
||||
|
||||
res_open_socket = vp_com_open(COM_CONTROL(), &control_socket, &control_read, &control_write);
|
||||
if( VP_SUCCEEDED(res_open_socket) )
|
||||
{
|
||||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 0;
|
||||
res_open_socket = vp_com_open(COM_CONTROL(), &control_socket, &control_read, &control_write);
|
||||
if( VP_SUCCEEDED(res_open_socket) )
|
||||
{
|
||||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
setsockopt((int32_t)control_socket.priv,
|
||||
SOL_SOCKET,
|
||||
SO_RCVTIMEO,
|
||||
#ifdef _WIN32
|
||||
(const char*)&timeout_windows, sizeof(timeout_windows)
|
||||
#else
|
||||
(const char*)&tv, sizeof(tv)
|
||||
#endif
|
||||
);
|
||||
setsockopt((int32_t)control_socket.priv,
|
||||
SOL_SOCKET,
|
||||
SO_RCVTIMEO,
|
||||
#ifdef _WIN32
|
||||
(const char*)&timeout_windows, sizeof(timeout_windows)
|
||||
#else
|
||||
(const char*)&tv, sizeof(tv)
|
||||
#endif
|
||||
);
|
||||
|
||||
control_socket.is_disable = FALSE;
|
||||
return C_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_PRINT_SDK("VP_Com : Failed to open socket for control\n");
|
||||
perror("FTOSFC");
|
||||
return C_FAIL;
|
||||
}
|
||||
control_socket.is_disable = FALSE;
|
||||
return C_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_PRINT_SDK("VP_Com : Failed to open socket for control\n");
|
||||
perror("FTOSFC");
|
||||
return C_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -115,201 +110,201 @@ C_RESULT ardrone_control_connect_to_drone()
|
||||
*/
|
||||
C_RESULT ardrone_control_resume_on_navdata_received(uint32_t new_ardrone_state)
|
||||
{
|
||||
vp_os_mutex_lock(&control_mutex);
|
||||
vp_os_mutex_lock(&control_mutex);
|
||||
if( control_waited )
|
||||
{
|
||||
ardrone_state = new_ardrone_state;
|
||||
vp_os_cond_signal(&control_cond);
|
||||
}
|
||||
vp_os_mutex_unlock(&control_mutex);
|
||||
return C_OK;
|
||||
{
|
||||
ardrone_state = new_ardrone_state;
|
||||
vp_os_cond_signal(&control_cond);
|
||||
}
|
||||
vp_os_mutex_unlock(&control_mutex);
|
||||
return C_OK;
|
||||
}
|
||||
|
||||
C_RESULT ardrone_control_read(uint8_t* buffer, int32_t* size)
|
||||
{
|
||||
C_RESULT res = C_FAIL;
|
||||
C_RESULT res = C_FAIL;
|
||||
|
||||
if( control_read != NULL )
|
||||
{
|
||||
res = control_read(&control_socket, buffer, size);
|
||||
if(*size == 0)
|
||||
{
|
||||
res = C_FAIL;
|
||||
}
|
||||
}
|
||||
if( control_read != NULL )
|
||||
{
|
||||
res = control_read(&control_socket, buffer, size);
|
||||
if(*size == 0)
|
||||
{
|
||||
res = C_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
return res;
|
||||
}
|
||||
|
||||
C_RESULT ardrone_control_write(const uint8_t* buffer, int32_t* size)
|
||||
{
|
||||
C_RESULT res = C_FAIL;
|
||||
C_RESULT res = C_FAIL;
|
||||
|
||||
if( control_write != NULL )
|
||||
{
|
||||
res = control_write(&control_socket, buffer, size);
|
||||
}
|
||||
if( control_write != NULL )
|
||||
{
|
||||
res = control_write(&control_socket, buffer, size);
|
||||
}
|
||||
|
||||
return res;
|
||||
return res;
|
||||
}
|
||||
|
||||
C_RESULT ardrone_control_send_event( ardrone_control_event_t* event )
|
||||
{
|
||||
C_RESULT res;
|
||||
int32_t next_index_in_queue;
|
||||
C_RESULT res;
|
||||
int32_t next_index_in_queue;
|
||||
|
||||
res = C_FAIL;
|
||||
res = C_FAIL;
|
||||
|
||||
vp_os_mutex_lock(&event_queue_mutex);
|
||||
vp_os_mutex_lock(&event_queue_mutex);
|
||||
next_index_in_queue = (start_index_in_queue + 1) & (ARDRONE_CONTROL_MAX_NUM_EVENTS_IN_QUEUE - 1);
|
||||
if( next_index_in_queue != end_index_in_queue )
|
||||
{
|
||||
ardrone_control_event_queue[start_index_in_queue] = event;
|
||||
start_index_in_queue = next_index_in_queue;
|
||||
ardrone_control_event_queue[start_index_in_queue] = event;
|
||||
start_index_in_queue = next_index_in_queue;
|
||||
|
||||
res = C_OK;
|
||||
}
|
||||
res = C_OK;
|
||||
}
|
||||
|
||||
vp_os_mutex_unlock(&event_queue_mutex);
|
||||
vp_os_mutex_unlock(&event_queue_mutex);
|
||||
|
||||
return res;
|
||||
return res;
|
||||
}
|
||||
|
||||
DEFINE_THREAD_ROUTINE( ardrone_control, nomParams )
|
||||
{
|
||||
C_RESULT res_wait_navdata = C_OK;
|
||||
C_RESULT res = C_OK;
|
||||
uint32_t retry, current_ardrone_state;
|
||||
int32_t next_index_in_queue;
|
||||
ardrone_control_event_ptr_t current_event;
|
||||
|
||||
retry = 0;
|
||||
current_event = NULL;
|
||||
|
||||
DEBUG_PRINT_SDK("Thread control in progress...\n");
|
||||
control_socket.is_disable = TRUE;
|
||||
|
||||
ardrone_control_connect_to_drone();
|
||||
C_RESULT res_wait_navdata = C_OK;
|
||||
C_RESULT res = C_OK;
|
||||
uint32_t retry, current_ardrone_state;
|
||||
int32_t next_index_in_queue;
|
||||
ardrone_control_event_ptr_t current_event;
|
||||
|
||||
retry = 0;
|
||||
current_event = NULL;
|
||||
|
||||
DEBUG_PRINT_SDK("Thread control in progress...\n");
|
||||
control_socket.is_disable = TRUE;
|
||||
|
||||
ardrone_control_connect_to_drone();
|
||||
|
||||
while( bContinue
|
||||
&& !ardrone_tool_exit() )
|
||||
{
|
||||
vp_os_mutex_lock(&control_mutex);
|
||||
control_waited = TRUE;
|
||||
&& !ardrone_tool_exit() )
|
||||
{
|
||||
vp_os_mutex_lock(&control_mutex);
|
||||
control_waited = TRUE;
|
||||
|
||||
/* Wait for new navdata to be received. */
|
||||
res_wait_navdata = vp_os_cond_timed_wait(&control_cond, 1000);
|
||||
vp_os_mutex_unlock(&control_mutex);
|
||||
/* Wait for new navdata to be received. */
|
||||
res_wait_navdata = vp_os_cond_timed_wait(&control_cond, 1000);
|
||||
vp_os_mutex_unlock(&control_mutex);
|
||||
|
||||
/*
|
||||
* In case of timeout on the navdata, we assume that there was a problem
|
||||
* with the Wifi connection.
|
||||
* It is then safer to close and reopen the control socket (TCP 5559) since
|
||||
* some OS might stop giving data but not signal any disconnection.
|
||||
*/
|
||||
if(VP_FAILED(res_wait_navdata))
|
||||
{
|
||||
/*
|
||||
* In case of timeout on the navdata, we assume that there was a problem
|
||||
* with the Wifi connection.
|
||||
* It is then safer to close and reopen the control socket (TCP 5559) since
|
||||
* some OS might stop giving data but not signal any disconnection.
|
||||
*/
|
||||
if(VP_FAILED(res_wait_navdata))
|
||||
{
|
||||
if (FALSE == control_socket.is_disable)
|
||||
{
|
||||
DEBUG_PRINT_SDK("Timeout while waiting for new navdata.\n");
|
||||
DEBUG_PRINT_SDK("Timeout while waiting for new navdata.\n");
|
||||
vp_com_close(COM_CONTROL(), &control_socket);
|
||||
control_socket.is_disable = TRUE;
|
||||
}
|
||||
control_socket.is_disable = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if(control_socket.is_disable)
|
||||
{
|
||||
ardrone_control_connect_to_drone();
|
||||
}
|
||||
|
||||
if(VP_SUCCEEDED(res_wait_navdata) && (!control_socket.is_disable))
|
||||
{
|
||||
vp_os_mutex_lock(&control_mutex);
|
||||
current_ardrone_state = ardrone_state;
|
||||
control_waited = FALSE;
|
||||
vp_os_mutex_unlock(&control_mutex);
|
||||
|
||||
if( ardrone_tool_exit() ) // Test if we received a signal because we are quitting the application
|
||||
THREAD_RETURN( res );
|
||||
|
||||
if( current_event == NULL )
|
||||
{
|
||||
vp_os_mutex_lock(&event_queue_mutex);
|
||||
next_index_in_queue = (end_index_in_queue + 1) & (ARDRONE_CONTROL_MAX_NUM_EVENTS_IN_QUEUE - 1);
|
||||
|
||||
if( next_index_in_queue != start_index_in_queue )
|
||||
{ // There's an event to process
|
||||
current_event = ardrone_control_event_queue[next_index_in_queue];
|
||||
if( current_event != NULL )
|
||||
{
|
||||
if( current_event->ardrone_control_event_start != NULL )
|
||||
{
|
||||
current_event->ardrone_control_event_start( current_event );
|
||||
}
|
||||
}
|
||||
end_index_in_queue = next_index_in_queue;
|
||||
|
||||
retry = 0;
|
||||
|
||||
if(control_socket.is_disable)
|
||||
{
|
||||
ardrone_control_connect_to_drone();
|
||||
}
|
||||
|
||||
if(VP_SUCCEEDED(res_wait_navdata) && (!control_socket.is_disable))
|
||||
{
|
||||
vp_os_mutex_lock(&control_mutex);
|
||||
current_ardrone_state = ardrone_state;
|
||||
control_waited = FALSE;
|
||||
vp_os_mutex_unlock(&control_mutex);
|
||||
|
||||
if( ardrone_tool_exit() ) // Test if we received a signal because we are quitting the application
|
||||
THREAD_RETURN( res );
|
||||
|
||||
if( current_event == NULL )
|
||||
{
|
||||
vp_os_mutex_lock(&event_queue_mutex);
|
||||
next_index_in_queue = (end_index_in_queue + 1) & (ARDRONE_CONTROL_MAX_NUM_EVENTS_IN_QUEUE - 1);
|
||||
|
||||
if( next_index_in_queue != start_index_in_queue )
|
||||
{ // There's an event to process
|
||||
current_event = ardrone_control_event_queue[next_index_in_queue];
|
||||
if( current_event != NULL )
|
||||
{
|
||||
if( current_event->ardrone_control_event_start != NULL )
|
||||
{
|
||||
current_event->ardrone_control_event_start( current_event );
|
||||
}
|
||||
}
|
||||
end_index_in_queue = next_index_in_queue;
|
||||
|
||||
retry = 0;
|
||||
}
|
||||
|
||||
vp_os_mutex_unlock(&event_queue_mutex);
|
||||
}
|
||||
|
||||
if( current_event != NULL )
|
||||
{
|
||||
switch( current_event->event )
|
||||
{
|
||||
case CFG_GET_CONTROL_MODE:
|
||||
case CUSTOM_CFG_GET_CONTROL_MODE: /* multiconfiguration support */
|
||||
res = ardrone_control_configuration_run( current_ardrone_state, (ardrone_control_configuration_event_t*) current_event );
|
||||
break;
|
||||
|
||||
case ACK_CONTROL_MODE:
|
||||
res = ardrone_control_ack_run( current_ardrone_state, (ardrone_control_ack_event_t *) current_event);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if( VP_FAILED(res) )
|
||||
{
|
||||
retry ++;
|
||||
if( retry > current_event->num_retries)
|
||||
current_event->status = ARDRONE_CONTROL_EVENT_FINISH_FAILURE;
|
||||
}
|
||||
else
|
||||
{
|
||||
retry = 0;
|
||||
}
|
||||
|
||||
if( current_event->status & ARDRONE_CONTROL_EVENT_FINISH )
|
||||
{
|
||||
if( current_event->ardrone_control_event_end != NULL )
|
||||
current_event->ardrone_control_event_end( current_event );
|
||||
|
||||
/* Make the thread read a new event on the next loop iteration */
|
||||
current_event = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Not changing 'current_event' makes the loop process the same
|
||||
* event when the next navdata packet arrives. */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}// while
|
||||
|
||||
vp_os_mutex_unlock(&event_queue_mutex);
|
||||
}
|
||||
/*Bug fix - mutexes were previously detroyed by another thread,
|
||||
which made ardrone_control crash.*/
|
||||
vp_os_mutex_destroy(&event_queue_mutex);
|
||||
vp_os_cond_destroy(&control_cond);
|
||||
vp_os_mutex_destroy(&control_mutex);
|
||||
|
||||
if( current_event != NULL )
|
||||
{
|
||||
switch( current_event->event )
|
||||
{
|
||||
case CFG_GET_CONTROL_MODE:
|
||||
case CUSTOM_CFG_GET_CONTROL_MODE: /* multiconfiguration support */
|
||||
res = ardrone_control_configuration_run( current_ardrone_state, (ardrone_control_configuration_event_t*) current_event );
|
||||
break;
|
||||
vp_com_close(COM_CONTROL(), &control_socket);
|
||||
|
||||
case ACK_CONTROL_MODE:
|
||||
res = ardrone_control_ack_run( current_ardrone_state, (ardrone_control_ack_event_t *) current_event);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if( VP_FAILED(res) )
|
||||
{
|
||||
retry ++;
|
||||
if( retry > current_event->num_retries)
|
||||
current_event->status = ARDRONE_CONTROL_EVENT_FINISH_FAILURE;
|
||||
}
|
||||
else
|
||||
{
|
||||
retry = 0;
|
||||
}
|
||||
|
||||
if( current_event->status & ARDRONE_CONTROL_EVENT_FINISH )
|
||||
{
|
||||
if( current_event->ardrone_control_event_end != NULL )
|
||||
current_event->ardrone_control_event_end( current_event );
|
||||
|
||||
/* Make the thread read a new event on the next loop iteration */
|
||||
current_event = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Not changing 'current_event' makes the loop process the same
|
||||
* event when the next navdata packet arrives. */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}// while
|
||||
|
||||
/* Stephane : Bug fix - mutexes were previously detroyed by another thread,
|
||||
which made ardrone_control crash.*/
|
||||
vp_os_mutex_destroy(&event_queue_mutex);
|
||||
vp_os_cond_destroy(&control_cond);
|
||||
vp_os_mutex_destroy(&control_mutex);
|
||||
|
||||
vp_com_close(COM_CONTROL(), &control_socket);
|
||||
|
||||
THREAD_RETURN( res );
|
||||
THREAD_RETURN( res );
|
||||
}
|
||||
|
||||
@@ -24,61 +24,61 @@
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SCREENSHOT_STATE_IDLE,
|
||||
SCREENSHOT_STATE_NEEDED,
|
||||
SCREENSHOT_STATE_INPROGRESS,
|
||||
SCREENSHOT_STATE_IDLE,
|
||||
SCREENSHOT_STATE_NEEDED,
|
||||
SCREENSHOT_STATE_INPROGRESS,
|
||||
} SCREENSHOT_STATE;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TAKEOFF_STATE_IDLE,
|
||||
TAKEOFF_STATE_NEEDED,
|
||||
TAKEOFF_STATE_WAIT_USERBOX,
|
||||
TAKEOFF_STATE_CANCELLING,
|
||||
TAKEOFF_STATE_IDLE,
|
||||
TAKEOFF_STATE_NEEDED,
|
||||
TAKEOFF_STATE_WAIT_USERBOX,
|
||||
TAKEOFF_STATE_CANCELLING,
|
||||
} TAKEOFF_STATE;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RECORD_STATE_IDLE,
|
||||
RECORD_STATE_NEEDED,
|
||||
RECORD_STATE_WAIT_USERBOX,
|
||||
RECORD_STATE_IDLE,
|
||||
RECORD_STATE_NEEDED,
|
||||
RECORD_STATE_WAIT_USERBOX,
|
||||
} RECORD_STATE;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
USERBOX_STATE_STARTING,
|
||||
USERBOX_STATE_STARTED,
|
||||
USERBOX_STATE_STOPPING,
|
||||
USERBOX_STATE_STOPPED,
|
||||
USERBOX_STATE_STARTING,
|
||||
USERBOX_STATE_STARTED,
|
||||
USERBOX_STATE_STOPPING,
|
||||
USERBOX_STATE_STOPPED,
|
||||
} USERBOX_STATE;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/**
|
||||
* variable to know if setting is needed
|
||||
*/
|
||||
bool_t wasEmergency;
|
||||
bool_t needSetEmergency;
|
||||
TAKEOFF_STATE takeoff_state;
|
||||
time_t takeoff_time;
|
||||
RECORD_STATE record_state;
|
||||
USERBOX_STATE userbox_state;
|
||||
SCREENSHOT_STATE screenshot_state;
|
||||
time_t userbox_time;
|
||||
vp_os_mutex_t aan_mutex;
|
||||
/**
|
||||
* variable to know if setting is needed
|
||||
*/
|
||||
bool_t wasEmergency;
|
||||
bool_t needSetEmergency;
|
||||
TAKEOFF_STATE takeoff_state;
|
||||
time_t takeoff_time;
|
||||
RECORD_STATE record_state;
|
||||
USERBOX_STATE userbox_state;
|
||||
SCREENSHOT_STATE screenshot_state;
|
||||
time_t userbox_time;
|
||||
vp_os_mutex_t aan_mutex;
|
||||
uint32_t usbFreeTime;
|
||||
bool_t droneStoppedUsbRecording;
|
||||
bool_t takeOffWasCancelled;
|
||||
|
||||
/**
|
||||
* Strings to display in interface
|
||||
*/
|
||||
bool_t isTakeOff;
|
||||
bool_t isEmergency;
|
||||
/**
|
||||
* Strings to display in interface
|
||||
*/
|
||||
bool_t isTakeOff;
|
||||
bool_t isEmergency;
|
||||
uint32_t lastState;
|
||||
bool_t cameraIsReady;
|
||||
bool_t usbIsReady;
|
||||
bool_t usbRecordInProgress;
|
||||
bool_t cameraIsReady;
|
||||
bool_t usbIsReady;
|
||||
bool_t usbRecordInProgress;
|
||||
bool_t internalRecordInProgress;
|
||||
} ardrone_academy_navdata_state_t;
|
||||
|
||||
@@ -97,10 +97,10 @@ bool_t ardrone_academy_navdata_takeoff(void)
|
||||
bool_t shouldNotDo = (TRUE == isBatteryLow && FALSE == navdata_state.isTakeOff) ? TRUE : FALSE;
|
||||
if(navdata_state.takeoff_state == TAKEOFF_STATE_IDLE &&
|
||||
FALSE == shouldNotDo)
|
||||
{
|
||||
LOCK_ND_MUTEX ();
|
||||
navdata_state.takeoff_state = TAKEOFF_STATE_NEEDED;
|
||||
navdata_state.takeoff_time = time (NULL);
|
||||
{
|
||||
LOCK_ND_MUTEX ();
|
||||
navdata_state.takeoff_state = TAKEOFF_STATE_NEEDED;
|
||||
navdata_state.takeoff_time = time (NULL);
|
||||
UNLOCK_ND_MUTEX ();
|
||||
result = TRUE;
|
||||
}
|
||||
@@ -110,20 +110,20 @@ bool_t ardrone_academy_navdata_takeoff(void)
|
||||
bool_t ardrone_academy_navdata_emergency(void)
|
||||
{
|
||||
bool_t result = TRUE;
|
||||
LOCK_ND_MUTEX ();
|
||||
navdata_state.needSetEmergency = TRUE;
|
||||
UNLOCK_ND_MUTEX ();
|
||||
LOCK_ND_MUTEX ();
|
||||
navdata_state.needSetEmergency = TRUE;
|
||||
UNLOCK_ND_MUTEX ();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool_t ardrone_academy_navdata_record(void)
|
||||
{
|
||||
bool_t result = FALSE;
|
||||
if(navdata_state.record_state == RECORD_STATE_IDLE)
|
||||
if(navdata_state.record_state == RECORD_STATE_IDLE)
|
||||
{
|
||||
LOCK_ND_MUTEX ();
|
||||
navdata_state.record_state = RECORD_STATE_NEEDED;
|
||||
UNLOCK_ND_MUTEX ();
|
||||
LOCK_ND_MUTEX ();
|
||||
navdata_state.record_state = RECORD_STATE_NEEDED;
|
||||
UNLOCK_ND_MUTEX ();
|
||||
result = TRUE;
|
||||
}
|
||||
return result;
|
||||
@@ -132,11 +132,11 @@ bool_t ardrone_academy_navdata_record(void)
|
||||
bool_t ardrone_academy_navdata_screenshot(void)
|
||||
{
|
||||
bool_t result = FALSE;
|
||||
if(navdata_state.screenshot_state == SCREENSHOT_STATE_IDLE)
|
||||
if(navdata_state.screenshot_state == SCREENSHOT_STATE_IDLE)
|
||||
{
|
||||
LOCK_ND_MUTEX ();
|
||||
navdata_state.screenshot_state = SCREENSHOT_STATE_NEEDED;
|
||||
UNLOCK_ND_MUTEX ();
|
||||
LOCK_ND_MUTEX ();
|
||||
navdata_state.screenshot_state = SCREENSHOT_STATE_NEEDED;
|
||||
UNLOCK_ND_MUTEX ();
|
||||
result = TRUE;
|
||||
}
|
||||
return result;
|
||||
@@ -144,40 +144,40 @@ bool_t ardrone_academy_navdata_screenshot(void)
|
||||
|
||||
bool_t ardrone_academy_navdata_get_camera_state(void)
|
||||
{
|
||||
return (navdata_state.cameraIsReady && (navdata_state.screenshot_state == SCREENSHOT_STATE_IDLE));
|
||||
return (navdata_state.cameraIsReady && (navdata_state.screenshot_state == SCREENSHOT_STATE_IDLE));
|
||||
}
|
||||
|
||||
bool_t ardrone_academy_navdata_get_usb_state(void)
|
||||
{
|
||||
return navdata_state.usbIsReady;
|
||||
return navdata_state.usbIsReady;
|
||||
}
|
||||
|
||||
bool_t ardrone_academy_navdata_get_takeoff_state(void)
|
||||
{
|
||||
return navdata_state.isTakeOff;
|
||||
return navdata_state.isTakeOff;
|
||||
}
|
||||
|
||||
bool_t ardrone_academy_navdata_get_record_ready(void)
|
||||
{
|
||||
bool_t result = FALSE;
|
||||
|
||||
if(1 == ARDRONE_VERSION())
|
||||
bool_t result = FALSE;
|
||||
|
||||
if(1 == ARDRONE_VERSION())
|
||||
{
|
||||
result = ardrone_academy_stage_recorder_state();
|
||||
result = ardrone_academy_stage_recorder_state();
|
||||
}
|
||||
else if(2 == ARDRONE_VERSION())
|
||||
else if(2 == ARDRONE_VERSION())
|
||||
{
|
||||
#if defined (RECORD_ENCODED_VIDEO)
|
||||
result = (video_stage_encoded_recorder_state() || navdata_state.usbRecordInProgress);
|
||||
result = (video_stage_encoded_recorder_state() || navdata_state.usbRecordInProgress);
|
||||
#else
|
||||
printf("ARDRONE VERSION 2 NEEDS RECORD_ENCODED_VIDEO MACRO!!!\n");
|
||||
PRINT("ARDRONE VERSION 2 NEEDS RECORD_ENCODED_VIDEO MACRO!!!\n");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
printf("ARDRONE VERSION NOT INITIALIZED !!!\n");
|
||||
PRINT("ARDRONE VERSION NOT INITIALIZED !!!\n");
|
||||
}
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool_t ardrone_academy_navdata_get_record_state(void)
|
||||
@@ -196,19 +196,19 @@ bool_t ardrone_academy_navdata_get_record_state(void)
|
||||
( VIDEO_ENCODED_STOPPED != recState &&
|
||||
VIDEO_ENCODED_WAITING_STREAM_END != recState);
|
||||
#else
|
||||
printf("ARDRONE VERSION 2 NEEDS RECORD_ENCODED_VIDEO MACRO!!!\n");
|
||||
PRINT("ARDRONE VERSION 2 NEEDS RECORD_ENCODED_VIDEO MACRO!!!\n");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("ARDRONE VERSION NOT INITIALIZED !!!\n");
|
||||
PRINT("ARDRONE VERSION NOT INITIALIZED !!!\n");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool_t ardrone_academy_navdata_get_emergency_state(void)
|
||||
{
|
||||
return navdata_state.isEmergency;
|
||||
return navdata_state.isEmergency;
|
||||
}
|
||||
|
||||
uint32_t ardrone_academy_navdata_get_remaining_usb_time (void)
|
||||
@@ -236,154 +236,154 @@ bool_t ardrone_academy_navdata_check_takeoff_cancelled (void)
|
||||
|
||||
void ardrone_academy_navdata_recorder_enable(bool_t enable, uint32_t timestamp)
|
||||
{
|
||||
if(1 == ARDRONE_VERSION())
|
||||
if(1 == ARDRONE_VERSION())
|
||||
{
|
||||
ardrone_academy_stage_recorder_enable(enable, timestamp);
|
||||
ardrone_academy_stage_recorder_enable(enable, timestamp);
|
||||
}
|
||||
else if(2 == ARDRONE_VERSION())
|
||||
else if(2 == ARDRONE_VERSION())
|
||||
{
|
||||
#if defined (RECORD_ENCODED_VIDEO)
|
||||
if (1 == enable)
|
||||
if (1 == enable)
|
||||
{
|
||||
/*
|
||||
Calling this function to disable the recorder is to be made outside
|
||||
a navdata handler, so we can finish a video even if the drone is
|
||||
disconnected (battery removed, or out of wifi range)
|
||||
The disable call is made inside the UI "button press" callbacks
|
||||
*/
|
||||
video_stage_encoded_recorder_enable(enable, timestamp);
|
||||
/*
|
||||
Calling this function to disable the recorder is to be made outside
|
||||
a navdata handler, so we can finish a video even if the drone is
|
||||
disconnected (battery removed, or out of wifi range)
|
||||
The disable call is made inside the UI "button press" callbacks
|
||||
*/
|
||||
video_stage_encoded_recorder_enable(enable, timestamp);
|
||||
}
|
||||
#else
|
||||
printf("ARDRONE VERSION 2 NEEDS RECORD_ENCODED_VIDEO MACRO!!!\n");
|
||||
PRINT("ARDRONE VERSION 2 NEEDS RECORD_ENCODED_VIDEO MACRO!!!\n");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
printf("ARDRONE VERSION NOT INITIALIZED !!!\n");
|
||||
PRINT("ARDRONE VERSION NOT INITIALIZED !!!\n");
|
||||
}
|
||||
}
|
||||
|
||||
FLYING_STATE ardrone_academy_navdata_get_flying_state(const navdata_unpacked_t* data)
|
||||
{
|
||||
FLYING_STATE tmp_state;
|
||||
switch ((data->navdata_demo.ctrl_state >> 16))
|
||||
FLYING_STATE tmp_state;
|
||||
switch ((data->navdata_demo.ctrl_state >> 16))
|
||||
{
|
||||
case CTRL_FLYING:
|
||||
case CTRL_HOVERING:
|
||||
case CTRL_TRANS_GOTOFIX:
|
||||
case CTRL_TRANS_LOOPING:
|
||||
tmp_state = FLYING_STATE_FLYING;
|
||||
break;
|
||||
|
||||
tmp_state = FLYING_STATE_FLYING;
|
||||
break;
|
||||
|
||||
case CTRL_TRANS_TAKEOFF:
|
||||
tmp_state = FLYING_STATE_TAKING_OFF;
|
||||
break;
|
||||
|
||||
tmp_state = FLYING_STATE_TAKING_OFF;
|
||||
break;
|
||||
|
||||
case CTRL_TRANS_LANDING:
|
||||
tmp_state = FLYING_STATE_LANDING;
|
||||
break;
|
||||
|
||||
tmp_state = FLYING_STATE_LANDING;
|
||||
break;
|
||||
|
||||
case CTRL_DEFAULT:
|
||||
case CTRL_LANDED:
|
||||
default:
|
||||
tmp_state = FLYING_STATE_LANDED;
|
||||
break;
|
||||
tmp_state = FLYING_STATE_LANDED;
|
||||
break;
|
||||
}
|
||||
return tmp_state;
|
||||
return tmp_state;
|
||||
}
|
||||
|
||||
void ardrone_academy_navdata_userbox_cb(bool_t result)
|
||||
{
|
||||
if(result)
|
||||
if(result)
|
||||
{
|
||||
LOCK_ND_MUTEX ();
|
||||
if(navdata_state.userbox_state == USERBOX_STATE_STARTING)
|
||||
LOCK_ND_MUTEX ();
|
||||
if(navdata_state.userbox_state == USERBOX_STATE_STARTING)
|
||||
{
|
||||
printf("Userbox started\n");
|
||||
navdata_state.userbox_state = USERBOX_STATE_STARTED;
|
||||
|
||||
switch (navdata_state.takeoff_state)
|
||||
PRINT("Userbox started\n");
|
||||
navdata_state.userbox_state = USERBOX_STATE_STARTED;
|
||||
|
||||
switch (navdata_state.takeoff_state)
|
||||
{
|
||||
case TAKEOFF_STATE_WAIT_USERBOX:
|
||||
navdata_state.takeoff_state = TAKEOFF_STATE_IDLE;
|
||||
ardrone_tool_set_ui_pad_start(1);
|
||||
break;
|
||||
navdata_state.takeoff_state = TAKEOFF_STATE_IDLE;
|
||||
ardrone_tool_set_ui_pad_start(1);
|
||||
break;
|
||||
case TAKEOFF_STATE_CANCELLING:
|
||||
navdata_state.takeoff_state = TAKEOFF_STATE_IDLE;
|
||||
ardrone_tool_set_ui_pad_start(0);
|
||||
break;
|
||||
navdata_state.takeoff_state = TAKEOFF_STATE_IDLE;
|
||||
ardrone_tool_set_ui_pad_start(0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if(navdata_state.record_state == RECORD_STATE_WAIT_USERBOX)
|
||||
|
||||
|
||||
if(navdata_state.record_state == RECORD_STATE_WAIT_USERBOX)
|
||||
{
|
||||
navdata_state.record_state = RECORD_STATE_IDLE;
|
||||
if (FALSE == navdata_state.usbRecordInProgress)
|
||||
{
|
||||
ardrone_academy_navdata_recorder_enable(TRUE, navdata_state.userbox_time);
|
||||
}
|
||||
navdata_state.record_state = RECORD_STATE_IDLE;
|
||||
if (FALSE == navdata_state.usbRecordInProgress)
|
||||
{
|
||||
ardrone_academy_navdata_recorder_enable(TRUE, navdata_state.userbox_time);
|
||||
}
|
||||
}
|
||||
else if(navdata_state.userbox_state == USERBOX_STATE_STOPPING)
|
||||
}
|
||||
else if(navdata_state.userbox_state == USERBOX_STATE_STOPPING)
|
||||
{
|
||||
printf("Userbox stopped\n");
|
||||
academy_download_resume ();
|
||||
if(navdata_state.takeoff_state == TAKEOFF_STATE_WAIT_USERBOX ||
|
||||
TAKEOFF_STATE_CANCELLING == navdata_state.takeoff_state)
|
||||
PRINT("Userbox stopped\n");
|
||||
academy_download_resume ();
|
||||
if(navdata_state.takeoff_state == TAKEOFF_STATE_WAIT_USERBOX ||
|
||||
TAKEOFF_STATE_CANCELLING == navdata_state.takeoff_state)
|
||||
{
|
||||
navdata_state.takeoff_state = TAKEOFF_STATE_IDLE;
|
||||
ardrone_tool_set_ui_pad_start(0);
|
||||
navdata_state.takeoff_state = TAKEOFF_STATE_IDLE;
|
||||
ardrone_tool_set_ui_pad_start(0);
|
||||
}
|
||||
|
||||
if(navdata_state.record_state == RECORD_STATE_WAIT_USERBOX)
|
||||
if(navdata_state.record_state == RECORD_STATE_WAIT_USERBOX)
|
||||
{
|
||||
navdata_state.record_state = RECORD_STATE_IDLE;
|
||||
ardrone_academy_navdata_recorder_enable(FALSE, navdata_state.userbox_time);
|
||||
navdata_state.usbRecordInProgress = FALSE;
|
||||
navdata_state.record_state = RECORD_STATE_IDLE;
|
||||
ardrone_academy_navdata_recorder_enable(FALSE, navdata_state.userbox_time);
|
||||
navdata_state.usbRecordInProgress = FALSE;
|
||||
}
|
||||
|
||||
navdata_state.userbox_state = USERBOX_STATE_STOPPED;
|
||||
navdata_state.userbox_state = USERBOX_STATE_STOPPED;
|
||||
}
|
||||
UNLOCK_ND_MUTEX ();
|
||||
UNLOCK_ND_MUTEX ();
|
||||
}
|
||||
}
|
||||
|
||||
void ardrone_academy_navdata_screenshot_cb(bool_t result)
|
||||
{
|
||||
if(result)
|
||||
if(result)
|
||||
{
|
||||
LOCK_ND_MUTEX ();
|
||||
if(navdata_state.screenshot_state == SCREENSHOT_STATE_INPROGRESS)
|
||||
LOCK_ND_MUTEX ();
|
||||
if(navdata_state.screenshot_state == SCREENSHOT_STATE_INPROGRESS)
|
||||
{
|
||||
navdata_state.screenshot_state = SCREENSHOT_STATE_IDLE;
|
||||
navdata_state.screenshot_state = SCREENSHOT_STATE_IDLE;
|
||||
}
|
||||
UNLOCK_ND_MUTEX ();
|
||||
UNLOCK_ND_MUTEX ();
|
||||
}
|
||||
}
|
||||
|
||||
void ardrone_academy_check_take_off_timeout (void)
|
||||
{
|
||||
static char cancelCommand[ARDRONE_DATE_MAXSIZE];
|
||||
time_t elapsedTime = time (NULL) - navdata_state.takeoff_time;
|
||||
if (TAKEOFF_TIMEOUT_SEC < elapsedTime)
|
||||
static char cancelCommand[ARDRONE_DATE_MAXSIZE];
|
||||
time_t elapsedTime = time (NULL) - navdata_state.takeoff_time;
|
||||
if (TAKEOFF_TIMEOUT_SEC < elapsedTime)
|
||||
{
|
||||
switch (navdata_state.takeoff_state)
|
||||
switch (navdata_state.takeoff_state)
|
||||
{
|
||||
case TAKEOFF_STATE_WAIT_USERBOX:
|
||||
snprintf (cancelCommand, ARDRONE_DATE_MAXSIZE-1, "%d", USERBOX_CMD_CANCEL);
|
||||
navdata_state.userbox_state = USERBOX_STATE_STOPPING;
|
||||
navdata_state.takeoff_state = TAKEOFF_STATE_CANCELLING;
|
||||
ARDRONE_TOOL_CONFIGURATION_ADDEVENT (userbox_cmd, cancelCommand, ardrone_academy_navdata_userbox_cb);
|
||||
snprintf (cancelCommand, ARDRONE_DATE_MAXSIZE-1, "%d", USERBOX_CMD_CANCEL);
|
||||
navdata_state.userbox_state = USERBOX_STATE_STOPPING;
|
||||
navdata_state.takeoff_state = TAKEOFF_STATE_CANCELLING;
|
||||
ARDRONE_TOOL_CONFIGURATION_ADDEVENT (userbox_cmd, cancelCommand, ardrone_academy_navdata_userbox_cb);
|
||||
navdata_state.takeOffWasCancelled = TRUE;
|
||||
break;
|
||||
break;
|
||||
case TAKEOFF_STATE_NEEDED:
|
||||
navdata_state.takeoff_state = TAKEOFF_STATE_IDLE;
|
||||
navdata_state.takeoff_state = TAKEOFF_STATE_IDLE;
|
||||
navdata_state.takeOffWasCancelled = TRUE;
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -391,58 +391,58 @@ void ardrone_academy_check_take_off_timeout (void)
|
||||
|
||||
void ardrone_academy_navdata_userbox_switch(void)
|
||||
{
|
||||
static char param[ARDRONE_DATE_MAXSIZE + 8];
|
||||
static char date[ARDRONE_DATE_MAXSIZE];
|
||||
if(navdata_state.userbox_state == USERBOX_STATE_STOPPED)
|
||||
static char param[ARDRONE_DATE_MAXSIZE + 8];
|
||||
static char date[ARDRONE_DATE_MAXSIZE];
|
||||
if(navdata_state.userbox_state == USERBOX_STATE_STOPPED)
|
||||
{
|
||||
navdata_state.userbox_time = time(NULL);
|
||||
ardrone_time2date(navdata_state.userbox_time, ARDRONE_FILE_DATE_FORMAT, date);
|
||||
sprintf(param, "%d,%s", USERBOX_CMD_START, date);
|
||||
navdata_state.userbox_state = USERBOX_STATE_STARTING;
|
||||
ARDRONE_TOOL_CONFIGURATION_ADDEVENT(userbox_cmd, param, ardrone_academy_navdata_userbox_cb);
|
||||
navdata_state.userbox_time = time(NULL);
|
||||
ardrone_time2date(navdata_state.userbox_time, ARDRONE_FILE_DATE_FORMAT, date);
|
||||
sprintf(param, "%d,%s", USERBOX_CMD_START, date);
|
||||
navdata_state.userbox_state = USERBOX_STATE_STARTING;
|
||||
ARDRONE_TOOL_CONFIGURATION_ADDEVENT(userbox_cmd, param, ardrone_academy_navdata_userbox_cb);
|
||||
}
|
||||
else if(navdata_state.userbox_state == USERBOX_STATE_STARTED)
|
||||
else if(navdata_state.userbox_state == USERBOX_STATE_STARTED)
|
||||
{
|
||||
sprintf(param, "%d", USERBOX_CMD_STOP);
|
||||
navdata_state.userbox_state = USERBOX_STATE_STOPPING;
|
||||
ARDRONE_TOOL_CONFIGURATION_ADDEVENT(userbox_cmd, param, ardrone_academy_navdata_userbox_cb);
|
||||
sprintf(param, "%d", USERBOX_CMD_STOP);
|
||||
navdata_state.userbox_state = USERBOX_STATE_STOPPING;
|
||||
ARDRONE_TOOL_CONFIGURATION_ADDEVENT(userbox_cmd, param, ardrone_academy_navdata_userbox_cb);
|
||||
}
|
||||
}
|
||||
|
||||
C_RESULT ardrone_academy_navdata_init(void* data)
|
||||
{
|
||||
navdata_state.wasEmergency = FALSE;
|
||||
navdata_state.needSetEmergency = FALSE;
|
||||
navdata_state.takeoff_state = TAKEOFF_STATE_IDLE;
|
||||
navdata_state.record_state = TAKEOFF_STATE_IDLE;
|
||||
navdata_state.userbox_state = USERBOX_STATE_STOPPED;
|
||||
navdata_state.isTakeOff = FALSE;
|
||||
navdata_state.isEmergency = FALSE;
|
||||
navdata_state.cameraIsReady = FALSE;
|
||||
navdata_state.usbIsReady = FALSE;
|
||||
navdata_state.usbRecordInProgress = FALSE;
|
||||
navdata_state.userbox_time = (time_t)0;
|
||||
navdata_state.takeoff_time = (time_t)0;
|
||||
navdata_state.wasEmergency = FALSE;
|
||||
navdata_state.needSetEmergency = FALSE;
|
||||
navdata_state.takeoff_state = TAKEOFF_STATE_IDLE;
|
||||
navdata_state.record_state = TAKEOFF_STATE_IDLE;
|
||||
navdata_state.userbox_state = USERBOX_STATE_STOPPED;
|
||||
navdata_state.isTakeOff = FALSE;
|
||||
navdata_state.isEmergency = FALSE;
|
||||
navdata_state.cameraIsReady = FALSE;
|
||||
navdata_state.usbIsReady = FALSE;
|
||||
navdata_state.usbRecordInProgress = FALSE;
|
||||
navdata_state.userbox_time = (time_t)0;
|
||||
navdata_state.takeoff_time = (time_t)0;
|
||||
navdata_state.usbFreeTime = 0;
|
||||
navdata_state.droneStoppedUsbRecording = FALSE;
|
||||
navdata_state.takeOffWasCancelled = FALSE;
|
||||
navdata_state.internalRecordInProgress = FALSE;
|
||||
navdata_state.lastState = 0;
|
||||
vp_os_mutex_init (&navdata_state.aan_mutex);
|
||||
vp_os_mutex_init (&navdata_state.aan_mutex);
|
||||
|
||||
return C_OK;
|
||||
return C_OK;
|
||||
}
|
||||
|
||||
C_RESULT ardrone_academy_navdata_process( const navdata_unpacked_t* const pnd )
|
||||
{
|
||||
static bool_t prevCameraIsReady = FALSE;
|
||||
static bool_t prevCameraIsReady = FALSE;
|
||||
static bool_t prevDroneUsbRecording = FALSE;
|
||||
if (C_OK == TRYLOCK_ND_MUTEX ())
|
||||
if (C_OK == TRYLOCK_ND_MUTEX ())
|
||||
{
|
||||
input_state_t* input_state = ardrone_tool_input_get_state();
|
||||
input_state_t* input_state = ardrone_tool_input_get_state();
|
||||
bool_t recordIsReady = ! ardrone_academy_navdata_get_record_ready();
|
||||
bool_t recordIsInProgress = ardrone_academy_navdata_get_record_state();
|
||||
|
||||
|
||||
// Save ARDrone State
|
||||
navdata_state.lastState = pnd->ardrone_state;
|
||||
|
||||
@@ -462,80 +462,80 @@ C_RESULT ardrone_academy_navdata_process( const navdata_unpacked_t* const pnd )
|
||||
}
|
||||
prevDroneUsbRecording = currentDroneUsbRecording;
|
||||
|
||||
ardrone_academy_check_take_off_timeout ();
|
||||
ardrone_academy_check_take_off_timeout ();
|
||||
|
||||
// Take off and Emergency management
|
||||
if(navdata_state.takeoff_state == TAKEOFF_STATE_NEEDED)
|
||||
{
|
||||
if(pnd->ardrone_state & ARDRONE_EMERGENCY_MASK)
|
||||
// Take off and Emergency management
|
||||
if(navdata_state.takeoff_state == TAKEOFF_STATE_NEEDED)
|
||||
{
|
||||
if(pnd->ardrone_state & ARDRONE_EMERGENCY_MASK)
|
||||
{
|
||||
navdata_state.needSetEmergency = TRUE;
|
||||
navdata_state.needSetEmergency = TRUE;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
if(recordIsInProgress)
|
||||
{
|
||||
if(!(pnd->ardrone_state & ARDRONE_USER_FEEDBACK_START))
|
||||
ardrone_tool_set_ui_pad_start(1);
|
||||
else
|
||||
ardrone_tool_set_ui_pad_start(0);
|
||||
navdata_state.takeoff_state = TAKEOFF_STATE_IDLE;
|
||||
if(!(pnd->ardrone_state & ARDRONE_USER_FEEDBACK_START))
|
||||
ardrone_tool_set_ui_pad_start(1);
|
||||
else
|
||||
ardrone_tool_set_ui_pad_start(0);
|
||||
navdata_state.takeoff_state = TAKEOFF_STATE_IDLE;
|
||||
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
navdata_state.takeoff_state = TAKEOFF_STATE_WAIT_USERBOX;
|
||||
ardrone_academy_navdata_userbox_switch();
|
||||
navdata_state.takeoff_state = TAKEOFF_STATE_WAIT_USERBOX;
|
||||
ardrone_academy_navdata_userbox_switch();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(navdata_state.needSetEmergency)
|
||||
{
|
||||
ardrone_tool_set_ui_pad_select(1);
|
||||
navdata_state.needSetEmergency = FALSE;
|
||||
}
|
||||
if(navdata_state.needSetEmergency)
|
||||
{
|
||||
ardrone_tool_set_ui_pad_select(1);
|
||||
navdata_state.needSetEmergency = FALSE;
|
||||
}
|
||||
|
||||
if(pnd->ardrone_state & ARDRONE_EMERGENCY_MASK)
|
||||
if(pnd->ardrone_state & ARDRONE_EMERGENCY_MASK)
|
||||
{
|
||||
if(!navdata_state.wasEmergency && (input_state->user_input & (1 << ARDRONE_UI_BIT_SELECT)))
|
||||
if(!navdata_state.wasEmergency && (input_state->user_input & (1 << ARDRONE_UI_BIT_SELECT)))
|
||||
{
|
||||
ardrone_tool_set_ui_pad_select(0);
|
||||
ardrone_tool_set_ui_pad_select(0);
|
||||
}
|
||||
|
||||
navdata_state.isEmergency = TRUE;
|
||||
navdata_state.isTakeOff = FALSE;
|
||||
|
||||
navdata_state.isEmergency = TRUE;
|
||||
navdata_state.isTakeOff = FALSE;
|
||||
|
||||
if(!navdata_state.internalRecordInProgress && !navdata_state.usbRecordInProgress && (navdata_state.userbox_state == USERBOX_STATE_STARTED))
|
||||
{
|
||||
printf("Emergency !! Stopping userbox...\n");
|
||||
ardrone_academy_navdata_userbox_switch();
|
||||
PRINT("Emergency !! Stopping userbox...\n");
|
||||
ardrone_academy_navdata_userbox_switch();
|
||||
}
|
||||
|
||||
ardrone_tool_input_start_reset();
|
||||
ardrone_tool_input_start_reset();
|
||||
}
|
||||
else // Not emergency landing
|
||||
else // Not emergency landing
|
||||
{
|
||||
if(navdata_state.wasEmergency && (input_state->user_input & (1 << ARDRONE_UI_BIT_SELECT)))
|
||||
if(navdata_state.wasEmergency && (input_state->user_input & (1 << ARDRONE_UI_BIT_SELECT)))
|
||||
{
|
||||
ardrone_tool_set_ui_pad_select(0);
|
||||
ardrone_tool_set_ui_pad_select(0);
|
||||
}
|
||||
|
||||
if(!(pnd->ardrone_state & ARDRONE_TIMER_ELAPSED))
|
||||
navdata_state.isEmergency = FALSE;
|
||||
|
||||
if(!(pnd->ardrone_state & ARDRONE_TIMER_ELAPSED))
|
||||
navdata_state.isEmergency = FALSE;
|
||||
|
||||
if(input_state->user_input & (1 << ARDRONE_UI_BIT_START))
|
||||
if(input_state->user_input & (1 << ARDRONE_UI_BIT_START))
|
||||
{
|
||||
navdata_state.isTakeOff = (pnd->ardrone_state & ARDRONE_USER_FEEDBACK_START) ? TRUE : FALSE;
|
||||
navdata_state.isTakeOff = (pnd->ardrone_state & ARDRONE_USER_FEEDBACK_START) ? TRUE : FALSE;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
navdata_state.isTakeOff = FALSE;
|
||||
navdata_state.isTakeOff = FALSE;
|
||||
}
|
||||
}
|
||||
navdata_state.wasEmergency = (pnd->ardrone_state & ARDRONE_EMERGENCY_MASK) ? TRUE : FALSE;
|
||||
|
||||
// Video record management
|
||||
navdata_state.wasEmergency = (pnd->ardrone_state & ARDRONE_EMERGENCY_MASK) ? TRUE : FALSE;
|
||||
|
||||
// Video record management
|
||||
|
||||
bool_t usbRecordEnable = FALSE;
|
||||
if(navdata_state.record_state == RECORD_STATE_NEEDED &&
|
||||
@@ -544,34 +544,34 @@ C_RESULT ardrone_academy_navdata_process( const navdata_unpacked_t* const pnd )
|
||||
bool_t continueRecord = TRUE;
|
||||
bool_t nextInternalRecordState = FALSE;
|
||||
if (IS_LEAST_ARDRONE2)
|
||||
{
|
||||
static codec_type_t oldCodec;
|
||||
{
|
||||
static codec_type_t oldCodec;
|
||||
codec_type_t cancelCodec;
|
||||
if (recordIsReady && ! navdata_state.usbRecordInProgress && !navdata_state.internalRecordInProgress) // We want to enable recording
|
||||
{
|
||||
if ((ARDRONE_USB_MASK == (pnd->ardrone_state & ARDRONE_USB_MASK)) &&
|
||||
{
|
||||
if ((ARDRONE_USB_MASK == (pnd->ardrone_state & ARDRONE_USB_MASK)) &&
|
||||
(0 < pnd->navdata_hdvideo_stream.usbkey_remaining_time) &&
|
||||
(TRUE == ardrone_control_config.video_on_usb))
|
||||
{
|
||||
(TRUE == ardrone_control_config.video_on_usb))
|
||||
{
|
||||
usbRecordEnable = TRUE;
|
||||
}
|
||||
}
|
||||
// Set the "non-record codec" to the codec defined as the application default
|
||||
oldCodec = ardrone_application_default_config.video_codec;
|
||||
cancelCodec = oldCodec;
|
||||
ardrone_control_config.video_codec = (TRUE == usbRecordEnable) ? usbRecordCodec : deviceWifiRecordCodec;
|
||||
printf ("Set codec %d -> %d\n", oldCodec, ardrone_control_config.video_codec);
|
||||
PRINT ("Set codec %d -> %d\n", oldCodec, ardrone_control_config.video_codec);
|
||||
nextInternalRecordState = TRUE;
|
||||
}
|
||||
else // We want to disable recording
|
||||
{
|
||||
}
|
||||
else // We want to disable recording
|
||||
{
|
||||
cancelCodec = ardrone_control_config.video_codec;
|
||||
ardrone_control_config.video_codec = oldCodec;
|
||||
printf ("Reset codec %d -> %d\n", cancelCodec, oldCodec);
|
||||
}
|
||||
ardrone_control_config.video_codec = oldCodec;
|
||||
PRINT ("Reset codec %d -> %d\n", cancelCodec, oldCodec);
|
||||
}
|
||||
bool_t addEventSucceeded = ARDRONE_TOOL_CONFIGURATION_ADDEVENT (video_codec, &ardrone_control_config.video_codec, NULL);
|
||||
if (FALSE == addEventSucceeded)
|
||||
{
|
||||
printf ("Unable to send codec switch ... retry later\n");
|
||||
PRINT ("Unable to send codec switch ... retry later\n");
|
||||
ardrone_control_config.video_codec = cancelCodec;
|
||||
continueRecord = FALSE;
|
||||
}
|
||||
@@ -584,93 +584,93 @@ C_RESULT ardrone_academy_navdata_process( const navdata_unpacked_t* const pnd )
|
||||
if (TRUE == continueRecord)
|
||||
{
|
||||
navdata_state.internalRecordInProgress = nextInternalRecordState;
|
||||
switch (navdata_state.userbox_state)
|
||||
{
|
||||
case USERBOX_STATE_STOPPED:
|
||||
navdata_state.record_state = RECORD_STATE_WAIT_USERBOX;
|
||||
switch (navdata_state.userbox_state)
|
||||
{
|
||||
case USERBOX_STATE_STOPPED:
|
||||
navdata_state.record_state = RECORD_STATE_WAIT_USERBOX;
|
||||
navdata_state.usbRecordInProgress = usbRecordEnable;
|
||||
ardrone_academy_navdata_userbox_switch();
|
||||
break;
|
||||
case USERBOX_STATE_STARTED:
|
||||
if(navdata_state.isTakeOff)
|
||||
{
|
||||
ardrone_academy_navdata_userbox_switch();
|
||||
break;
|
||||
case USERBOX_STATE_STARTED:
|
||||
if(navdata_state.isTakeOff)
|
||||
{
|
||||
if(! recordIsReady)
|
||||
{
|
||||
printf("Userbox is started and record is started => Stop record\n");
|
||||
ardrone_academy_navdata_recorder_enable(FALSE, navdata_state.userbox_time);
|
||||
navdata_state.usbRecordInProgress = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Userbox is started and record is stopped => Start record\n");
|
||||
{
|
||||
PRINT("Userbox is started and record is started => Stop record\n");
|
||||
ardrone_academy_navdata_recorder_enable(FALSE, navdata_state.userbox_time);
|
||||
navdata_state.usbRecordInProgress = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINT("Userbox is started and record is stopped => Start record\n");
|
||||
if (FALSE == usbRecordEnable)
|
||||
{
|
||||
// Only activate the local recorder if we don't record on USB
|
||||
ardrone_academy_navdata_recorder_enable(TRUE, navdata_state.userbox_time);
|
||||
{
|
||||
// Only activate the local recorder if we don't record on USB
|
||||
ardrone_academy_navdata_recorder_enable(TRUE, navdata_state.userbox_time);
|
||||
navdata_state.usbRecordInProgress = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
navdata_state.usbRecordInProgress = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
navdata_state.record_state = RECORD_STATE_IDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
navdata_state.record_state = RECORD_STATE_WAIT_USERBOX;
|
||||
ardrone_academy_navdata_userbox_switch();
|
||||
}
|
||||
break;
|
||||
case USERBOX_STATE_STARTING:
|
||||
navdata_state.record_state = RECORD_STATE_IDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
navdata_state.record_state = RECORD_STATE_WAIT_USERBOX;
|
||||
ardrone_academy_navdata_userbox_switch();
|
||||
}
|
||||
break;
|
||||
case USERBOX_STATE_STARTING:
|
||||
navdata_state.usbRecordInProgress = usbRecordEnable;
|
||||
navdata_state.record_state = RECORD_STATE_WAIT_USERBOX;
|
||||
break;
|
||||
case USERBOX_STATE_STOPPING:
|
||||
navdata_state.record_state = RECORD_STATE_WAIT_USERBOX;
|
||||
break;
|
||||
case USERBOX_STATE_STOPPING:
|
||||
navdata_state.usbRecordInProgress = usbRecordEnable;
|
||||
// Should never be here
|
||||
PRINT ("Don't know what to do for USERBOX_STATE_STOPPING\n");
|
||||
VP_OS_ASSERT (0 == 1); // Debug handler
|
||||
break;
|
||||
// Should never be here
|
||||
PRINT ("Don't know what to do for USERBOX_STATE_STOPPING\n");
|
||||
VP_OS_ASSERT (0 == 1); // Debug handler
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Screenshot management
|
||||
prevCameraIsReady = navdata_state.cameraIsReady;
|
||||
navdata_state.cameraIsReady = (pnd->ardrone_state & ARDRONE_CAMERA_MASK) ? TRUE : FALSE;
|
||||
if (TRUE == navdata_state.cameraIsReady && FALSE == prevCameraIsReady)
|
||||
{
|
||||
academy_download_resume ();
|
||||
}
|
||||
// Screenshot management
|
||||
prevCameraIsReady = navdata_state.cameraIsReady;
|
||||
navdata_state.cameraIsReady = (pnd->ardrone_state & ARDRONE_CAMERA_MASK) ? TRUE : FALSE;
|
||||
if (TRUE == navdata_state.cameraIsReady && FALSE == prevCameraIsReady)
|
||||
{
|
||||
academy_download_resume ();
|
||||
}
|
||||
|
||||
if((navdata_state.screenshot_state == SCREENSHOT_STATE_NEEDED) && navdata_state.cameraIsReady)
|
||||
{
|
||||
char param[ARDRONE_DATE_MAXSIZE + 64];
|
||||
char date[ARDRONE_DATE_MAXSIZE];
|
||||
time_t t = time(NULL);
|
||||
ardrone_time2date(t, ARDRONE_FILE_DATE_FORMAT, date);
|
||||
navdata_state.screenshot_state = SCREENSHOT_STATE_INPROGRESS;
|
||||
sprintf(param, "%d,%d,%d,%s", USERBOX_CMD_SCREENSHOT, 0, 0, date);
|
||||
ARDRONE_TOOL_CONFIGURATION_ADDEVENT(userbox_cmd, (char*)param, ardrone_academy_navdata_screenshot_cb);
|
||||
}
|
||||
if((navdata_state.screenshot_state == SCREENSHOT_STATE_NEEDED) && navdata_state.cameraIsReady)
|
||||
{
|
||||
static char param[ARDRONE_DATE_MAXSIZE + 64];
|
||||
static char date[ARDRONE_DATE_MAXSIZE];
|
||||
time_t t = time(NULL);
|
||||
ardrone_time2date(t, ARDRONE_FILE_DATE_FORMAT, date);
|
||||
navdata_state.screenshot_state = SCREENSHOT_STATE_INPROGRESS;
|
||||
sprintf(param, "%d,%d,%d,%s", USERBOX_CMD_SCREENSHOT, 0, 0, date);
|
||||
ARDRONE_TOOL_CONFIGURATION_ADDEVENT(userbox_cmd, param, ardrone_academy_navdata_screenshot_cb);
|
||||
}
|
||||
|
||||
// USB management
|
||||
navdata_state.usbIsReady = (pnd->ardrone_state & ARDRONE_USB_MASK) ? TRUE : FALSE;
|
||||
UNLOCK_ND_MUTEX ();
|
||||
// USB management
|
||||
navdata_state.usbIsReady = (pnd->ardrone_state & ARDRONE_USB_MASK) ? TRUE : FALSE;
|
||||
UNLOCK_ND_MUTEX ();
|
||||
}
|
||||
return C_OK;
|
||||
return C_OK;
|
||||
}
|
||||
|
||||
C_RESULT ardrone_academy_navdata_release( void )
|
||||
{
|
||||
if(ardrone_academy_navdata_get_record_state())
|
||||
if(ardrone_academy_navdata_get_record_state())
|
||||
{
|
||||
ardrone_academy_navdata_recorder_enable(FALSE, navdata_state.userbox_time);
|
||||
ardrone_academy_navdata_recorder_enable(FALSE, navdata_state.userbox_time);
|
||||
}
|
||||
vp_os_mutex_destroy (&navdata_state.aan_mutex);
|
||||
return C_OK;
|
||||
vp_os_mutex_destroy (&navdata_state.aan_mutex);
|
||||
return C_OK;
|
||||
}
|
||||
|
||||
void ardrone_academy_navdata_set_wifi_record_codec (codec_type_t newCodec)
|
||||
|
||||
@@ -35,11 +35,11 @@ static inline int versionSupportsMulticonfiguration (const char *currentString)
|
||||
#define _GENERAL_NAVDATA_DEBUG_PREFIX "General Navdata : "
|
||||
#if _GENERAL_NAVDATA_DEBUG || defined (DEBUG)
|
||||
#define PRINTDBG(...) \
|
||||
do \
|
||||
do \
|
||||
{ \
|
||||
printf ("[%d] %s", __LINE__, _GENERAL_NAVDATA_DEBUG_PREFIX); \
|
||||
printf (__VA_ARGS__); \
|
||||
printf ("\n"); \
|
||||
printf ("[%d] %s", __LINE__, _GENERAL_NAVDATA_DEBUG_PREFIX); \
|
||||
printf (__VA_ARGS__); \
|
||||
printf ("\n"); \
|
||||
} while (0)
|
||||
#else
|
||||
#define PRINTDBG(...)
|
||||
@@ -50,7 +50,7 @@ static void sendInitConfigurations(void)
|
||||
}
|
||||
|
||||
static void switchToSession(void)
|
||||
{
|
||||
{
|
||||
ARDRONE_TOOL_CONFIGURATION_ADDEVENT (session_id, ses_id, NULL);
|
||||
}
|
||||
|
||||
@@ -142,7 +142,7 @@ C_RESULT ardrone_general_navdata_process( const navdata_unpacked_t* const pnd )
|
||||
navdata_mode_t current_navdata_state = NAVDATA_BOOTSTRAP;
|
||||
|
||||
/* Makes sure the navdata stream will be resumed if the drone is disconnected and reconnected.
|
||||
* Allows changing the drone battery during debugging sessions. */
|
||||
* Allows changing the drone battery during debugging sessions. */
|
||||
if( ardrone_get_mask_from_state(pnd->ardrone_state, ARDRONE_NAVDATA_BOOTSTRAP) )
|
||||
{
|
||||
current_navdata_state = NAVDATA_BOOTSTRAP;
|
||||
@@ -154,7 +154,16 @@ C_RESULT ardrone_general_navdata_process( const navdata_unpacked_t* const pnd )
|
||||
|
||||
if (current_navdata_state == NAVDATA_BOOTSTRAP && configState == MULTICONFIG_IDLE && navdataState == NAVDATA_REQUEST_IDLE)
|
||||
{
|
||||
navdataState = NAVDATA_REQUEST_NEEDED;
|
||||
if ((0 != strncmp(ardrone_control_config.application_id, app_id, APPLI_NAME_SIZE)) ||
|
||||
(0 != strncmp(ardrone_control_config.profile_id, usr_id, USER_NAME_SIZE)) ||
|
||||
(0 != strncmp(ardrone_control_config.session_id, ses_id, SESSION_NAME_SIZE)))
|
||||
{
|
||||
configState = MULTICONFIG_NEEDED;
|
||||
}
|
||||
else
|
||||
{
|
||||
navdataState = NAVDATA_REQUEST_NEEDED;
|
||||
}
|
||||
}
|
||||
|
||||
/* Multiconfig settings */
|
||||
@@ -318,14 +327,14 @@ C_RESULT ardrone_general_navdata_process( const navdata_unpacked_t* const pnd )
|
||||
navdataState = NAVDATA_REQUEST_IN_PROGRESS;
|
||||
switchToSession(); // Resend session id when reconnecting.
|
||||
sendInitConfigurations();
|
||||
ARDRONE_TOOL_CONFIGURATION_ADDEVENT(navdata_demo, &ardrone_application_default_config.navdata_demo, NULL);
|
||||
ARDRONE_TOOL_CONFIGURATION_ADDEVENT (navdata_demo, &ardrone_application_default_config.navdata_demo, NULL);
|
||||
ARDRONE_TOOL_CONFIGURATION_ADDEVENT (navdata_options, &ardrone_application_default_config.navdata_options, navdataCallback);
|
||||
break;
|
||||
case NAVDATA_REQUEST_DONE:
|
||||
// Refresh configuration file
|
||||
PRINTDBG ("Refreshing from NAVDATA FSM");
|
||||
navdataState = NAVDATA_REQUEST_IDLE;
|
||||
ARDRONE_TOOL_CONFIGURATION_GET (NULL);
|
||||
ARDRONE_TOOL_CONFIGURATION_GET (NULL);
|
||||
break;
|
||||
case NAVDATA_REQUEST_IN_PROGRESS:
|
||||
case NAVDATA_REQUEST_IDLE:
|
||||
@@ -421,6 +430,7 @@ ardrone_users_t *ardrone_get_user_list(void)
|
||||
if (NULL == retVal->userList)
|
||||
{
|
||||
vp_os_free (retVal);
|
||||
retVal = NULL;
|
||||
return NULL;
|
||||
}
|
||||
strncpy (retVal->userList[validUserCount-1].ident, available_configurations[CAT_USER].list[configIndex].id, MULTICONFIG_ID_SIZE);
|
||||
@@ -438,6 +448,7 @@ void ardrone_free_user_list (ardrone_users_t **users)
|
||||
if (NULL != (*users)->userList)
|
||||
{
|
||||
vp_os_free ((*users)->userList);
|
||||
(*users)->userList = NULL;
|
||||
}
|
||||
vp_os_free (*users);
|
||||
*users = NULL;
|
||||
|
||||
@@ -18,35 +18,35 @@
|
||||
// Handler to resume control thread is mandatory
|
||||
#define BEGIN_NAVDATA_HANDLER_TABLE \
|
||||
ardrone_navdata_handler_t ardrone_navdata_handler_table[] = { \
|
||||
{ ardrone_navdata_control_init, ardrone_navdata_control_process, ardrone_navdata_control_release, NULL }, \
|
||||
{ ardrone_navdata_control_init, ardrone_navdata_control_process, ardrone_navdata_control_release, NULL }, \
|
||||
{ ardrone_general_navdata_init, ardrone_general_navdata_process, ardrone_general_navdata_release, NULL }, \
|
||||
{ video_navdata_handler_init, video_navdata_handler_process, video_navdata_handler_release, NULL }, \
|
||||
{ ardrone_academy_navdata_init, ardrone_academy_navdata_process, ardrone_academy_navdata_release, NULL },
|
||||
|
||||
#define END_NAVDATA_HANDLER_TABLE \
|
||||
{ NULL, NULL, NULL, NULL } \
|
||||
};
|
||||
};
|
||||
|
||||
#define NAVDATA_HANDLER_TABLE_ENTRY( init, process, release, init_data_ptr ) \
|
||||
{ (ardrone_navdata_handler_init_t)init, process, release, init_data_ptr },
|
||||
{ (ardrone_navdata_handler_init_t)init, process, release, init_data_ptr },
|
||||
|
||||
typedef C_RESULT (*ardrone_navdata_handler_init_t)( void* data );
|
||||
typedef C_RESULT (*ardrone_navdata_handler_process_t)( const navdata_unpacked_t* const navdata );
|
||||
typedef C_RESULT (*ardrone_navdata_handler_release_t)( void );
|
||||
|
||||
typedef struct _ardrone_navdata_handler_t {
|
||||
ardrone_navdata_handler_init_t init;
|
||||
ardrone_navdata_handler_process_t process;
|
||||
ardrone_navdata_handler_release_t release;
|
||||
ardrone_navdata_handler_init_t init;
|
||||
ardrone_navdata_handler_process_t process;
|
||||
ardrone_navdata_handler_release_t release;
|
||||
|
||||
void* data; // Data used during initialization
|
||||
void* data; // Data used during initialization
|
||||
} ardrone_navdata_handler_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
NAVDATA_BOOTSTRAP = 0,
|
||||
NAVDATA_DEMO,
|
||||
NAVDATA_FULL
|
||||
NAVDATA_BOOTSTRAP = 0,
|
||||
NAVDATA_DEMO,
|
||||
NAVDATA_FULL
|
||||
} navdata_mode_t;
|
||||
|
||||
extern ardrone_navdata_handler_t ardrone_navdata_handler_table[] WEAK;
|
||||
|
||||
@@ -49,6 +49,11 @@ navdata_option_t* ardrone_navdata_search_option( navdata_option_t* navdata_optio
|
||||
{
|
||||
ptr = (uint8_t*) navdata_options_ptr;
|
||||
ptr += navdata_options_ptr->size;
|
||||
if (0 == navdata_options_ptr->size)
|
||||
{
|
||||
navdata_options_ptr = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
navdata_options_ptr = (navdata_option_t*) ptr;
|
||||
}
|
||||
|
||||
@@ -28,9 +28,9 @@ typedef int socklen_t;
|
||||
#define PDBG(...) \
|
||||
do \
|
||||
{ \
|
||||
printf ("V_COM_STAGE: %s:%d : ", __FUNCTION__, __LINE__); \
|
||||
printf (__VA_ARGS__); \
|
||||
printf ("\n"); \
|
||||
PRINT ("V_COM_STAGE: %s:%d : ", __FUNCTION__, __LINE__); \
|
||||
PRINT (__VA_ARGS__); \
|
||||
PRINT ("\n"); \
|
||||
} while (0)
|
||||
#else
|
||||
#define PDBG(...)
|
||||
@@ -116,20 +116,20 @@ C_RESULT video_com_stage_connect (video_com_config_t *cfg)
|
||||
|
||||
if( cfg->protocol == VP_COM_PROBE)
|
||||
{
|
||||
printf("\n\nPROBING\n");
|
||||
PRINT("\n\nPROBING\n");
|
||||
|
||||
cfg->socket.protocol = VP_COM_TCP;
|
||||
res = vp_com_open(cfg->com, &cfg->socket, &cfg->read, &cfg->write);
|
||||
|
||||
if( VP_SUCCEEDED(res) )
|
||||
{
|
||||
printf("\n\nTCP\n");
|
||||
PRINT("\n\nTCP\n");
|
||||
vp_com_close (cfg->com, &cfg->socket);
|
||||
cfg->protocol = VP_COM_TCP;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\n\nUDP\n");
|
||||
PRINT("\n\nUDP\n");
|
||||
cfg->protocol = VP_COM_UDP;
|
||||
}
|
||||
}
|
||||
@@ -230,11 +230,11 @@ C_RESULT video_com_multisocket_stage_open(video_com_multisocket_config_t *cfg)
|
||||
cfg->configs[i]->mustReconnect = 0;
|
||||
}
|
||||
|
||||
printf("Video multisocket : init %i sockets\n",cfg->nb_sockets);
|
||||
PRINT("Video multisocket : init %i sockets\n",cfg->nb_sockets);
|
||||
|
||||
for(i=0;i<cfg->nb_sockets;i++)
|
||||
{
|
||||
printf("Video multisocket : connecting socket %d on port %d %s\n",
|
||||
PRINT("Video multisocket : connecting socket %d on port %d %s\n",
|
||||
i,
|
||||
cfg->configs[i]->socket.port,
|
||||
(cfg->configs[i]->protocol==VP_COM_TCP)?"TCP":"UDP");
|
||||
@@ -242,7 +242,7 @@ C_RESULT video_com_multisocket_stage_open(video_com_multisocket_config_t *cfg)
|
||||
cfg->configs[i]->connected = FALSE;
|
||||
res = video_com_stage_connect(cfg->configs[i]);
|
||||
if (!VP_SUCCEEDED(res)) {
|
||||
printf(" - Connection failed\n");
|
||||
PRINT(" - Connection failed\n");
|
||||
nb_failed_connections++;
|
||||
|
||||
}
|
||||
@@ -266,9 +266,9 @@ C_RESULT video_com_stage_transform(video_com_config_t *cfg, vp_api_io_data_t *in
|
||||
if (1 == cfg->mustReconnect)
|
||||
{
|
||||
PDBG ("Will call connect");
|
||||
printf ("Reconnecting ... ");
|
||||
PRINT ("Reconnecting ... ");
|
||||
res = video_com_stage_connect (cfg);
|
||||
printf ("%s\n", (VP_FAILED (res) ? "FAIL" : "OK"));
|
||||
PRINT ("%s\n", (VP_FAILED (res) ? "FAIL" : "OK"));
|
||||
cfg->mustReconnect = 0;
|
||||
}
|
||||
|
||||
@@ -313,10 +313,10 @@ C_RESULT video_com_stage_transform(video_com_config_t *cfg, vp_api_io_data_t *in
|
||||
PDBG ("%s [%d] : status set to error !\n", __FUNCTION__, __LINE__);
|
||||
perror ("Video_com_stage");
|
||||
cfg->mustReconnect = 1;
|
||||
out->size = 0;
|
||||
out->size = 0;
|
||||
vp_os_mutex_unlock (&out->lock);
|
||||
return C_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if( out->size == 0)
|
||||
{
|
||||
@@ -377,7 +377,7 @@ C_RESULT video_com_stage_transform(video_com_config_t *cfg, vp_api_io_data_t *in
|
||||
|
||||
C_RESULT video_com_multisocket_stage_transform(video_com_multisocket_config_t *cfg, vp_api_io_data_t *in, vp_api_io_data_t *out)
|
||||
{
|
||||
C_RESULT res,res2;
|
||||
C_RESULT res;
|
||||
fd_set rfds;
|
||||
int retval;
|
||||
int fs,maxfs;
|
||||
@@ -394,10 +394,10 @@ C_RESULT video_com_multisocket_stage_transform(video_com_multisocket_config_t *c
|
||||
if (1 == cfg->configs[i]->mustReconnect)
|
||||
{
|
||||
PDBG ("Will call connect");
|
||||
printf ("Reconnecting ... ");
|
||||
PRINT ("Reconnecting ... ");
|
||||
res = C_FAIL;
|
||||
res = video_com_stage_connect (cfg->configs[i]);
|
||||
printf ("%s\n", (VP_FAILED (res) ? "FAIL" : "OK"));
|
||||
PRINT ("%s\n", (VP_FAILED (res) ? "FAIL" : "OK"));
|
||||
cfg->configs[i]->mustReconnect = 0;
|
||||
}
|
||||
}
|
||||
@@ -480,20 +480,20 @@ C_RESULT video_com_multisocket_stage_transform(video_com_multisocket_config_t *c
|
||||
|
||||
if(i == cfg->nb_sockets)
|
||||
{
|
||||
printf("%s:%d BUG !!!!!", __FUNCTION__, __LINE__);
|
||||
PRINT("%s:%d BUG !!!!!", __FUNCTION__, __LINE__);
|
||||
selectTimeout = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_PRINT_SDK("%s\n",(retval==0) ? "timeout" : "error");
|
||||
DEBUG_PRINT_SDK("%s\n",(retval==0)?"timeout":"error");
|
||||
selectTimeout = TRUE;
|
||||
}
|
||||
|
||||
if (FALSE == selectTimeout)
|
||||
{
|
||||
DEBUG_PRINT_SDK ("Will read on socket %d\n", i);
|
||||
// DEBUG_PRINT_SDK ("Will read on socket %d\n", i);
|
||||
// Actual first time read
|
||||
res = cfg->configs[i]->read(&cfg->configs[i]->socket, out->buffers[0], &out->size);
|
||||
if (VP_FAILED (res))
|
||||
@@ -504,7 +504,7 @@ C_RESULT video_com_multisocket_stage_transform(video_com_multisocket_config_t *c
|
||||
out->size = 0;
|
||||
vp_os_mutex_unlock (&out->lock);
|
||||
return C_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// Loop read to empty the socket buffers if needed
|
||||
cfg->configs[i]->socket.block = VP_COM_DONTWAIT;
|
||||
@@ -512,14 +512,14 @@ C_RESULT video_com_multisocket_stage_transform(video_com_multisocket_config_t *c
|
||||
int32_t readSize = cfg->configs[i]->buffer_size - out->size;
|
||||
while (TRUE == bContinue)
|
||||
{
|
||||
DEBUG_PRINT_SDK ("Will read %d octets from socket %d\n", readSize, i);
|
||||
// DEBUG_PRINT_SDK ("Will read %d octets from socket %d\n", readSize, i);
|
||||
res = cfg->configs[i]->read(&cfg->configs[i]->socket, &(out->buffers[0][out->size]), &readSize);
|
||||
if (VP_FAILED (res))
|
||||
{
|
||||
PDBG ("%s [%d] : status set to error !\n", __FUNCTION__, __LINE__);
|
||||
perror ("Video_com_stage");
|
||||
cfg->configs[i]->mustReconnect = 1;
|
||||
out->size = 0;
|
||||
out->size = 0;
|
||||
vp_os_mutex_unlock (&out->lock);
|
||||
return C_OK;
|
||||
}
|
||||
@@ -551,7 +551,7 @@ C_RESULT video_com_multisocket_stage_transform(video_com_multisocket_config_t *c
|
||||
DEBUG_PRINT_SDK("Video multisocket : sending connection byte on port %s %d\n",
|
||||
(cfg->configs[i]->socket.protocol==VP_COM_TCP)?"TCP":"UDP",cfg->configs[i]->socket.port);
|
||||
|
||||
res2 = cfg->configs[i]->write(&cfg->configs[i]->socket, (uint8_t*) &flag, &len);
|
||||
cfg->configs[i]->write(&cfg->configs[i]->socket, (uint8_t*) &flag, &len);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -566,7 +566,7 @@ C_RESULT video_com_multisocket_stage_transform(video_com_multisocket_config_t *c
|
||||
|
||||
if((selectTimeout == TRUE) && cfg->forceNonBlocking && *(cfg->forceNonBlocking)==TRUE)
|
||||
{
|
||||
//printf("Debug %s:%d\n",__FUNCTION__,__LINE__);
|
||||
//PRINT("Debug %s:%d\n",__FUNCTION__,__LINE__);
|
||||
|
||||
/* No data are available here, but some are available in the next stage */
|
||||
/* out->size=0 would restart the pipeline */
|
||||
|
||||
@@ -61,7 +61,7 @@ DEFINE_THREAD_ROUTINE(video_recorder, data)
|
||||
vp_api_io_stage_t stages[3];
|
||||
PIPELINE_HANDLE video_recorder_pipeline_handle;
|
||||
video_recorder_thread_param_t *video_recorder_thread_param = (video_recorder_thread_param_t *)data;
|
||||
|
||||
|
||||
video_stage_tcp_config_t tcpConf;
|
||||
|
||||
if(video_recorder_thread_param != NULL)
|
||||
|
||||
@@ -197,14 +197,21 @@ DEFINE_THREAD_ROUTINE(video_stage, data) {
|
||||
}
|
||||
|
||||
vp_os_free(params->pre_processing_stages_list->stages_list);
|
||||
params->pre_processing_stages_list->stages_list = NULL;
|
||||
vp_os_free(params->post_processing_stages_list->stages_list);
|
||||
params->post_processing_stages_list->stages_list = NULL;
|
||||
vp_os_free(params->pre_processing_stages_list);
|
||||
params->pre_processing_stages_list = NULL;
|
||||
vp_os_free(params->post_processing_stages_list);
|
||||
params->post_processing_stages_list = NULL;
|
||||
|
||||
vp_os_free(params->in_pic);
|
||||
params->in_pic = NULL;
|
||||
vp_os_free(params->out_pic);
|
||||
params->out_pic = NULL;
|
||||
|
||||
vp_os_free(params);
|
||||
params = NULL;
|
||||
|
||||
vp_api_close(&pipeline, &video_pipeline_handle);
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <ardrone_tool/Video/video_stage_decoder.h>
|
||||
#include <video_encapsulation.h>
|
||||
#include <VP_Os/vp_os_malloc.h>
|
||||
#include <VP_Os/vp_os_print.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef USE_ANDROID
|
||||
@@ -18,19 +19,22 @@
|
||||
# define mp4h264_open ittiam_stage_decoding_open
|
||||
# define mp4h264_transform ittiam_stage_decoding_transform
|
||||
# define mp4h264_close ittiam_stage_decoding_close
|
||||
static const int resetDecoderOnStreamChange = 1;
|
||||
# else // FFMPEG
|
||||
# define mp4h264_open ffmpeg_stage_decoding_open
|
||||
# define mp4h264_transform ffmpeg_stage_decoding_transform
|
||||
# define mp4h264_close ffmpeg_stage_decoding_close
|
||||
static const int resetDecoderOnStreamChange = 0;
|
||||
# endif
|
||||
#else
|
||||
#else // ANDROID
|
||||
typedef enum {
|
||||
NEON_SUPPORT_UNKNOWN = 0,
|
||||
NEON_SUPPORT_OK,
|
||||
NEON_SUPPORT_FAIL,
|
||||
NEON_SUPPORT_UNKNOWN = 0,
|
||||
NEON_SUPPORT_OK,
|
||||
NEON_SUPPORT_FAIL,
|
||||
} neon_status_t;
|
||||
|
||||
static neon_status_t neonStatus = NEON_SUPPORT_UNKNOWN;
|
||||
static neon_status_t neonStatus = NEON_SUPPORT_FAIL; // <<< FORCE FFMPEG <<<
|
||||
static int resetDecoderOnStreamChange = 0; // NON CONST as it will be set at runtime
|
||||
|
||||
C_RESULT mp4h264_open (mp4h264_config_t *cfg);
|
||||
C_RESULT mp4h264_transform (mp4h264_config_t *cfg, vp_api_io_data_t *in, vp_api_io_data_t *out);
|
||||
@@ -48,19 +52,19 @@ float DEBUG_decodingTimeUsec = 0.0;
|
||||
#define ENABLE_VIDEO_STAGE_DECODER_DEBUG (0)
|
||||
|
||||
const vp_api_stage_funcs_t video_decoding_funcs = {
|
||||
(vp_api_stage_handle_msg_t) NULL,
|
||||
(vp_api_stage_open_t) video_stage_decoder_open,
|
||||
(vp_api_stage_transform_t) video_stage_decoder_transform,
|
||||
(vp_api_stage_close_t) video_stage_decoder_close
|
||||
(vp_api_stage_handle_msg_t) NULL,
|
||||
(vp_api_stage_open_t) video_stage_decoder_open,
|
||||
(vp_api_stage_transform_t) video_stage_decoder_transform,
|
||||
(vp_api_stage_close_t) video_stage_decoder_close
|
||||
};
|
||||
|
||||
#if ENABLE_VIDEO_STAGE_DECODER_DEBUG || defined (DEBUG)
|
||||
#define PDBG(...) \
|
||||
do \
|
||||
do \
|
||||
{ \
|
||||
printf ("VIDEO_STAGE_DECODER (%s@%d) : ", __FUNCTION__, __LINE__); \
|
||||
printf (__VA_ARGS__); \
|
||||
printf ("\n"); \
|
||||
printf ("VIDEO_STAGE_DECODER (%s@%d) : ", __FUNCTION__, __LINE__); \
|
||||
printf (__VA_ARGS__); \
|
||||
printf ("\n"); \
|
||||
} while (0)
|
||||
#else
|
||||
#define PDBG(...)
|
||||
@@ -68,13 +72,13 @@ const vp_api_stage_funcs_t video_decoding_funcs = {
|
||||
|
||||
|
||||
#define ALLOC_CHECK(POINTER, SIZE) \
|
||||
do \
|
||||
do \
|
||||
{ \
|
||||
POINTER = vp_os_calloc (SIZE, 1); \
|
||||
if (NULL == POINTER) \
|
||||
POINTER = vp_os_calloc (SIZE, 1); \
|
||||
if (NULL == POINTER) \
|
||||
{ \
|
||||
printf ("Unable to alloc %s\n", #POINTER); \
|
||||
return C_FAIL; \
|
||||
printf ("Unable to alloc %s\n", #POINTER); \
|
||||
return C_FAIL; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
@@ -88,286 +92,295 @@ parrot_video_encapsulation_codecs_t video_stage_decoder_lastDetectedCodec = 0;
|
||||
|
||||
C_RESULT video_stage_decoder_open (video_decoder_config_t *cfg)
|
||||
{
|
||||
// Allocate internal datas
|
||||
ALLOC_CHECK (cfg->vlibConf, sizeof (vlib_stage_decoding_config_t));
|
||||
ALLOC_CHECK (cfg->vlibOut, sizeof (vp_api_io_data_t));
|
||||
ALLOC_CHECK (cfg->mp4h264Conf, sizeof (mp4h264_config_t));
|
||||
ALLOC_CHECK (cfg->mp4h264Out, sizeof (vp_api_io_data_t));
|
||||
// Allocate internal datas
|
||||
ALLOC_CHECK (cfg->vlibConf, sizeof (vlib_stage_decoding_config_t));
|
||||
ALLOC_CHECK (cfg->vlibOut, sizeof (vp_api_io_data_t));
|
||||
ALLOC_CHECK (cfg->mp4h264Conf, sizeof (mp4h264_config_t));
|
||||
ALLOC_CHECK (cfg->mp4h264Out, sizeof (vp_api_io_data_t));
|
||||
|
||||
// Fill alloc'd structs with data from cfg
|
||||
// --> MPEG4 / H264
|
||||
cfg->mp4h264Conf->dst_picture.format = cfg->dst_picture->format;
|
||||
// --> VLIB
|
||||
cfg->vlibConf->width = cfg->dst_picture->width;
|
||||
cfg->vlibConf->height = cfg->dst_picture->height;
|
||||
cfg->vlibConf->picture = cfg->dst_picture;
|
||||
cfg->vlibConf->luma_only = FALSE;
|
||||
cfg->vlibConf->block_mode_enable = TRUE;
|
||||
// Fill alloc'd structs with data from cfg
|
||||
// --> MPEG4 / H264
|
||||
cfg->mp4h264Conf->dst_picture.format = cfg->dst_picture->format;
|
||||
// --> VLIB
|
||||
cfg->vlibConf->width = cfg->dst_picture->width;
|
||||
cfg->vlibConf->height = cfg->dst_picture->height;
|
||||
cfg->vlibConf->picture = cfg->dst_picture;
|
||||
cfg->vlibConf->luma_only = FALSE;
|
||||
cfg->vlibConf->block_mode_enable = TRUE;
|
||||
|
||||
switch (cfg->dst_picture->format)
|
||||
switch (cfg->dst_picture->format)
|
||||
{
|
||||
case PIX_FMT_RGB565:
|
||||
cfg->bpp=2;
|
||||
break;
|
||||
cfg->bpp=2;
|
||||
break;
|
||||
case PIX_FMT_RGB24:
|
||||
cfg->bpp=3;
|
||||
break;
|
||||
cfg->bpp=3;
|
||||
break;
|
||||
default:
|
||||
cfg->bpp=0;
|
||||
break;
|
||||
cfg->bpp=0;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
vlib_stage_decoding_open (cfg->vlibConf);
|
||||
mp4h264_open (cfg->mp4h264Conf);
|
||||
|
||||
return C_OK;
|
||||
|
||||
vlib_stage_decoding_open (cfg->vlibConf);
|
||||
mp4h264_open (cfg->mp4h264Conf);
|
||||
|
||||
return C_OK;
|
||||
}
|
||||
|
||||
static inline bool_t havePaVE (uint8_t *buffer)
|
||||
{
|
||||
if (buffer [0] == 'P' &&
|
||||
buffer [1] == 'a' &&
|
||||
buffer [2] == 'V' &&
|
||||
buffer [3] == 'E')
|
||||
if (buffer [0] == 'P' &&
|
||||
buffer [1] == 'a' &&
|
||||
buffer [2] == 'V' &&
|
||||
buffer [3] == 'E')
|
||||
{
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
C_RESULT video_stage_decoder_transform (video_decoder_config_t *cfg, vp_api_io_data_t *in, vp_api_io_data_t *out)
|
||||
{
|
||||
C_RESULT retVal = C_OK;
|
||||
bool_t useVlib = FALSE;
|
||||
bool_t useMP4H264 = FALSE;
|
||||
vp_api_io_data_t *outToCopy = NULL;
|
||||
uint8_t *buffer = in->buffers[in->indexBuffer];
|
||||
static int lastDecodedStreamID = -1;
|
||||
C_RESULT retVal = C_OK;
|
||||
bool_t useVlib = FALSE;
|
||||
bool_t useMP4H264 = FALSE;
|
||||
vp_api_io_data_t *outToCopy = NULL;
|
||||
uint8_t *buffer = in->buffers[in->indexBuffer];
|
||||
static int lastDecodedStreamID = -1;
|
||||
|
||||
#if defined(TARGET_OS_IPHONE) || defined (TARGET_OS_IPHONE_SIMULATOR)
|
||||
uint64_t startTime = 0;
|
||||
uint64_t stopTime = 0;
|
||||
uint64_t elapsedNano = 0;
|
||||
static mach_timebase_info_data_t sTimebaseInfo;
|
||||
if (0 == sTimebaseInfo.denom)
|
||||
uint64_t startTime = 0;
|
||||
uint64_t stopTime = 0;
|
||||
uint64_t elapsedNano = 0;
|
||||
static mach_timebase_info_data_t sTimebaseInfo;
|
||||
if (0 == sTimebaseInfo.denom)
|
||||
{
|
||||
mach_timebase_info (&sTimebaseInfo);
|
||||
mach_timebase_info (&sTimebaseInfo);
|
||||
}
|
||||
startTime = mach_absolute_time ();
|
||||
startTime = mach_absolute_time ();
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// Check for PaVE
|
||||
if (havePaVE (buffer))
|
||||
|
||||
// Check for PaVE
|
||||
if (havePaVE (buffer))
|
||||
{
|
||||
parrot_video_encapsulation_t *PaVE = (parrot_video_encapsulation_t *)buffer;
|
||||
|
||||
video_stage_decoder_lastDetectedCodec = PaVE->video_codec;
|
||||
parrot_video_encapsulation_t *PaVE = (parrot_video_encapsulation_t *)buffer;
|
||||
|
||||
if (lastDecodedStreamID!=-1 && lastDecodedStreamID!=PaVE->stream_id)
|
||||
video_stage_decoder_lastDetectedCodec = PaVE->video_codec;
|
||||
|
||||
if (lastDecodedStreamID!=-1 && lastDecodedStreamID!=PaVE->stream_id && 1 == resetDecoderOnStreamChange)
|
||||
{
|
||||
printf("Resetting the video decoder.\n");
|
||||
video_stage_decoder_close(cfg);
|
||||
video_stage_decoder_open(cfg);
|
||||
PRINT("Resetting the video decoder.\n");
|
||||
video_stage_decoder_close(cfg);
|
||||
video_stage_decoder_open(cfg);
|
||||
}
|
||||
lastDecodedStreamID=PaVE->stream_id;
|
||||
lastDecodedStreamID=PaVE->stream_id;
|
||||
|
||||
|
||||
if (CODEC_VLIB == PaVE->video_codec ||
|
||||
CODEC_P264 == PaVE->video_codec)
|
||||
if (CODEC_VLIB == PaVE->video_codec ||
|
||||
CODEC_P264 == PaVE->video_codec)
|
||||
{
|
||||
useVlib = TRUE;
|
||||
useVlib = TRUE;
|
||||
}
|
||||
else if (CODEC_MPEG4_VISUAL == PaVE->video_codec ||
|
||||
CODEC_MPEG4_AVC == PaVE->video_codec)
|
||||
else if (CODEC_MPEG4_VISUAL == PaVE->video_codec ||
|
||||
CODEC_MPEG4_AVC == PaVE->video_codec)
|
||||
{
|
||||
useMP4H264 = TRUE;
|
||||
useMP4H264 = TRUE;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
// Unknown codec
|
||||
return C_FAIL;
|
||||
// Unknown codec
|
||||
return C_FAIL;
|
||||
}
|
||||
}
|
||||
else if ( ((*(uint32_t*)buffer) & 0xFFFE7C00 )== 0 ) /* true if a UVLC or P264 header is present */
|
||||
else if ( ((*(uint32_t*)buffer) & 0xFFFE7C00 )== 0 ) /* true if a UVLC or P264 header is present */
|
||||
{
|
||||
/* Test bits 15 and 16 of the header to differenciate UVLC and P264 */
|
||||
video_stage_decoder_lastDetectedCodec = ( ((*(uint32_t*)buffer) & 0x8000 )== 0x8000 ) ? CODEC_VLIB : CODEC_P264;
|
||||
// No PaVE -> give to VLIB
|
||||
useVlib = TRUE;
|
||||
/* Test bits 15 and 16 of the header to differenciate UVLC and P264 */
|
||||
video_stage_decoder_lastDetectedCodec = ( ((*(uint32_t*)buffer) & 0x8000 )== 0x8000 ) ? CODEC_VLIB : CODEC_P264;
|
||||
// No PaVE -> give to VLIB
|
||||
useVlib = TRUE;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
// Unknown codec
|
||||
printf(" -- Critical error : unrecognized codec (first bytes : %x %x %x %x %x) --\n",
|
||||
buffer[0],buffer[1],buffer[2],buffer[3],buffer[4]);
|
||||
return C_FAIL;
|
||||
// Unknown codec
|
||||
printf(" -- Critical error : unrecognized codec (first bytes : %x %x %x %x %x) --\n",
|
||||
buffer[0],buffer[1],buffer[2],buffer[3],buffer[4]);
|
||||
return C_FAIL;
|
||||
}
|
||||
|
||||
if (useVlib)
|
||||
if (useVlib)
|
||||
{
|
||||
cfg->vlibConf->num_picture_decoded = cfg->num_picture_decoded;
|
||||
|
||||
retVal = vlib_stage_decoding_transform (cfg->vlibConf, in, cfg->vlibOut);
|
||||
if (C_FAIL == retVal)
|
||||
cfg->vlibConf->num_picture_decoded = cfg->num_picture_decoded;
|
||||
|
||||
retVal = vlib_stage_decoding_transform (cfg->vlibConf, in, cfg->vlibOut);
|
||||
if (C_FAIL == retVal)
|
||||
{
|
||||
return retVal;
|
||||
return retVal;
|
||||
}
|
||||
cfg->num_picture_decoded = cfg->vlibConf->num_picture_decoded;
|
||||
cfg->num_frames = cfg->vlibConf->controller.num_frames;
|
||||
|
||||
cfg->src_picture->height = cfg->vlibConf->controller.height;
|
||||
cfg->src_picture->width = cfg->vlibConf->controller.width;
|
||||
cfg->rowstride = cfg->dst_picture->width * cfg->bpp; // Size of the buffer we got for VLIB
|
||||
cfg->vlibOut->size = cfg->rowstride * cfg->dst_picture->height;
|
||||
outToCopy = cfg->vlibOut;
|
||||
cfg->num_picture_decoded = cfg->vlibConf->num_picture_decoded;
|
||||
cfg->num_frames = cfg->vlibConf->controller.num_frames;
|
||||
|
||||
cfg->src_picture->height = cfg->vlibConf->controller.height;
|
||||
cfg->src_picture->width = cfg->vlibConf->controller.width;
|
||||
cfg->rowstride = cfg->dst_picture->width * cfg->bpp; // Size of the buffer we got for VLIB
|
||||
cfg->vlibOut->size = cfg->rowstride * cfg->dst_picture->height;
|
||||
outToCopy = cfg->vlibOut;
|
||||
}
|
||||
|
||||
if (useMP4H264)
|
||||
if (useMP4H264)
|
||||
{
|
||||
parrot_video_encapsulation_t *PaVE = (parrot_video_encapsulation_t *)buffer;
|
||||
|
||||
cfg->mp4h264Conf->num_picture_decoded = cfg->num_picture_decoded;
|
||||
|
||||
retVal = mp4h264_transform (cfg->mp4h264Conf, in, cfg->mp4h264Out);
|
||||
if (C_FAIL == retVal)
|
||||
parrot_video_encapsulation_t *PaVE = (parrot_video_encapsulation_t *)buffer;
|
||||
|
||||
cfg->mp4h264Conf->num_picture_decoded = cfg->num_picture_decoded;
|
||||
|
||||
retVal = mp4h264_transform (cfg->mp4h264Conf, in, cfg->mp4h264Out);
|
||||
if (C_FAIL == retVal)
|
||||
{
|
||||
return retVal;
|
||||
return retVal;
|
||||
}
|
||||
cfg->num_picture_decoded = cfg->mp4h264Conf->num_picture_decoded;
|
||||
cfg->num_frames = PaVE->frame_number;
|
||||
|
||||
cfg->dst_picture->height = cfg->mp4h264Conf->dst_picture.height;
|
||||
cfg->dst_picture->width = cfg->mp4h264Conf->dst_picture.width;
|
||||
cfg->src_picture->height = cfg->mp4h264Conf->src_picture.height;
|
||||
cfg->src_picture->width = cfg->mp4h264Conf->src_picture.width;
|
||||
cfg->rowstride = cfg->dst_picture->width * cfg->bpp; // Size of the actual picture, alloc'd by MPEG4 / H264 stage
|
||||
outToCopy = cfg->mp4h264Out;
|
||||
cfg->num_picture_decoded = cfg->mp4h264Conf->num_picture_decoded;
|
||||
cfg->num_frames = PaVE->frame_number;
|
||||
|
||||
cfg->dst_picture->height = cfg->mp4h264Conf->dst_picture.height;
|
||||
cfg->dst_picture->width = cfg->mp4h264Conf->dst_picture.width;
|
||||
cfg->src_picture->height = cfg->mp4h264Conf->src_picture.height;
|
||||
cfg->src_picture->width = cfg->mp4h264Conf->src_picture.width;
|
||||
cfg->rowstride = cfg->dst_picture->width * cfg->bpp; // Size of the actual picture, alloc'd by MPEG4 / H264 stage
|
||||
outToCopy = cfg->mp4h264Out;
|
||||
}
|
||||
|
||||
if (NULL == outToCopy)
|
||||
if (NULL == outToCopy)
|
||||
{
|
||||
retVal = C_FAIL;
|
||||
retVal = C_FAIL;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
out->numBuffers = outToCopy->numBuffers;
|
||||
out->buffers = outToCopy->buffers;
|
||||
out->indexBuffer = outToCopy->indexBuffer;
|
||||
out->size = outToCopy->size;
|
||||
out->lineSize = outToCopy->lineSize;
|
||||
out->status = outToCopy->status;
|
||||
out->numBuffers = outToCopy->numBuffers;
|
||||
out->buffers = outToCopy->buffers;
|
||||
out->indexBuffer = outToCopy->indexBuffer;
|
||||
out->size = outToCopy->size;
|
||||
out->lineSize = outToCopy->lineSize;
|
||||
out->status = outToCopy->status;
|
||||
|
||||
retVal = C_OK;
|
||||
retVal = C_OK;
|
||||
}
|
||||
|
||||
#if defined(TARGET_OS_IPHONE) || defined (TARGET_OS_IPHONE_SIMULATOR)
|
||||
stopTime = mach_absolute_time ();
|
||||
elapsedNano = (stopTime - startTime) * sTimebaseInfo.numer / sTimebaseInfo.denom;
|
||||
if (0.0 == DEBUG_decodingTimeUsec)
|
||||
stopTime = mach_absolute_time ();
|
||||
elapsedNano = (stopTime - startTime) * sTimebaseInfo.numer / sTimebaseInfo.denom;
|
||||
if (0.0 == DEBUG_decodingTimeUsec)
|
||||
{
|
||||
DEBUG_decodingTimeUsec = elapsedNano / 1000.0;
|
||||
DEBUG_decodingTimeUsec = elapsedNano / 1000.0;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
DEBUG_decodingTimeUsec = 0.9 * DEBUG_decodingTimeUsec + (0.1 * elapsedNano / 1000.0);
|
||||
DEBUG_decodingTimeUsec = 0.9 * DEBUG_decodingTimeUsec + (0.1 * elapsedNano / 1000.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef USE_LINUX
|
||||
usleep(video_stage_decoder_fakeLatency * 1000);
|
||||
usleep(video_stage_decoder_fakeLatency * 1000);
|
||||
#endif
|
||||
|
||||
|
||||
return retVal;
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
C_RESULT video_stage_decoder_close (video_decoder_config_t *cfg)
|
||||
{
|
||||
C_RESULT res, resVlib, resMp4h264;
|
||||
resVlib = vlib_stage_decoding_close (cfg->vlibConf);
|
||||
resMp4h264 = mp4h264_close (cfg->mp4h264Conf);
|
||||
res = (C_OK == resVlib && C_OK == resMp4h264 ) ? C_OK : C_FAIL;
|
||||
vp_os_free (cfg->vlibConf);
|
||||
cfg->vlibConf = NULL;
|
||||
vp_os_free (cfg->vlibOut);
|
||||
cfg->vlibOut = NULL;
|
||||
vp_os_free (cfg->mp4h264Conf);
|
||||
cfg->mp4h264Conf = NULL;
|
||||
vp_os_free (cfg->mp4h264Out);
|
||||
cfg->mp4h264Out = NULL;
|
||||
return res;
|
||||
C_RESULT res, resVlib, resMp4h264;
|
||||
resVlib = vlib_stage_decoding_close (cfg->vlibConf);
|
||||
resMp4h264 = mp4h264_close (cfg->mp4h264Conf);
|
||||
res = (C_OK == resVlib && C_OK == resMp4h264 ) ? C_OK : C_FAIL;
|
||||
vp_os_free (cfg->vlibConf);
|
||||
cfg->vlibConf = NULL;
|
||||
vp_os_free (cfg->vlibOut);
|
||||
cfg->vlibOut = NULL;
|
||||
vp_os_free (cfg->mp4h264Conf);
|
||||
cfg->mp4h264Conf = NULL;
|
||||
vp_os_free (cfg->mp4h264Out);
|
||||
cfg->mp4h264Out = NULL;
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifdef USE_ANDROID
|
||||
#define NEONCHECK_BUFFER_STRING_SIZE (512)
|
||||
void checkNeonSupport ()
|
||||
{
|
||||
neon_status_t loc_neonStat = NEON_SUPPORT_FAIL;
|
||||
FILE *cpuInfo = fopen ("/proc/cpuinfo", "r");
|
||||
if (NULL == cpuInfo)
|
||||
neon_status_t loc_neonStat = NEON_SUPPORT_FAIL;
|
||||
resetDecoderOnStreamChange = 0;
|
||||
FILE *cpuInfo = fopen ("/proc/cpuinfo", "r");
|
||||
if (NULL == cpuInfo)
|
||||
{
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
char *neonCheckStrBuf = vp_os_malloc (NEONCHECK_BUFFER_STRING_SIZE * sizeof (char));
|
||||
if (NULL == neonCheckStrBuf)
|
||||
char *neonCheckStrBuf = vp_os_malloc (NEONCHECK_BUFFER_STRING_SIZE * sizeof (char));
|
||||
if (NULL == neonCheckStrBuf)
|
||||
{
|
||||
fclose (cpuInfo);
|
||||
return;
|
||||
fclose (cpuInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
while (NULL != fgets (neonCheckStrBuf, NEONCHECK_BUFFER_STRING_SIZE, cpuInfo))
|
||||
while (NULL != fgets (neonCheckStrBuf, NEONCHECK_BUFFER_STRING_SIZE, cpuInfo))
|
||||
{
|
||||
char *supportTest = strstr (neonCheckStrBuf, "neon");
|
||||
if (NULL != supportTest)
|
||||
char *supportTest = strstr (neonCheckStrBuf, "neon");
|
||||
if (NULL != supportTest)
|
||||
{
|
||||
loc_neonStat = NEON_SUPPORT_OK;
|
||||
break;
|
||||
loc_neonStat = NEON_SUPPORT_OK;
|
||||
resetDecoderOnStreamChange = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
vp_os_free (neonCheckStrBuf);
|
||||
fclose (cpuInfo);
|
||||
|
||||
neonStatus = loc_neonStat;
|
||||
vp_os_free (neonCheckStrBuf);
|
||||
neonCheckStrBuf = NULL;
|
||||
fclose (cpuInfo);
|
||||
|
||||
neonStatus = loc_neonStat;
|
||||
}
|
||||
|
||||
C_RESULT mp4h264_open (mp4h264_config_t *cfg)
|
||||
{
|
||||
if (NEON_SUPPORT_UNKNOWN == neonStatus)
|
||||
checkNeonSupport ();
|
||||
if (NEON_SUPPORT_OK == neonStatus)
|
||||
return ittiam_stage_decoding_open (cfg);
|
||||
else
|
||||
return ffmpeg_stage_decoding_open (cfg);
|
||||
#if ITTIAM_SUPPORT
|
||||
if (NEON_SUPPORT_UNKNOWN == neonStatus)
|
||||
checkNeonSupport ();
|
||||
if (NEON_SUPPORT_OK == neonStatus)
|
||||
return ittiam_stage_decoding_open ((ittiam_stage_decoding_config_t *)cfg);
|
||||
else
|
||||
#endif
|
||||
return ffmpeg_stage_decoding_open (cfg);
|
||||
}
|
||||
|
||||
C_RESULT mp4h264_transform (mp4h264_config_t *cfg, vp_api_io_data_t *in, vp_api_io_data_t *out)
|
||||
{
|
||||
if (NEON_SUPPORT_UNKNOWN == neonStatus)
|
||||
checkNeonSupport ();
|
||||
if (NEON_SUPPORT_OK == neonStatus)
|
||||
return ittiam_stage_decoding_transform (cfg, in, out);
|
||||
else
|
||||
return ffmpeg_stage_decoding_transform (cfg, in, out);
|
||||
#if ITTIAM_SUPPORT
|
||||
if (NEON_SUPPORT_UNKNOWN == neonStatus)
|
||||
checkNeonSupport ();
|
||||
if (NEON_SUPPORT_OK == neonStatus)
|
||||
return ittiam_stage_decoding_transform ((ittiam_stage_decoding_config_t *)cfg, in, out);
|
||||
else
|
||||
#endif
|
||||
return ffmpeg_stage_decoding_transform (cfg, in, out);
|
||||
}
|
||||
|
||||
C_RESULT mp4h264_close (mp4h264_config_t *cfg)
|
||||
{
|
||||
if (NEON_SUPPORT_UNKNOWN == neonStatus)
|
||||
checkNeonSupport ();
|
||||
if (NEON_SUPPORT_OK == neonStatus)
|
||||
return ittiam_stage_decoding_close (cfg);
|
||||
else
|
||||
return ffmpeg_stage_decoding_close (cfg);
|
||||
#if ITTIAM_SUPPORT
|
||||
if (NEON_SUPPORT_UNKNOWN == neonStatus)
|
||||
checkNeonSupport ();
|
||||
if (NEON_SUPPORT_OK == neonStatus)
|
||||
return ittiam_stage_decoding_close ((ittiam_stage_decoding_config_t *)cfg);
|
||||
else
|
||||
#endif
|
||||
return ffmpeg_stage_decoding_close (cfg);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -11,18 +11,17 @@
|
||||
#ifndef __VIDEO_STAGE_DECODER_H__
|
||||
#define __VIDEO_STAGE_DECODER_H__
|
||||
|
||||
#ifndef TARGET_OS_ANDROID
|
||||
# ifdef ITTIAM_SUPPORT
|
||||
# define mp4h264_config_t ittiam_stage_decoding_config_t
|
||||
# include <ardrone_tool/Video/video_stage_ittiam_decoder.h>
|
||||
# else // FFMPEG
|
||||
# define mp4h264_config_t ffmpeg_stage_decoding_config_t
|
||||
# endif
|
||||
#else
|
||||
#ifdef FFMPEG_SUPPORT
|
||||
# define mp4h264_config_t ffmpeg_stage_decoding_config_t
|
||||
# include <ardrone_tool/Video/video_stage_ittiam_decoder.h>
|
||||
#elif defined (ITTIAM_SUPPORT)
|
||||
# define mp4h264_config_t ittiam_stage_decoding_config_t
|
||||
#else
|
||||
# error Either FFMPEG_SUPPORT or ITTIAM_SUPPORT must be defined
|
||||
#endif
|
||||
|
||||
#ifdef ITTIAM_SUPPORT
|
||||
# include <ardrone_tool/Video/video_stage_ittiam_decoder.h>
|
||||
#endif
|
||||
|
||||
#ifdef FFMPEG_SUPPORT
|
||||
# include <ardrone_tool/Video/video_stage_ffmpeg_decoder.h>
|
||||
|
||||
@@ -17,10 +17,6 @@
|
||||
|
||||
#include <ardrone_tool/Video/video_navdata_handler.h>
|
||||
|
||||
#ifdef USE_ELINUX
|
||||
#define VIDEO_ENCODED_FILE_DEFAULT_PATH "/data/video/usb/"
|
||||
#endif
|
||||
|
||||
#define VIDEO_ENCODED_RECORDER_VERBOSE (1)
|
||||
|
||||
#if defined(DEBUG) || VIDEO_ENCODED_RECORDER_VERBOSE
|
||||
@@ -58,468 +54,269 @@ extern char flight_dir[];
|
||||
#endif
|
||||
|
||||
const vp_api_stage_funcs_t video_encoded_recorder_funcs = {
|
||||
(vp_api_stage_handle_msg_t) video_stage_encoded_recorder_handle,
|
||||
(vp_api_stage_open_t) video_stage_encoded_recorder_open,
|
||||
(vp_api_stage_transform_t) video_stage_encoded_recorder_transform,
|
||||
(vp_api_stage_close_t) video_stage_encoded_recorder_close
|
||||
(vp_api_stage_handle_msg_t) video_stage_encoded_recorder_handle,
|
||||
(vp_api_stage_open_t) video_stage_encoded_recorder_open,
|
||||
(vp_api_stage_transform_t) video_stage_encoded_recorder_transform,
|
||||
(vp_api_stage_close_t) video_stage_encoded_recorder_close
|
||||
};
|
||||
|
||||
video_stage_encoded_recorder_config_t video_stage_encoded_recorder_config;
|
||||
|
||||
|
||||
#ifdef USE_ELINUX
|
||||
DEFINE_THREAD_ROUTINE_STACK(video_stage_encoded_recorder,param,VIDEO_STAGE_ENCODED_RECORDER_STACK_SIZE)
|
||||
{
|
||||
int res;
|
||||
video_stage_encoded_recorder_config_t *cfg = (video_stage_encoded_recorder_config_t *)param;
|
||||
video_stage_encoded_recorder_msg_t msg;
|
||||
char errBuf [50] = {0};
|
||||
ardrone_video_error_t vError = ARDRONE_VIDEO_NO_ERROR;
|
||||
parrot_video_encapsulation_t *PaVE;
|
||||
//int counter = 0;
|
||||
|
||||
/* TODO : check if mutual exclusion with the main thread is needed */
|
||||
|
||||
while(1)
|
||||
{
|
||||
/* Read the address of a new slice to write in the video file */
|
||||
res = read(cfg->com_pipe[0],&msg,sizeof(msg));
|
||||
|
||||
if (res!=sizeof(msg)) { sleep(1); continue; }
|
||||
|
||||
//printf("----> Reading %p %d bytes\n",msg.slice,msg.sliceSize);
|
||||
PaVE = (parrot_video_encapsulation_t *) msg.slice;
|
||||
|
||||
if (msg.slice!=NULL)
|
||||
{
|
||||
/* Create a new MP4 file if necessary */
|
||||
if (NULL==cfg->video)
|
||||
{
|
||||
cfg->video = ardrone_video_start (cfg->video_filename, cfg->fps, VIDEO_FORMAT, &vError);
|
||||
if (ARDRONE_VIDEO_SUCCEEDED (vError) && NULL != cfg->video)
|
||||
{
|
||||
cfg->currentStreamId = PaVE->stream_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
VER_PRINT ("An error occured when creating video");
|
||||
cfg->startRec=VIDEO_ENCODED_STOPPED;
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL!=cfg->video)
|
||||
{
|
||||
ardrone_video_error_t vError = ardrone_video_addSlice (cfg->video, msg.slice);
|
||||
|
||||
if (ARDRONE_VIDEO_FAILED (vError))
|
||||
{
|
||||
ardrone_video_error_string (vError, errBuf, 50);
|
||||
VER_PRINT ("Error while recording frame : %s", errBuf);
|
||||
ardrone_video_cleanup (&(cfg->video));
|
||||
cfg->startRec = VIDEO_ENCODED_STOPPED;
|
||||
}
|
||||
if (1 == frameIsLastFrame(msg.slice))
|
||||
{
|
||||
VER_PRINT ("Received last frame for current stream, finishing video\n");
|
||||
video_stage_encoded_recorder_finish (cfg);
|
||||
}
|
||||
|
||||
//counter++; if (counter%16) { sync(); }
|
||||
}
|
||||
|
||||
/* Free the data bloc which was just written */
|
||||
vp_os_free(msg.slice);
|
||||
}
|
||||
else /* the data pointer is NULL to signal the end of the recording */
|
||||
{
|
||||
video_stage_encoded_recorder_finish (cfg);
|
||||
}
|
||||
|
||||
}/*while 1*/
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
C_RESULT video_stage_encoded_recorder_finish (video_stage_encoded_recorder_config_t *cfg)
|
||||
{
|
||||
C_RESULT retVal = C_OK;
|
||||
C_RESULT retVal = C_OK;
|
||||
|
||||
#ifndef USE_ELINUX
|
||||
endRetreiving ();
|
||||
#endif
|
||||
endRetreiving ();
|
||||
|
||||
cfg->lastStreamId = cfg->currentStreamId;
|
||||
ardrone_video_error_t vError = ardrone_video_finish (&(cfg->video));
|
||||
if (ARDRONE_VIDEO_SUCCEEDED (vError))
|
||||
cfg->lastStreamId = cfg->currentStreamId;
|
||||
ardrone_video_error_t vError = ardrone_video_finish (&(cfg->video));
|
||||
if (ARDRONE_VIDEO_SUCCEEDED (vError))
|
||||
{
|
||||
VER_PRINT ("Video %s successfully written", cfg->video_filename);
|
||||
VER_PRINT ("Video %s successfully written", cfg->video_filename);
|
||||
if(cfg->finish_callback != NULL)
|
||||
cfg->finish_callback((const char *)cfg->video_filename);
|
||||
cfg->finish_callback((const char *)cfg->video_filename, FALSE);
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
VER_PRINT ("Error while completing video");
|
||||
retVal = C_FAIL;
|
||||
VER_PRINT ("Error while completing video");
|
||||
retVal = C_FAIL;
|
||||
}
|
||||
// Erase filename
|
||||
vp_os_memset (cfg->video_filename, 0x0, VIDEO_ENCODED_FILENAME_LENGTH);
|
||||
cfg->startRec = VIDEO_ENCODED_STOPPED;
|
||||
// Erase filename
|
||||
vp_os_memset (cfg->video_filename, 0x0, VIDEO_ENCODED_FILENAME_LENGTH);
|
||||
cfg->startRec = VIDEO_ENCODED_STOPPED;
|
||||
|
||||
#ifdef USE_ELINUX
|
||||
ardrone_video_system_cleanup();
|
||||
#endif
|
||||
|
||||
return retVal;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
C_RESULT video_stage_encoded_recorder_handle (video_stage_encoded_recorder_config_t * cfg, PIPELINE_MSG msg_id, void *callback, void *param)
|
||||
{
|
||||
#ifdef USE_ELINUX
|
||||
/* Handling the asynchronous mode */
|
||||
video_stage_encoded_recorder_msg_t asyn_msg;
|
||||
#endif
|
||||
vp_os_mutex_lock (&cfg->videoMutex);
|
||||
|
||||
|
||||
#ifndef USE_ELINUX
|
||||
vp_os_mutex_lock (&cfg->videoMutex);
|
||||
#endif
|
||||
|
||||
void (*recorder_callback)(video_stage_encoded_recorder_config_t*) = callback;
|
||||
|
||||
switch (msg_id)
|
||||
void (*recorder_callback)(video_stage_encoded_recorder_config_t*) = callback;
|
||||
|
||||
switch (msg_id)
|
||||
{
|
||||
case PIPELINE_MSG_START: // video start
|
||||
if(cfg->startRec==VIDEO_ENCODED_STOPPED)
|
||||
if(cfg->startRec==VIDEO_ENCODED_STOPPED)
|
||||
{
|
||||
time_t t;
|
||||
char date[ARDRONE_DATE_MAXSIZE];
|
||||
ardrone_time2date(*((uint32_t*)param), ARDRONE_FILE_DATE_FORMAT, date);
|
||||
char media_dirname[VIDEO_ENCODED_FILENAME_LENGTH];
|
||||
struct stat statbuf;
|
||||
cfg->startRec = VIDEO_ENCODED_START_RECORD;
|
||||
time_t t;
|
||||
char date[ARDRONE_DATE_MAXSIZE];
|
||||
ardrone_time2date(*((uint32_t*)param), ARDRONE_FILE_DATE_FORMAT, date);
|
||||
char media_dirname[VIDEO_ENCODED_FILENAME_LENGTH];
|
||||
struct stat statbuf;
|
||||
|
||||
snprintf(media_dirname, VIDEO_ENCODED_FILENAME_LENGTH, "%s/media_%s", VIDEO_ENCODED_FILE_DEFAULT_PATH, date);
|
||||
if((stat(media_dirname, &statbuf) != 0) && (mkdir(media_dirname, 0777) >= 0))
|
||||
VER_PRINT("Create local media directory %s if not exist\n", media_dirname);
|
||||
snprintf(media_dirname, VIDEO_ENCODED_FILENAME_LENGTH, "%s/media_%s", VIDEO_ENCODED_FILE_DEFAULT_PATH, date);
|
||||
if((stat(media_dirname, &statbuf) != 0) && (mkdir(media_dirname, 0777) >= 0))
|
||||
VER_PRINT("Create local media directory %s if not exist\n", media_dirname);
|
||||
|
||||
t = time(NULL);
|
||||
ardrone_time2date(t, ARDRONE_FILE_DATE_FORMAT, date);
|
||||
t = time(NULL);
|
||||
ardrone_time2date(t, ARDRONE_FILE_DATE_FORMAT, date);
|
||||
|
||||
snprintf(cfg->video_filename,
|
||||
VIDEO_ENCODED_FILENAME_LENGTH,
|
||||
"%s/video_%s.%s",
|
||||
media_dirname,
|
||||
date,
|
||||
MOVIE_FILE_EXTENSION);
|
||||
VIDEO_ENCODED_FILENAME_LENGTH,
|
||||
"%s/video_%s.%s",
|
||||
media_dirname,
|
||||
date,
|
||||
MOVIE_FILE_EXTENSION);
|
||||
|
||||
cfg->startRec = VIDEO_ENCODED_START_RECORD;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case PIPELINE_MSG_STOP: // video stop
|
||||
if (cfg->startRec==VIDEO_ENCODED_START_RECORD)
|
||||
if (cfg->startRec==VIDEO_ENCODED_START_RECORD)
|
||||
{
|
||||
cfg->startRec=VIDEO_ENCODED_STOPPED;
|
||||
cfg->startRec=VIDEO_ENCODED_STOPPED;
|
||||
}
|
||||
else if (cfg->startRec==VIDEO_ENCODED_RECORDING)
|
||||
else if (cfg->startRec==VIDEO_ENCODED_RECORDING)
|
||||
{
|
||||
cfg->startRec = VIDEO_ENCODED_WAITING_STREAM_END;
|
||||
#ifndef USE_ELINUX
|
||||
startRetreiving ();
|
||||
#endif
|
||||
cfg->startRec = VIDEO_ENCODED_WAITING_STREAM_END;
|
||||
startRetreiving ();
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case PIPELINE_MSG_SUSPEND: // Force stop
|
||||
if (cfg->startRec==VIDEO_ENCODED_START_RECORD)
|
||||
if (cfg->startRec==VIDEO_ENCODED_START_RECORD)
|
||||
{
|
||||
cfg->startRec=VIDEO_ENCODED_STOPPED;
|
||||
cfg->startRec=VIDEO_ENCODED_STOPPED;
|
||||
}
|
||||
else if (cfg->startRec==VIDEO_ENCODED_RECORDING ||
|
||||
cfg->startRec==VIDEO_ENCODED_WAITING_STREAM_END)
|
||||
else if (cfg->startRec==VIDEO_ENCODED_RECORDING ||
|
||||
cfg->startRec==VIDEO_ENCODED_WAITING_STREAM_END)
|
||||
{
|
||||
#ifdef USE_ELINUX
|
||||
if (cfg->use_asynchronous_mode)
|
||||
{
|
||||
/* Send an empty slice to the asynchronous thread */
|
||||
asyn_msg.sliceSize = 0;
|
||||
asyn_msg.slice = NULL;
|
||||
write(cfg->com_pipe[1],&asyn_msg,sizeof(asyn_msg));
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
video_stage_encoded_recorder_finish (cfg);
|
||||
|
||||
#ifdef USE_ELINUX
|
||||
}
|
||||
#endif
|
||||
|
||||
video_stage_encoded_recorder_finish (cfg);
|
||||
}
|
||||
break;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (recorder_callback!=NULL) {
|
||||
recorder_callback(cfg);
|
||||
break;
|
||||
}
|
||||
if (recorder_callback!=NULL) {
|
||||
recorder_callback(cfg);
|
||||
}
|
||||
|
||||
vp_os_mutex_unlock (&cfg->videoMutex);
|
||||
|
||||
#ifndef USE_ELINUX
|
||||
vp_os_mutex_unlock (&cfg->videoMutex);
|
||||
#endif
|
||||
|
||||
return (VP_SUCCESS);
|
||||
return (VP_SUCCESS);
|
||||
}
|
||||
|
||||
bool_t video_stage_encoded_recorder_state(void)
|
||||
{
|
||||
return (video_stage_encoded_recorder_config.startRec != VIDEO_ENCODED_STOPPED);
|
||||
return (video_stage_encoded_recorder_config.startRec != VIDEO_ENCODED_STOPPED);
|
||||
}
|
||||
|
||||
video_encoded_record_state video_stage_encoded_complete_recorder_state (void)
|
||||
{
|
||||
return video_stage_encoded_recorder_config.startRec;
|
||||
return video_stage_encoded_recorder_config.startRec;
|
||||
}
|
||||
|
||||
void video_stage_encoded_recorder_enable(bool_t enable, uint32_t timestamp)
|
||||
{
|
||||
printf("Recording %s...\n", enable ? "started" : "stopped");
|
||||
video_stage_encoded_recorder_handle (&video_stage_encoded_recorder_config, (enable ? PIPELINE_MSG_START : PIPELINE_MSG_STOP), NULL, ×tamp);
|
||||
printf("Recording %s...\n", enable ? "started" : "stopped");
|
||||
video_stage_encoded_recorder_handle (&video_stage_encoded_recorder_config, (enable ? PIPELINE_MSG_START : PIPELINE_MSG_STOP), NULL, ×tamp);
|
||||
}
|
||||
|
||||
void video_stage_encoded_recorder_com_timeout (void)
|
||||
{
|
||||
if (VIDEO_ENCODED_WAITING_STREAM_END == video_stage_encoded_recorder_config.startRec)
|
||||
if (VIDEO_ENCODED_WAITING_STREAM_END == video_stage_encoded_recorder_config.startRec)
|
||||
{
|
||||
video_stage_encoded_recorder_force_stop ();
|
||||
video_stage_encoded_recorder_force_stop ();
|
||||
}
|
||||
}
|
||||
|
||||
void video_stage_encoded_recorder_force_stop (void)
|
||||
{
|
||||
printf ("Force recording stop\n");
|
||||
video_stage_encoded_recorder_handle (&video_stage_encoded_recorder_config, PIPELINE_MSG_SUSPEND, NULL, NULL);
|
||||
printf ("Force recording stop\n");
|
||||
video_stage_encoded_recorder_handle (&video_stage_encoded_recorder_config, PIPELINE_MSG_SUSPEND, NULL, NULL);
|
||||
}
|
||||
|
||||
C_RESULT video_stage_encoded_recorder_open(video_stage_encoded_recorder_config_t *cfg)
|
||||
{
|
||||
|
||||
if (0 == cfg->fps)
|
||||
if (0 == cfg->fps)
|
||||
{
|
||||
cfg->fps = 30;
|
||||
cfg->fps = 30;
|
||||
}
|
||||
cfg->startRec=VIDEO_ENCODED_STOPPED;
|
||||
cfg->lastStreamId = UINT16_MAX;
|
||||
cfg->currentStreamId = UINT16_MAX;
|
||||
cfg->startRec=VIDEO_ENCODED_STOPPED;
|
||||
cfg->lastStreamId = UINT16_MAX;
|
||||
cfg->currentStreamId = UINT16_MAX;
|
||||
|
||||
cfg->video = NULL;
|
||||
cfg->video = NULL;
|
||||
|
||||
#ifndef USE_ELINUX
|
||||
vp_os_mutex_init (&cfg->videoMutex);
|
||||
ardrone_video_remove_all (VIDEO_ENCODED_FILE_DEFAULT_PATH);
|
||||
#endif
|
||||
|
||||
#ifdef USE_ELINUX
|
||||
if (cfg->use_asynchronous_mode){
|
||||
/* Create a pipe to send video slices to the recording thread */
|
||||
pipe((int*)(&cfg->com_pipe));
|
||||
vp_os_mutex_init (&cfg->videoMutex);
|
||||
ardrone_video_remove_all (VIDEO_ENCODED_FILE_DEFAULT_PATH);
|
||||
|
||||
/* Create the above-mentioned thread */
|
||||
vp_os_thread_create(thread_video_stage_encoded_recorder,
|
||||
(void*)cfg,
|
||||
&cfg->thread_handle,
|
||||
cfg->thread_priority,
|
||||
"VideoFlashRec",
|
||||
(void*)stack_video_stage_encoded_recorder,
|
||||
sizeof(stack_video_stage_encoded_recorder),
|
||||
&cfg->thread );
|
||||
}
|
||||
#endif
|
||||
|
||||
return C_OK;
|
||||
return C_OK;
|
||||
}
|
||||
|
||||
int frameIsLastFrame (uint8_t *data)
|
||||
{
|
||||
int retVal = 0;
|
||||
if (PAVE_CHECK (data))
|
||||
int retVal = 0;
|
||||
if (PAVE_CHECK (data))
|
||||
{
|
||||
parrot_video_encapsulation_t *PaVE = (parrot_video_encapsulation_t *)data;
|
||||
if (PAVE_CTRL_LAST_FRAME_IN_STREAM & PaVE->control)
|
||||
parrot_video_encapsulation_t *PaVE = (parrot_video_encapsulation_t *)data;
|
||||
if (PAVE_CTRL_LAST_FRAME_IN_STREAM & PaVE->control)
|
||||
{
|
||||
retVal = 1;
|
||||
retVal = 1;
|
||||
}
|
||||
}
|
||||
return retVal;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
#ifdef USE_ELINUX
|
||||
int ardrone_video_usb_key_get_free_space(void);
|
||||
#endif
|
||||
|
||||
C_RESULT video_stage_encoded_recorder_transform(video_stage_encoded_recorder_config_t *cfg, vp_api_io_data_t *in, vp_api_io_data_t *out)
|
||||
{
|
||||
#ifdef USE_ELINUX
|
||||
/* Handling the asynchronous mode */
|
||||
video_stage_encoded_recorder_msg_t asyn_msg;
|
||||
#endif
|
||||
vp_os_mutex_lock (&out->lock);
|
||||
vp_os_mutex_lock (&cfg->videoMutex);
|
||||
|
||||
vp_os_mutex_lock (&out->lock);
|
||||
|
||||
#ifndef USE_ELINUX
|
||||
vp_os_mutex_lock (&cfg->videoMutex);
|
||||
#endif
|
||||
|
||||
// Copy in to out
|
||||
if (NULL != in && NULL != out)
|
||||
// Copy in to out
|
||||
if (NULL != in && NULL != out)
|
||||
{
|
||||
out->numBuffers = in->numBuffers;
|
||||
out->indexBuffer = in->indexBuffer;
|
||||
out->lineSize = in->lineSize;
|
||||
out->size = in->size;
|
||||
out->status = in->status;
|
||||
out->buffers = in->buffers;
|
||||
out->status = VP_API_STATUS_PROCESSING;
|
||||
out->numBuffers = in->numBuffers;
|
||||
out->indexBuffer = in->indexBuffer;
|
||||
out->lineSize = in->lineSize;
|
||||
out->size = in->size;
|
||||
out->status = in->status;
|
||||
out->buffers = in->buffers;
|
||||
out->status = VP_API_STATUS_PROCESSING;
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_ELINUX
|
||||
/* The drone pipeline may call the recorder with an empty input */
|
||||
uint8_t *slice = in->buffers[in->indexBuffer];
|
||||
parrot_video_encapsulation_t *PaVE = (parrot_video_encapsulation_t *)slice;
|
||||
|
||||
if (NULL==in || NULL==in->buffers || in->size<1) { vp_os_mutex_unlock (&out->lock); return C_OK; }
|
||||
#endif
|
||||
|
||||
uint8_t *slice = in->buffers[in->indexBuffer];
|
||||
parrot_video_encapsulation_t *PaVE = (parrot_video_encapsulation_t *)slice;
|
||||
|
||||
if (cfg->lastStreamId == PaVE->stream_id)
|
||||
if (cfg->lastStreamId == PaVE->stream_id)
|
||||
{
|
||||
VER_PRINT ("Got a video slice from an old stream, skipping\n");
|
||||
#ifndef USE_ELINUX
|
||||
vp_os_mutex_unlock (&cfg->videoMutex);
|
||||
#endif
|
||||
vp_os_mutex_unlock (&out->lock);
|
||||
return C_OK;
|
||||
VER_PRINT ("Got a video slice from an old stream, skipping\n");
|
||||
vp_os_mutex_unlock (&cfg->videoMutex);
|
||||
vp_os_mutex_unlock (&out->lock);
|
||||
return C_OK;
|
||||
}
|
||||
|
||||
if(cfg->startRec == VIDEO_ENCODED_START_RECORD)
|
||||
|
||||
if(cfg->startRec == VIDEO_ENCODED_START_RECORD)
|
||||
{
|
||||
ardrone_video_error_t vError = ARDRONE_VIDEO_NO_ERROR;
|
||||
ardrone_video_error_t vError = ARDRONE_VIDEO_NO_ERROR;
|
||||
|
||||
#ifdef USE_ELINUX
|
||||
/* Determine the amount of video data we can store */
|
||||
cfg->quota = ardrone_video_usb_key_get_free_space() /* kbytes */ - ( 100 * 1024 ); /* Keep 100 megabytes free */
|
||||
if(cfg->quota<0) { cfg->quota = 0; }
|
||||
printf("Flash video recording : available space : %dkb (time est. %d\'%d\") - (keeping a 100Mb margin on %s)\n",
|
||||
cfg->quota,(cfg->quota>>10)/60,(cfg->quota>>10)%60,
|
||||
VIDEO_ENCODED_FILE_DEFAULT_PATH);
|
||||
|
||||
if (cfg->use_asynchronous_mode)
|
||||
cfg->video = ardrone_video_start (cfg->video_filename, cfg->fps, VIDEO_FORMAT, &vError);
|
||||
if (ARDRONE_VIDEO_SUCCEEDED (vError) && NULL != cfg->video)
|
||||
{
|
||||
cfg->startRec=VIDEO_ENCODED_RECORDING;
|
||||
cfg->startRec=VIDEO_ENCODED_RECORDING;
|
||||
cfg->currentStreamId = PaVE->stream_id;
|
||||
}
|
||||
else{
|
||||
#endif
|
||||
|
||||
cfg->video = ardrone_video_start (cfg->video_filename, cfg->fps, VIDEO_FORMAT, &vError);
|
||||
if (ARDRONE_VIDEO_SUCCEEDED (vError) && NULL != cfg->video)
|
||||
{
|
||||
cfg->startRec=VIDEO_ENCODED_RECORDING;
|
||||
cfg->currentStreamId = PaVE->stream_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
VER_PRINT ("An error occured when creating video");
|
||||
cfg->startRec=VIDEO_ENCODED_STOPPED;
|
||||
}
|
||||
|
||||
#ifdef USE_ELINUX
|
||||
else
|
||||
{
|
||||
VER_PRINT ("An error occured when creating video");
|
||||
cfg->startRec=VIDEO_ENCODED_STOPPED;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
if((cfg->startRec == VIDEO_ENCODED_RECORDING) ||
|
||||
(cfg->startRec == VIDEO_ENCODED_WAITING_STREAM_END))
|
||||
if((cfg->startRec == VIDEO_ENCODED_RECORDING) ||
|
||||
(cfg->startRec == VIDEO_ENCODED_WAITING_STREAM_END))
|
||||
{
|
||||
|
||||
#if USE_LINUX
|
||||
/* Quick and dirty debugging inside AR.Drone Navigation */
|
||||
if (PAVE_CHECK(slice))
|
||||
{
|
||||
parrot_video_encapsulation_t * pave = (parrot_video_encapsulation_t*) slice;
|
||||
printf("Recording frame %dx%d num %d \n\033[1A",pave->display_width,pave->display_height,pave->frame_number);
|
||||
if (pave->control & PAVE_CTRL_LAST_FRAME_IN_STREAM) {
|
||||
printf("\n\nEnd of stream PaVE received !\n\n");
|
||||
}
|
||||
}
|
||||
/* Quick and dirty debugging inside AR.Drone Navigation */
|
||||
if (PAVE_CHECK(slice))
|
||||
{
|
||||
parrot_video_encapsulation_t * pave = (parrot_video_encapsulation_t*) slice;
|
||||
printf("Recording frame %dx%d num %d \n\033[1A",pave->display_width,pave->display_height,pave->frame_number);
|
||||
if (pave->control & PAVE_CTRL_LAST_FRAME_IN_STREAM) {
|
||||
printf("\n\nEnd of stream PaVE received !\n\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_ELINUX
|
||||
if (( ( in->size /*bytes*/ ) >>10 ) > cfg->quota )
|
||||
ardrone_video_error_t vError = ardrone_video_addSlice (cfg->video, slice);
|
||||
if (ARDRONE_VIDEO_FAILED (vError))
|
||||
{
|
||||
printf("Flash video recording : out of disk space.\n");
|
||||
cfg->startRec=VIDEO_ENCODED_STOPPED;
|
||||
char errBuf [50] = {0};
|
||||
ardrone_video_error_string (vError, errBuf, 50);
|
||||
VER_PRINT ("Error while recording frame : %s", errBuf);
|
||||
ardrone_video_cleanup (&(cfg->video));
|
||||
cfg->startRec = VIDEO_ENCODED_STOPPED;
|
||||
}
|
||||
else
|
||||
|
||||
if (1 == frameIsLastFrame (slice))
|
||||
{
|
||||
cfg->quota /*kbytes*/ -= ( ( in->size /*bytes*/ ) >>10 );
|
||||
navdata_set_hdvideo_usbkey_freespace(cfg->quota);
|
||||
|
||||
if (cfg->use_asynchronous_mode)
|
||||
{
|
||||
/* Create a RAM buffer to hold a temporary copy of the slice to write */
|
||||
asyn_msg.sliceSize = in->size;
|
||||
asyn_msg.slice = vp_os_malloc(asyn_msg.sliceSize);
|
||||
if (asyn_msg.slice){
|
||||
vp_os_memcpy(asyn_msg.slice,slice,asyn_msg.sliceSize);
|
||||
/* Send the copy to thread which does the actual writing */
|
||||
//printf("----> Writing %p %d bytes\n",asyn_msg.slice,asyn_msg.sliceSize);
|
||||
write(cfg->com_pipe[1],&asyn_msg,sizeof(asyn_msg));
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Flash video recording : out of RAM - dropping frame.\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
ardrone_video_error_t vError = ardrone_video_addSlice (cfg->video, slice);
|
||||
if (ARDRONE_VIDEO_FAILED (vError))
|
||||
{
|
||||
char errBuf [50] = {0};
|
||||
ardrone_video_error_string (vError, errBuf, 50);
|
||||
VER_PRINT ("Error while recording frame : %s", errBuf);
|
||||
ardrone_video_cleanup (&(cfg->video));
|
||||
cfg->startRec = VIDEO_ENCODED_STOPPED;
|
||||
}
|
||||
|
||||
if (1 == frameIsLastFrame (slice))
|
||||
{
|
||||
VER_PRINT ("Received last frame for current stream, finishing video\n");
|
||||
video_stage_encoded_recorder_finish (cfg);
|
||||
}
|
||||
|
||||
#ifdef USE_ELINUX
|
||||
}
|
||||
VER_PRINT ("Received last frame for current stream, finishing video\n");
|
||||
video_stage_encoded_recorder_finish (cfg);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
#ifndef USE_ELINUX
|
||||
vp_os_mutex_unlock (&cfg->videoMutex);
|
||||
#endif
|
||||
vp_os_mutex_unlock (&out->lock);
|
||||
return C_OK;
|
||||
vp_os_mutex_unlock (&cfg->videoMutex);
|
||||
vp_os_mutex_unlock (&out->lock);
|
||||
return C_OK;
|
||||
}
|
||||
|
||||
C_RESULT video_stage_encoded_recorder_close(video_stage_encoded_recorder_config_t *cfg)
|
||||
{
|
||||
if (NULL != cfg->video)
|
||||
if (NULL != cfg->video)
|
||||
{
|
||||
ardrone_video_finish (&(cfg->video));
|
||||
ardrone_video_finish (&(cfg->video));
|
||||
}
|
||||
return C_OK;
|
||||
return C_OK;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ typedef enum
|
||||
} video_encoded_record_state;
|
||||
#endif
|
||||
|
||||
typedef void (*video_stage_encoded_recorder_callback)(const char *mediaPath);
|
||||
typedef void (*video_stage_encoded_recorder_callback)(const char *mediaPath, bool_t addToQueue);
|
||||
|
||||
typedef struct _video_stage_encoded_recorder_config_t
|
||||
{
|
||||
|
||||
@@ -214,19 +214,18 @@ void ffmpeg_decoder_dumpPave (parrot_video_encapsulation_t *PaVE)
|
||||
|
||||
static inline bool_t check_and_copy_PaVE (parrot_video_encapsulation_t *PaVE, vp_api_io_data_t *data, parrot_video_encapsulation_t *prevPaVE, bool_t *dimChanged)
|
||||
{
|
||||
|
||||
parrot_video_encapsulation_t *localPaVE = (parrot_video_encapsulation_t *)data->buffers[data->indexBuffer];
|
||||
if (localPaVE->signature[0] == 'P' &&
|
||||
localPaVE->signature[1] == 'a' &&
|
||||
localPaVE->signature[2] == 'V' &&
|
||||
localPaVE->signature[3] == 'E')
|
||||
{
|
||||
{
|
||||
//FFMPEG_DEBUG("Found a PaVE");
|
||||
vp_os_memcpy (prevPaVE, PaVE, sizeof (parrot_video_encapsulation_t)); // Make a backup of previous PaVE so we can check if things have changed
|
||||
|
||||
vp_os_memcpy (PaVE, localPaVE, sizeof (parrot_video_encapsulation_t)); // Copy PaVE to our local one
|
||||
|
||||
|
||||
|
||||
#if __FFMPEG_DEBUG_ENABLED
|
||||
printf ("------------------------------------\n");
|
||||
printf ("PREV : ");
|
||||
@@ -291,7 +290,8 @@ C_RESULT ffmpeg_stage_decoding_transform(ffmpeg_stage_decoding_config_t *cfg, vp
|
||||
int frameFinished = 0;
|
||||
|
||||
bool_t frameDimChanged = FALSE;
|
||||
static parrot_video_encapsulation_t PaVE, prevPaVE;
|
||||
static parrot_video_encapsulation_t __attribute__ ((aligned (4))) PaVE;
|
||||
static parrot_video_encapsulation_t __attribute__ ((aligned (4))) prevPaVE;
|
||||
|
||||
#if WAIT_FOR_I_FRAME
|
||||
static bool_t waitForIFrame = TRUE;
|
||||
@@ -300,7 +300,7 @@ C_RESULT ffmpeg_stage_decoding_transform(ffmpeg_stage_decoding_config_t *cfg, vp
|
||||
#ifdef NUM_SAMPLES
|
||||
static struct timeval start_time, start_time2;
|
||||
static int numsamples = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (0 == in->size) // No frame
|
||||
{
|
||||
@@ -387,6 +387,7 @@ C_RESULT ffmpeg_stage_decoding_transform(ffmpeg_stage_decoding_config_t *cfg, vp
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
if(out->status == VP_API_STATUS_PROCESSING && (!waitForIFrame || (PaVE.frame_type == FRAME_TYPE_IDR_FRAME) || (PaVE.frame_type == FRAME_TYPE_I_FRAME))) // Processing code
|
||||
{
|
||||
waitForIFrame = FALSE;
|
||||
@@ -398,6 +399,7 @@ C_RESULT ffmpeg_stage_decoding_transform(ffmpeg_stage_decoding_config_t *cfg, vp
|
||||
packet.data = ((unsigned char*)in->buffers[in->indexBuffer]);
|
||||
packet.size = in->size;
|
||||
FFMPEG_DEBUG("Size : %d", packet.size);
|
||||
|
||||
|
||||
#ifdef NUM_SAMPLES
|
||||
struct timeval end_time;
|
||||
@@ -443,6 +445,11 @@ C_RESULT ffmpeg_stage_decoding_transform(ffmpeg_stage_decoding_config_t *cfg, vp
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Skip frames are usually 7 bytes long
|
||||
* and make FFMPEG return an error. It is however normal to get
|
||||
* skip frames from the drone.
|
||||
*/
|
||||
if (7!=PaVE.payload_size)
|
||||
printf ("Decoding failed for a %s\n", (PaVE.frame_type == FRAME_TYPE_P_FRAME) ? "P Frame" : "I Frame");
|
||||
}
|
||||
|
||||
|
||||
@@ -795,7 +795,9 @@ C_RESULT ittiam_stage_decoding_close(ittiam_stage_decoding_config_t *cfg) {
|
||||
}
|
||||
|
||||
vp_os_free(h264_mem_rec);
|
||||
h264_mem_rec = NULL;
|
||||
vp_os_free(h264_ps_it_mem);
|
||||
h264_ps_it_mem = NULL;
|
||||
|
||||
} else if (current_PaVE.video_codec == CODEC_MPEG4_VISUAL) {
|
||||
//MPEG4
|
||||
@@ -820,7 +822,9 @@ C_RESULT ittiam_stage_decoding_close(ittiam_stage_decoding_config_t *cfg) {
|
||||
}
|
||||
|
||||
vp_os_free(mpeg4_mem_rec);
|
||||
mpeg4_mem_rec = NULL;
|
||||
vp_os_free(mpeg4_ps_it_mem);
|
||||
mpeg4_ps_it_mem = NULL;
|
||||
}
|
||||
old_num_frame = cfg->num_picture_decoded;
|
||||
ITTIAM_DEBUG_PRINT("ITTIAM CLEAN");
|
||||
|
||||
@@ -404,7 +404,10 @@ C_RESULT video_stage_tcp_transform(video_stage_tcp_config_t *cfg, vp_api_io_data
|
||||
C_RESULT video_stage_tcp_close(video_stage_tcp_config_t *cfg)
|
||||
{
|
||||
vp_os_free (cfg->bufferPointer);
|
||||
cfg->bufferPointer = NULL;
|
||||
vp_os_free (cfg->globalBuffer);
|
||||
cfg->globalBuffer = NULL;
|
||||
vp_os_free (cfg->frameBuffer);
|
||||
cfg->frameBuffer = NULL;
|
||||
return C_OK;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ C_RESULT vlib_stage_decoding_open(vlib_stage_decoding_config_t *cfg)
|
||||
video_controller_set_format( &cfg->controller, ACQ_WIDTH, ACQ_HEIGHT );
|
||||
|
||||
vp_os_free( cfg->controller.in_stream.bytes );
|
||||
cfg->controller.in_stream.bytes = NULL;
|
||||
|
||||
return C_OK;
|
||||
}
|
||||
|
||||
@@ -275,7 +275,7 @@ C_RESULT ardrone_tool_shutdown()
|
||||
ardrone_navdata_client_shutdown();
|
||||
ardrone_control_shutdown();
|
||||
ardrone_tool_input_shutdown();
|
||||
|
||||
|
||||
JOIN_THREAD(ardrone_control);
|
||||
JOIN_THREAD(navdata_update);
|
||||
|
||||
@@ -332,14 +332,11 @@ int ardrone_tool_main(int argc, char **argv)
|
||||
argc--; argv++;
|
||||
}
|
||||
|
||||
// Making the driver ROS compatible
|
||||
/*
|
||||
if( show_usage || (argc != 0) )
|
||||
/*if( show_usage || (argc != 0) )
|
||||
{
|
||||
ardrone_tool_usage( appname );
|
||||
exit(-1);
|
||||
}
|
||||
*/
|
||||
}*/
|
||||
|
||||
/* After a first analysis, the arguments are restored so they can be passed to the user-defined functions */
|
||||
argc=argc_backup;
|
||||
@@ -351,7 +348,6 @@ int ardrone_tool_main(int argc, char **argv)
|
||||
{
|
||||
PRINT("You have to install new locales in your dev environment! (avoid the need of conv_coma_to_dot)\n");
|
||||
PRINT("As root, do a \"dpkg-reconfigure locales\" and add en_GB.UTF8 to your locale settings\n");
|
||||
PRINT("If you have any problem, feel free to contact Pierre Eline (pierre.eline@parrot.com)\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -407,10 +403,12 @@ int ardrone_tool_main(int argc, char **argv)
|
||||
appname = &argv[0][lastSlashPos+1];
|
||||
ardrone_gen_appid (appname, __SDK_VERSION__, app_id, app_name, sizeof (app_name));
|
||||
res = ardrone_tool_init(wifi_ardrone_ip, strlen(wifi_ardrone_ip), NULL, appname, NULL, NULL, NULL, MAX_FLIGHT_STORING_SIZE, NULL);
|
||||
|
||||
while( SUCCEED(res) && ardrone_tool_exit() == FALSE )
|
||||
{
|
||||
res = ardrone_tool_update();
|
||||
}
|
||||
|
||||
res = ardrone_tool_shutdown();
|
||||
}
|
||||
|
||||
|
||||
@@ -226,9 +226,15 @@ static void ardrone_tool_configuration_event_configure_end(struct _ardrone_contr
|
||||
}
|
||||
|
||||
if (NULL!=ardrone_tool_configuration_data[ardrone_tool_configuration_current_index].value)
|
||||
{
|
||||
vp_os_free(ardrone_tool_configuration_data[ardrone_tool_configuration_current_index].value);
|
||||
ardrone_tool_configuration_data[ardrone_tool_configuration_current_index].value = NULL;
|
||||
}
|
||||
if (NULL!=ardrone_tool_configuration_data[ardrone_tool_configuration_current_index].event)
|
||||
{
|
||||
vp_os_free(ardrone_tool_configuration_data[ardrone_tool_configuration_current_index].event);
|
||||
ardrone_tool_configuration_data[ardrone_tool_configuration_current_index].event = NULL;
|
||||
}
|
||||
ardrone_tool_configuration_data[ardrone_tool_configuration_current_index].event = NULL;
|
||||
ardrone_tool_configuration_data[ardrone_tool_configuration_current_index].value = NULL;
|
||||
ardrone_tool_configuration_current_index = (ardrone_tool_configuration_current_index + 1) % ARDRONE_TOOL_CONFIGURATION_MAX_EVENT;
|
||||
@@ -269,7 +275,9 @@ static void ardrone_tool_configuration_event_configure(void)
|
||||
ardrone_control_ack_event_t *event = NULL;
|
||||
|
||||
if (ardrone_tool_configuration_data[ardrone_tool_configuration_current_index].callback)
|
||||
{
|
||||
ardrone_tool_configuration_data[ardrone_tool_configuration_current_index].callback(ardrone_tool_configuration_data[ardrone_tool_configuration_current_index].value, ses_id, usr_id, app_id);
|
||||
}
|
||||
|
||||
if(ardrone_tool_configuration_data[ardrone_tool_configuration_current_index].event == NULL)
|
||||
ardrone_tool_configuration_data[ardrone_tool_configuration_current_index].event = vp_os_malloc(sizeof(ardrone_control_ack_event_t));
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#ifndef USE_ELINUX
|
||||
|
||||
int
|
||||
compareVersions (ardrone_version_t *v1, ardrone_version_t *v2)
|
||||
{
|
||||
@@ -53,6 +55,7 @@ getDroneVersion (const char *tempPath, const char *droneIp, ardrone_version_t *v
|
||||
if (FTP_FAILED (status))
|
||||
{
|
||||
vp_os_free (localName);
|
||||
localName = NULL;
|
||||
ftpClose (&ftp);
|
||||
return -1;
|
||||
}
|
||||
@@ -64,6 +67,7 @@ getDroneVersion (const char *tempPath, const char *droneIp, ardrone_version_t *v
|
||||
{
|
||||
remove (localName);
|
||||
vp_os_free (localName);
|
||||
localName = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -73,12 +77,14 @@ getDroneVersion (const char *tempPath, const char *droneIp, ardrone_version_t *v
|
||||
fclose (versionFile);
|
||||
remove (localName);
|
||||
vp_os_free (localName);
|
||||
localName = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
fclose (versionFile);
|
||||
remove (localName);
|
||||
vp_os_free (localName);
|
||||
localName = NULL;
|
||||
|
||||
version->majorVersion = maj;
|
||||
version->minorVersion = min;
|
||||
@@ -86,3 +92,5 @@ getDroneVersion (const char *tempPath, const char *droneIp, ardrone_version_t *v
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -59,6 +59,8 @@ int getDroneVersion (const char *tempPath, const char *droneIp, ardrone_version_
|
||||
# define ARDRONE_VERSION() 1
|
||||
# endif
|
||||
|
||||
#define getDroneVersion(...) ARDRONE_VERSION()
|
||||
|
||||
#endif
|
||||
|
||||
#define IS_ARDRONE1 (1 == ARDRONE_VERSION()) // Drone 1
|
||||
|
||||
+1161
-1095
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -61,6 +61,7 @@ typedef struct _ftp_s
|
||||
int abortCurrentOp;
|
||||
_ftp_status lastStatus;
|
||||
char *lastFileList;
|
||||
void * tag; // Allows to put any pointer to some useful data that is associated with this ftp connectionS
|
||||
} _ftp_t;
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
#include <utils/ardrone_time.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <sys/timeb.h>
|
||||
|
||||
static int _gettimeofday (struct timeval *tp, void *tz)
|
||||
{
|
||||
struct _timeb timebuffer;
|
||||
_ftime (&timebuffer);
|
||||
tp->tv_sec = (long)timebuffer.time;
|
||||
tp->tv_usec = (long)timebuffer.millitm * 1000;
|
||||
return 0;
|
||||
}
|
||||
#include <sys/timeb.h>
|
||||
|
||||
static int _gettimeofday (struct timeval *tp, void *tz)
|
||||
{
|
||||
struct _timeb timebuffer;
|
||||
_ftime (&timebuffer);
|
||||
tp->tv_sec = (long)timebuffer.time;
|
||||
tp->tv_usec = (long)timebuffer.millitm * 1000;
|
||||
return 0;
|
||||
}
|
||||
#elif defined(TARGET_OS_IPHONE) || defined(TARGET_OS_SIMULATOR)
|
||||
#include <mach/mach_time.h>
|
||||
static int _gettimeofday (struct timeval *tp, void *tz)
|
||||
@@ -20,13 +20,13 @@ static int _gettimeofday (struct timeval *tp, void *tz)
|
||||
mach_timebase_info_data_t sTimebaseInfo;
|
||||
uint64_t mtime = mach_absolute_time();
|
||||
uint64_t useconds;
|
||||
|
||||
|
||||
mach_timebase_info(&sTimebaseInfo);
|
||||
useconds = (mtime * (sTimebaseInfo.numer / sTimebaseInfo.denom) / 1000);
|
||||
|
||||
tp->tv_sec = (long)(useconds / 1000000);
|
||||
tp->tv_usec = (long)(useconds % 1000000);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
@@ -36,21 +36,21 @@ static int _gettimeofday (struct timeval *tp, void *tz)
|
||||
|
||||
C_RESULT ardrone_timer_reset(ardrone_timer_t* timer)
|
||||
{
|
||||
vp_os_memset(timer, 0, sizeof(ardrone_timer_t));
|
||||
vp_os_memset(timer, 0, sizeof(ardrone_timer_t));
|
||||
|
||||
return C_OK;
|
||||
return C_OK;
|
||||
}
|
||||
|
||||
C_RESULT ardrone_timer_update(ardrone_timer_t* timer)
|
||||
{
|
||||
C_RESULT retVal = C_OK;
|
||||
if( timer->init == FALSE )
|
||||
{
|
||||
_gettimeofday(&timer->tv_init, NULL);
|
||||
timer->init = TRUE;
|
||||
}
|
||||
if( timer->init == FALSE )
|
||||
{
|
||||
_gettimeofday(&timer->tv_init, NULL);
|
||||
timer->init = TRUE;
|
||||
}
|
||||
|
||||
_gettimeofday(&timer->tv, NULL);
|
||||
_gettimeofday(&timer->tv, NULL);
|
||||
if (timer->tv.tv_usec >= timer->tv_init.tv_usec)
|
||||
{
|
||||
timer->tv.tv_usec -= timer->tv_init.tv_usec;
|
||||
@@ -69,19 +69,19 @@ C_RESULT ardrone_timer_update(ardrone_timer_t* timer)
|
||||
}
|
||||
timer->tv.tv_sec -= timer->tv_init.tv_sec;
|
||||
|
||||
return C_OK;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
uint64_t ardrone_timer_elapsed_ms(ardrone_timer_t* timer)
|
||||
{
|
||||
uint64_t time;
|
||||
|
||||
time = -1;
|
||||
time = -1;
|
||||
|
||||
if( timer->init )
|
||||
{
|
||||
if( timer->init )
|
||||
{
|
||||
time = (1000ll * (uint64_t)timer->tv.tv_sec) + ((uint64_t)timer->tv.tv_usec / 1000ll);
|
||||
}
|
||||
}
|
||||
|
||||
return time;
|
||||
}
|
||||
@@ -90,22 +90,22 @@ uint64_t ardrone_timer_elapsed_us(ardrone_timer_t* timer)
|
||||
{
|
||||
uint64_t time;
|
||||
|
||||
time = -1;
|
||||
time = -1;
|
||||
|
||||
if( timer->init )
|
||||
{
|
||||
if( timer->init )
|
||||
{
|
||||
time = (1000000ll * (uint64_t)timer->tv.tv_sec) + ((uint64_t)timer->tv.tv_usec);
|
||||
}
|
||||
}
|
||||
|
||||
return time;
|
||||
return time;
|
||||
}
|
||||
|
||||
uint64_t ardrone_timer_delta_ms(ardrone_timer_t* timer)
|
||||
{
|
||||
ardrone_timer_t timer_current;
|
||||
ardrone_timer_t timer_current;
|
||||
|
||||
timer_current.init = TRUE;
|
||||
timer_current.tv_init = timer->tv_init;
|
||||
timer_current.init = TRUE;
|
||||
timer_current.tv_init = timer->tv_init;
|
||||
|
||||
uint64_t retVal = 0;
|
||||
if (C_OK == ardrone_timer_update(&timer_current))
|
||||
@@ -118,16 +118,16 @@ uint64_t ardrone_timer_delta_ms(ardrone_timer_t* timer)
|
||||
|
||||
uint64_t ardrone_timer_delta_us(ardrone_timer_t* timer)
|
||||
{
|
||||
ardrone_timer_t timer_current;
|
||||
|
||||
timer_current.init = TRUE;
|
||||
timer_current.tv_init = timer->tv_init;
|
||||
|
||||
ardrone_timer_t timer_current;
|
||||
|
||||
timer_current.init = TRUE;
|
||||
timer_current.tv_init = timer->tv_init;
|
||||
|
||||
uint64_t retVal = 0;
|
||||
if (C_OK == ardrone_timer_update(&timer_current))
|
||||
{
|
||||
retVal = ardrone_timer_elapsed_us(&timer_current) - ardrone_timer_elapsed_us(timer);
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
|
||||
#include <VP_Os/vp_os_types.h>
|
||||
|
||||
#define ARDRONE_TIME_SEC_TO_MSEC(x) ((x)*1000.f)
|
||||
#define ARDRONE_TIME_MSEC_TO_SEC(x) ((x)/1000.f)
|
||||
|
||||
typedef struct _ardrone_timer_t
|
||||
{
|
||||
bool_t init;
|
||||
|
||||
@@ -84,49 +84,51 @@
|
||||
|
||||
movie_atom_t *atomFromData (uint32_t data_size, const char *_tag, const uint8_t *_data)
|
||||
{
|
||||
movie_atom_t *retAtom = ATOM_MALLOC (sizeof (movie_atom_t));
|
||||
if (NULL == retAtom)
|
||||
movie_atom_t *retAtom = ATOM_MALLOC (sizeof (movie_atom_t));
|
||||
if (NULL == retAtom)
|
||||
{
|
||||
return retAtom;
|
||||
return retAtom;
|
||||
}
|
||||
retAtom->size = data_size + 8;
|
||||
strncpy (retAtom->tag, _tag, 4);
|
||||
retAtom->size = data_size + 8;
|
||||
strncpy (retAtom->tag, _tag, 4);
|
||||
|
||||
retAtom->data = NULL;
|
||||
if (NULL != _data && data_size > 0)
|
||||
retAtom->data = NULL;
|
||||
if (NULL != _data && data_size > 0)
|
||||
{
|
||||
retAtom->data = ATOM_MALLOC (data_size);
|
||||
if (NULL == retAtom->data)
|
||||
retAtom->data = ATOM_MALLOC (data_size);
|
||||
if (NULL == retAtom->data)
|
||||
{
|
||||
ATOM_FREE (retAtom);
|
||||
return NULL;
|
||||
ATOM_FREE (retAtom);
|
||||
retAtom = NULL;
|
||||
return NULL;
|
||||
}
|
||||
ATOM_MEMCOPY (retAtom->data, _data, data_size);
|
||||
ATOM_MEMCOPY (retAtom->data, _data, data_size);
|
||||
}
|
||||
retAtom->wide = 0;
|
||||
return retAtom;
|
||||
retAtom->wide = 0;
|
||||
return retAtom;
|
||||
}
|
||||
|
||||
void insertAtomIntoAtom (movie_atom_t *container, movie_atom_t **leaf)
|
||||
{
|
||||
uint32_t new_container_size = container->size - 8 + (*leaf)->size;
|
||||
container->data = ATOM_REALLOC (container->data, new_container_size);
|
||||
if (NULL == container->data)
|
||||
uint32_t new_container_size = container->size - 8 + (*leaf)->size;
|
||||
container->data = ATOM_REALLOC (container->data, new_container_size);
|
||||
if (NULL == container->data)
|
||||
{
|
||||
fprintf (stderr, "Alloc error for atom insertion\n");
|
||||
return;
|
||||
fprintf (stderr, "Alloc error for atom insertion\n");
|
||||
return;
|
||||
}
|
||||
uint32_t leafSizeNetworkEndian = htonl ((*leaf)->size);
|
||||
ATOM_MEMCOPY (&container->data[container->size - 8], &leafSizeNetworkEndian, sizeof (uint32_t));
|
||||
ATOM_MEMCOPY (&container->data[container->size - 4], (*leaf)->tag, 4);
|
||||
if (NULL != (*leaf)->data)
|
||||
uint32_t leafSizeNetworkEndian = htonl ((*leaf)->size);
|
||||
ATOM_MEMCOPY (&container->data[container->size - 8], &leafSizeNetworkEndian, sizeof (uint32_t));
|
||||
ATOM_MEMCOPY (&container->data[container->size - 4], (*leaf)->tag, 4);
|
||||
if (NULL != (*leaf)->data)
|
||||
{
|
||||
ATOM_MEMCOPY (&container->data[container->size], (*leaf)->data, ((*leaf)->size - 8));
|
||||
container->size = new_container_size + 8;
|
||||
ATOM_MEMCOPY (&container->data[container->size], (*leaf)->data, ((*leaf)->size - 8));
|
||||
container->size = new_container_size + 8;
|
||||
}
|
||||
ATOM_FREE ((*leaf)->data);
|
||||
ATOM_FREE (*leaf);
|
||||
*leaf = NULL;
|
||||
ATOM_FREE ((*leaf)->data);
|
||||
(*leaf)->data = NULL;
|
||||
ATOM_FREE (*leaf);
|
||||
*leaf = NULL;
|
||||
}
|
||||
|
||||
int writeAtomToFile (movie_atom_t **_atom, FILE *file)
|
||||
@@ -135,108 +137,123 @@ int writeAtomToFile (movie_atom_t **_atom, FILE *file)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
uint32_t networkEndianSize = htonl ((*_atom)->size);
|
||||
if (4 != fwrite (&networkEndianSize, 1, 4, file))
|
||||
uint32_t networkEndianSize = htonl ((*_atom)->size);
|
||||
if (4 != fwrite (&networkEndianSize, 1, 4, file))
|
||||
{
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
if (4 != fwrite ((*_atom)->tag, 1, 4, file))
|
||||
if (4 != fwrite ((*_atom)->tag, 1, 4, file))
|
||||
{
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
if (NULL != (*_atom)->data)
|
||||
if (NULL != (*_atom)->data)
|
||||
{
|
||||
uint32_t atom_data_size = 0;
|
||||
if (1 == (*_atom)->wide)
|
||||
uint32_t atom_data_size = 0;
|
||||
if (1 == (*_atom)->wide)
|
||||
{
|
||||
atom_data_size = 8;
|
||||
atom_data_size = 8;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
atom_data_size = (*_atom)->size - 8;
|
||||
atom_data_size = (*_atom)->size - 8;
|
||||
}
|
||||
if (atom_data_size != fwrite ((*_atom)->data, 1, atom_data_size, file))
|
||||
if (atom_data_size != fwrite ((*_atom)->data, 1, atom_data_size, file))
|
||||
{
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
ATOM_FREE ((*_atom)->data);
|
||||
ATOM_FREE (*_atom);
|
||||
*_atom = NULL;
|
||||
ATOM_FREE ((*_atom)->data);
|
||||
(*_atom)->data = NULL;
|
||||
ATOM_FREE (*_atom);
|
||||
*_atom = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
void freeAtom (movie_atom_t **_atom)
|
||||
{
|
||||
if ((NULL != _atom) &&
|
||||
(NULL != *_atom))
|
||||
{
|
||||
if (NULL != (*_atom)->data)
|
||||
{
|
||||
ATOM_FREE ((*_atom)->data);
|
||||
}
|
||||
ATOM_FREE (*_atom);
|
||||
*_atom = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
movie_atom_t *ftypAtomForFormatAndCodecWithOffset (ardrone_video_type_t format, parrot_video_encapsulation_codecs_t codec, uint32_t *offset, movie_atom_t **wideAtom)
|
||||
{
|
||||
if (NULL == offset || NULL == wideAtom)
|
||||
if (NULL == offset || NULL == wideAtom)
|
||||
{
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
movie_atom_t *retAtom = NULL;
|
||||
if (ARDRONE_VIDEO_MP4 == format)
|
||||
{
|
||||
movie_atom_t *retAtom = NULL;
|
||||
if (ARDRONE_VIDEO_MP4 == format)
|
||||
{
|
||||
uint8_t data [24] = {'i', 's', 'o', 'm',
|
||||
0x00, 0x00, 0x02, 0x00,
|
||||
0x00, 0x00, 0x02, 0x00,
|
||||
'i', 's', 'o', 'm',
|
||||
'i', 's', 'o', '2',
|
||||
'a', 'v', 'c', '1',
|
||||
'm', 'p', '4', '1'};
|
||||
retAtom = atomFromData (24, "ftyp", data);
|
||||
*offset = 48;
|
||||
}
|
||||
else if (ARDRONE_VIDEO_MOV == format)
|
||||
'm', 'p', '4', '1'};
|
||||
retAtom = atomFromData (24, "ftyp", data);
|
||||
*offset = 48;
|
||||
}
|
||||
else if (ARDRONE_VIDEO_MOV == format)
|
||||
{
|
||||
uint8_t data [12] = {'q', 't', ' ', ' ',
|
||||
0x00, 0x00, 0x02, 0x00,
|
||||
'q', 't', ' ', ' '};
|
||||
retAtom = atomFromData (12, "ftyp", data);
|
||||
uint8_t wideData [4] = {0};
|
||||
*wideAtom = atomFromData (4, "wide", wideData);
|
||||
*offset = 48;
|
||||
0x00, 0x00, 0x02, 0x00,
|
||||
'q', 't', ' ', ' '};
|
||||
retAtom = atomFromData (12, "ftyp", data);
|
||||
uint8_t wideData [4] = {0};
|
||||
*wideAtom = atomFromData (4, "wide", wideData);
|
||||
*offset = 48;
|
||||
}
|
||||
return retAtom;
|
||||
return retAtom;
|
||||
}
|
||||
|
||||
movie_atom_t *mdatAtomForFormatWithVideoSize (ardrone_video_type_t format, uint64_t videoSize)
|
||||
{
|
||||
movie_atom_t *retAtom = NULL;
|
||||
if (videoSize <= INT32_MAX)
|
||||
movie_atom_t *retAtom = NULL;
|
||||
if (videoSize <= INT32_MAX)
|
||||
{
|
||||
// Free/wide atom + mdat
|
||||
uint8_t data [8] = {0x00, 0x00, 0x00, 0x00,
|
||||
'm', 'd', 'a', 't'};
|
||||
uint32_t sizeNe = htonl ((uint32_t) videoSize);
|
||||
ATOM_MEMCOPY (data, &sizeNe, sizeof (uint32_t));
|
||||
if (ARDRONE_VIDEO_MP4 == format)
|
||||
// Free/wide atom + mdat
|
||||
uint8_t data [8] = {0x00, 0x00, 0x00, 0x00,
|
||||
'm', 'd', 'a', 't'};
|
||||
uint32_t sizeNe = htonl ((uint32_t) videoSize);
|
||||
ATOM_MEMCOPY (data, &sizeNe, sizeof (uint32_t));
|
||||
if (ARDRONE_VIDEO_MP4 == format)
|
||||
{
|
||||
retAtom = atomFromData (8, "free", data);
|
||||
retAtom->size = 8;
|
||||
retAtom->wide = 1;
|
||||
retAtom = atomFromData (8, "free", data);
|
||||
retAtom->size = 8;
|
||||
retAtom->wide = 1;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
retAtom = atomFromData (8, "wide", data);
|
||||
retAtom->size = 8;
|
||||
retAtom->wide = 1;
|
||||
retAtom = atomFromData (8, "wide", data);
|
||||
retAtom->size = 8;
|
||||
retAtom->wide = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
// 64bit wide mdat atom
|
||||
uint8_t data [8] = {0};
|
||||
uint32_t highSize = (videoSize >> 32);
|
||||
// 64bit wide mdat atom
|
||||
uint8_t data [8] = {0};
|
||||
uint32_t highSize = (videoSize >> 32);
|
||||
uint32_t lowSize = (videoSize & 0xffffffff);
|
||||
uint32_t highSizeNe = htonl (highSize);
|
||||
uint32_t lowSizeNe = htonl (lowSize);
|
||||
ATOM_MEMCOPY (data, &highSizeNe, sizeof (uint32_t));
|
||||
ATOM_MEMCOPY (&data[4], &lowSizeNe, sizeof (uint32_t));
|
||||
retAtom = atomFromData (8, "mdat", data);
|
||||
retAtom->size = 0;
|
||||
retAtom->wide = 1;
|
||||
uint32_t highSizeNe = htonl (highSize);
|
||||
uint32_t lowSizeNe = htonl (lowSize);
|
||||
ATOM_MEMCOPY (data, &highSizeNe, sizeof (uint32_t));
|
||||
ATOM_MEMCOPY (&data[4], &lowSizeNe, sizeof (uint32_t));
|
||||
retAtom = atomFromData (8, "mdat", data);
|
||||
retAtom->size = 0;
|
||||
retAtom->wide = 1;
|
||||
}
|
||||
return retAtom;
|
||||
return retAtom;
|
||||
}
|
||||
|
||||
movie_atom_t *mvhdAtomFromFpsNumFramesAndDate (uint32_t fps, uint32_t nbFrames, time_t date)
|
||||
@@ -280,6 +297,7 @@ movie_atom_t *mvhdAtomFromFpsNumFramesAndDate (uint32_t fps, uint32_t nbFrames,
|
||||
|
||||
movie_atom_t *retAtom = atomFromData (100, "mvhd", data);
|
||||
ATOM_FREE (data);
|
||||
data = NULL;
|
||||
return retAtom;
|
||||
}
|
||||
|
||||
@@ -321,6 +339,7 @@ movie_atom_t *tkhdAtomWithResolutionNumFramesFpsAndDate (uint32_t w, uint32_t h,
|
||||
|
||||
movie_atom_t *retAtom = atomFromData (84, "tkhd", data);
|
||||
ATOM_FREE (data);
|
||||
data = NULL;
|
||||
return retAtom;
|
||||
}
|
||||
|
||||
@@ -343,278 +362,281 @@ movie_atom_t *mdhdAtomFromFpsNumFramesAndDate (uint32_t fps, uint32_t nbFrames,
|
||||
|
||||
movie_atom_t *retAtom = atomFromData (24, "mdhd", data);
|
||||
ATOM_FREE (data);
|
||||
data = NULL;
|
||||
return retAtom;
|
||||
}
|
||||
|
||||
|
||||
movie_atom_t *hdlrAtomForMdia ()
|
||||
{
|
||||
uint8_t data [37] = {0x00, 0x00, 0x00, 0x00,
|
||||
'm', 'h', 'l', 'r',
|
||||
'v', 'i', 'd', 'e',
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x0c, 'V', 'i', 'd',
|
||||
'e', 'o', 'H', 'a',
|
||||
'n', 'd', 'l', 'e',
|
||||
'r'};
|
||||
return atomFromData (37, "hdlr", data);
|
||||
uint8_t data [37] = {0x00, 0x00, 0x00, 0x00,
|
||||
'm', 'h', 'l', 'r',
|
||||
'v', 'i', 'd', 'e',
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x0c, 'V', 'i', 'd',
|
||||
'e', 'o', 'H', 'a',
|
||||
'n', 'd', 'l', 'e',
|
||||
'r'};
|
||||
return atomFromData (37, "hdlr", data);
|
||||
}
|
||||
|
||||
movie_atom_t *vmhdAtomGen ()
|
||||
{
|
||||
uint8_t data [12] = {0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00};
|
||||
return atomFromData (12, "vmhd", data);
|
||||
uint8_t data [12] = {0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00};
|
||||
return atomFromData (12, "vmhd", data);
|
||||
}
|
||||
|
||||
movie_atom_t *hdlrAtomForMinf ()
|
||||
{
|
||||
uint8_t data [36] = {0x00, 0x00, 0x00, 0x00,
|
||||
'd', 'h', 'l', 'r',
|
||||
'u', 'r', 'l', ' ',
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x0b, 'D', 'a', 't',
|
||||
'a', 'H', 'a', 'n',
|
||||
'd', 'l', 'e', 'r'};
|
||||
return atomFromData (36, "hdlr", data);
|
||||
uint8_t data [36] = {0x00, 0x00, 0x00, 0x00,
|
||||
'd', 'h', 'l', 'r',
|
||||
'u', 'r', 'l', ' ',
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x0b, 'D', 'a', 't',
|
||||
'a', 'H', 'a', 'n',
|
||||
'd', 'l', 'e', 'r'};
|
||||
return atomFromData (36, "hdlr", data);
|
||||
}
|
||||
|
||||
movie_atom_t *drefAtomGen ()
|
||||
{
|
||||
uint8_t data [20] = {0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x0C,
|
||||
0x75, 0x72, 0x6c, 0x20,
|
||||
0x00, 0x00, 0x00, 0x01};
|
||||
return atomFromData (20, "dref", data);
|
||||
uint8_t data [20] = {0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x0C,
|
||||
0x75, 0x72, 0x6c, 0x20,
|
||||
0x00, 0x00, 0x00, 0x01};
|
||||
return atomFromData (20, "dref", data);
|
||||
}
|
||||
|
||||
movie_atom_t *stsdAtomWithResolutionAndCodec (uint32_t w, uint32_t h, parrot_video_encapsulation_codecs_t codec)
|
||||
{
|
||||
if (CODEC_MPEG4_AVC == codec)
|
||||
if (CODEC_MPEG4_AVC == codec)
|
||||
{
|
||||
uint8_t data [128] = {0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x78,
|
||||
'a', 'v', 'c', '1', // vse type
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
'A', 'R', '.', 'D', // Muxer string
|
||||
0x00, 0x00, 0x02, 0x00,
|
||||
0x00, 0x00, 0x02, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,// 40 -> width | 42 -> height
|
||||
0x00, 0x48, 0x00, 0x00,
|
||||
0x00, 0x48, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x18,
|
||||
0xff, 0xff, 0x00, 0x00,
|
||||
0x00, 0x22, 0x61, 0x76,
|
||||
0x63, 0x43, 0x01, 0x42,
|
||||
0x80, 0x1e, 0xff, 0xe1,
|
||||
0x00, 0x09, 0x67, 0x42,
|
||||
0x80, 0x1e, 0x8b, 0x68,
|
||||
0x0a, 0x02, 0xf1, 0x01,
|
||||
0x00, 0x06, 0x68, 0xce,
|
||||
0x01, 0xa8, 0x77, 0x20};
|
||||
uint16_t neW = htons ((uint16_t) w);
|
||||
uint16_t neH = htons ((uint16_t) h);
|
||||
ATOM_MEMCOPY(&data[40], &neW, sizeof (uint16_t));
|
||||
ATOM_MEMCOPY(&data[42], &neH, sizeof (uint16_t));
|
||||
return atomFromData (128, "stsd", data);
|
||||
uint8_t data [128] = {0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x78,
|
||||
'a', 'v', 'c', '1', // vse type
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
'A', 'R', '.', 'D', // Muxer string
|
||||
0x00, 0x00, 0x02, 0x00,
|
||||
0x00, 0x00, 0x02, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,// 40 -> width | 42 -> height
|
||||
0x00, 0x48, 0x00, 0x00,
|
||||
0x00, 0x48, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x18,
|
||||
0xff, 0xff, 0x00, 0x00,
|
||||
0x00, 0x22, 0x61, 0x76,
|
||||
0x63, 0x43, 0x01, 0x42,
|
||||
0x80, 0x1e, 0xff, 0xe1,
|
||||
0x00, 0x09, 0x67, 0x42,
|
||||
0x80, 0x1e, 0x8b, 0x68,
|
||||
0x0a, 0x02, 0xf1, 0x01,
|
||||
0x00, 0x06, 0x68, 0xce,
|
||||
0x01, 0xa8, 0x77, 0x20};
|
||||
uint16_t neW = htons ((uint16_t) w);
|
||||
uint16_t neH = htons ((uint16_t) h);
|
||||
ATOM_MEMCOPY(&data[40], &neW, sizeof (uint16_t));
|
||||
ATOM_MEMCOPY(&data[42], &neH, sizeof (uint16_t));
|
||||
return atomFromData (128, "stsd", data);
|
||||
}
|
||||
else if (CODEC_MPEG4_VISUAL == codec)
|
||||
else if (CODEC_MPEG4_VISUAL == codec)
|
||||
{
|
||||
uint8_t data [187] = {0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0xb3,
|
||||
'm', 'p', '4', 'v', // vse type
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
'A', 'R', '.', 'D', // Muxer string
|
||||
0x00, 0x00, 0x02, 0x00,
|
||||
0x00, 0x00, 0x02, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,// 40 -> width | 42 -> height
|
||||
0x00, 0x48, 0x00, 0x00,
|
||||
0x00, 0x48, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01, 0x05, 'm',
|
||||
'p', 'e', 'g', '4',
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x18,
|
||||
0xff, 0xff, 0x00, 0x00,
|
||||
0x00, 0x5d, 0x65, 0x73,
|
||||
0x64, 0x73, 0x00, 0x00,
|
||||
0x00, 0x00, 0x03, 0x80,
|
||||
0x80, 0x80, 0x4c, 0x00,
|
||||
0x01, 0x00, 0x04, 0x80,
|
||||
0x80, 0x80, 0x3e, 0x20,
|
||||
0x11, 0x00, 0x00, 0x00,
|
||||
0x00, 0x07, 0xac, 0xda,
|
||||
0x00, 0x07, 0xac, 0xda,
|
||||
0x05, 0x80, 0x80, 0x80,
|
||||
0x2c, 0x00, 0x00, 0x01,
|
||||
0xb0, 0x01, 0x00, 0x00,
|
||||
0x01, 0xb5, 0x89, 0x13,
|
||||
0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x01, 0x20,
|
||||
0x00, 0xc4, 0x8d, 0x88,
|
||||
0x00, 0xf5, 0x14, 0x04,
|
||||
0x2e, 0x14, 0x63, 0x00,
|
||||
0x00, 0x01, 0xb2, 'A',
|
||||
'R', '.', 'D', 'r',
|
||||
'o', 'n', 'e', '_',
|
||||
'2', 0x06, 0x80, 0x80,
|
||||
0x80, 0x01, 0x02};
|
||||
uint16_t neW = htons ((uint16_t) w);
|
||||
uint16_t neH = htons ((uint16_t) h);
|
||||
ATOM_MEMCOPY(&data[40], &neW, sizeof (uint16_t));
|
||||
ATOM_MEMCOPY(&data[42], &neH, sizeof (uint16_t));
|
||||
return atomFromData (187, "stsd", data);
|
||||
uint8_t data [187] = {0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0xb3,
|
||||
'm', 'p', '4', 'v', // vse type
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
'A', 'R', '.', 'D', // Muxer string
|
||||
0x00, 0x00, 0x02, 0x00,
|
||||
0x00, 0x00, 0x02, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,// 40 -> width | 42 -> height
|
||||
0x00, 0x48, 0x00, 0x00,
|
||||
0x00, 0x48, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01, 0x05, 'm',
|
||||
'p', 'e', 'g', '4',
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x18,
|
||||
0xff, 0xff, 0x00, 0x00,
|
||||
0x00, 0x5d, 0x65, 0x73,
|
||||
0x64, 0x73, 0x00, 0x00,
|
||||
0x00, 0x00, 0x03, 0x80,
|
||||
0x80, 0x80, 0x4c, 0x00,
|
||||
0x01, 0x00, 0x04, 0x80,
|
||||
0x80, 0x80, 0x3e, 0x20,
|
||||
0x11, 0x00, 0x00, 0x00,
|
||||
0x00, 0x07, 0xac, 0xda,
|
||||
0x00, 0x07, 0xac, 0xda,
|
||||
0x05, 0x80, 0x80, 0x80,
|
||||
0x2c, 0x00, 0x00, 0x01,
|
||||
0xb0, 0x01, 0x00, 0x00,
|
||||
0x01, 0xb5, 0x89, 0x13,
|
||||
0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x01, 0x20,
|
||||
0x00, 0xc4, 0x8d, 0x88,
|
||||
0x00, 0xf5, 0x14, 0x04,
|
||||
0x2e, 0x14, 0x63, 0x00,
|
||||
0x00, 0x01, 0xb2, 'A',
|
||||
'R', '.', 'D', 'r',
|
||||
'o', 'n', 'e', '_',
|
||||
'2', 0x06, 0x80, 0x80,
|
||||
0x80, 0x01, 0x02};
|
||||
uint16_t neW = htons ((uint16_t) w);
|
||||
uint16_t neH = htons ((uint16_t) h);
|
||||
ATOM_MEMCOPY(&data[40], &neW, sizeof (uint16_t));
|
||||
ATOM_MEMCOPY(&data[42], &neH, sizeof (uint16_t));
|
||||
return atomFromData (187, "stsd", data);
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
return atomFromData (0, "stsd", NULL);
|
||||
return atomFromData (0, "stsd", NULL);
|
||||
}
|
||||
}
|
||||
|
||||
movie_atom_t *stsdAtomWithResolutionCodecSpsAndPps (uint32_t w, uint32_t h, parrot_video_encapsulation_codecs_t codec, uint8_t *sps, uint32_t spsSize, uint8_t *pps, uint32_t ppsSize)
|
||||
{
|
||||
if (NULL == sps || NULL == pps || CODEC_MPEG4_AVC != codec)
|
||||
if (NULL == sps || NULL == pps || CODEC_MPEG4_AVC != codec)
|
||||
{
|
||||
return stsdAtomWithResolutionAndCodec (w, h, codec);
|
||||
return stsdAtomWithResolutionAndCodec (w, h, codec);
|
||||
}
|
||||
uint32_t avcCSize = 19 + spsSize + ppsSize;
|
||||
uint32_t vse_size = avcCSize + 86;
|
||||
uint32_t dataSize = vse_size + 8;
|
||||
uint8_t *data = ATOM_MALLOC (dataSize);
|
||||
if (NULL == data)
|
||||
uint32_t avcCSize = 19 + spsSize + ppsSize;
|
||||
uint32_t vse_size = avcCSize + 86;
|
||||
uint32_t dataSize = vse_size + 8;
|
||||
uint8_t *data = ATOM_MALLOC (dataSize);
|
||||
if (NULL == data)
|
||||
{
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
uint32_t currentIndex = 0;
|
||||
ATOM_WRITE_U32 (0); /* version / flags */
|
||||
ATOM_WRITE_U32 (1); /* entry count */
|
||||
ATOM_WRITE_U32 (vse_size); /* video sample entry size */
|
||||
ATOM_WRITE_4CC ('a', 'v', 'c', '1'); /* VSE type */
|
||||
ATOM_WRITE_U32 (0); /* Reserved */
|
||||
ATOM_WRITE_U16 (0); /* Reserved */
|
||||
ATOM_WRITE_U16 (1); /* Data reference index */
|
||||
ATOM_WRITE_U16 (0); /* Codec stream version */
|
||||
ATOM_WRITE_U16 (0); /* Codec stream revision */
|
||||
ATOM_WRITE_4CC ('A', 'R', '.', 'D'); /* Muxer name */
|
||||
ATOM_WRITE_U32 (0x200); /* Temporal quality */
|
||||
ATOM_WRITE_U32 (0x200); /* Spatial quality */
|
||||
ATOM_WRITE_U16 (w); /* Width */
|
||||
ATOM_WRITE_U16 (h); /* Height */
|
||||
ATOM_WRITE_U32 (0x00480000); /* Horiz DPI : 72dpi */
|
||||
ATOM_WRITE_U32 (0x00480000); /* Vert DPI : 72dpi */
|
||||
ATOM_WRITE_U32 (0); /* Data size */
|
||||
ATOM_WRITE_U16 (1); /* Frame count */
|
||||
ATOM_WRITE_U32 (0); /* Compressor name ... 32 octets of zeros */
|
||||
ATOM_WRITE_U32 (0); /* Compressor name ... 32 octets of zeros */
|
||||
ATOM_WRITE_U32 (0); /* Compressor name ... 32 octets of zeros */
|
||||
ATOM_WRITE_U32 (0); /* Compressor name ... 32 octets of zeros */
|
||||
ATOM_WRITE_U32 (0); /* Compressor name ... 32 octets of zeros */
|
||||
ATOM_WRITE_U32 (0); /* Compressor name ... 32 octets of zeros */
|
||||
ATOM_WRITE_U32 (0); /* Compressor name ... 32 octets of zeros */
|
||||
ATOM_WRITE_U32 (0); /* Compressor name ... 32 octets of zeros */
|
||||
ATOM_WRITE_U16 (0x18); /* Reserved */
|
||||
ATOM_WRITE_U16 (0xffff); /* Reserved */
|
||||
/* avcC tag */
|
||||
ATOM_WRITE_U32 (avcCSize); /* Size */
|
||||
ATOM_WRITE_4CC ('a', 'v', 'c', 'C'); /* avcC header */
|
||||
ATOM_WRITE_U8 (1); /* version */
|
||||
ATOM_WRITE_U8 (sps[1]); /* profile */
|
||||
ATOM_WRITE_U8 (sps[2]); /* profile compat */
|
||||
ATOM_WRITE_U8 (sps[3]); /* level */
|
||||
ATOM_WRITE_U8 (0xff); /* Reserved (6bits) -- NAL size length - 1 (2bits) */
|
||||
ATOM_WRITE_U8 (0xe1); /* Reserved (3 bits) -- Number of SPS (5 bits) */
|
||||
ATOM_WRITE_U16 (spsSize); /* Size of SPS */
|
||||
ATOM_WRITE_BYTES (sps, spsSize); /* SPS header */
|
||||
ATOM_WRITE_U8 (1); /* Number of PPS */
|
||||
ATOM_WRITE_U16 (ppsSize); /* Size of PPS */
|
||||
ATOM_WRITE_BYTES (pps, ppsSize); /* PPS Header */
|
||||
uint32_t currentIndex = 0;
|
||||
ATOM_WRITE_U32 (0); /* version / flags */
|
||||
ATOM_WRITE_U32 (1); /* entry count */
|
||||
ATOM_WRITE_U32 (vse_size); /* video sample entry size */
|
||||
ATOM_WRITE_4CC ('a', 'v', 'c', '1'); /* VSE type */
|
||||
ATOM_WRITE_U32 (0); /* Reserved */
|
||||
ATOM_WRITE_U16 (0); /* Reserved */
|
||||
ATOM_WRITE_U16 (1); /* Data reference index */
|
||||
ATOM_WRITE_U16 (0); /* Codec stream version */
|
||||
ATOM_WRITE_U16 (0); /* Codec stream revision */
|
||||
ATOM_WRITE_4CC ('A', 'R', '.', 'D'); /* Muxer name */
|
||||
ATOM_WRITE_U32 (0x200); /* Temporal quality */
|
||||
ATOM_WRITE_U32 (0x200); /* Spatial quality */
|
||||
ATOM_WRITE_U16 (w); /* Width */
|
||||
ATOM_WRITE_U16 (h); /* Height */
|
||||
ATOM_WRITE_U32 (0x00480000); /* Horiz DPI : 72dpi */
|
||||
ATOM_WRITE_U32 (0x00480000); /* Vert DPI : 72dpi */
|
||||
ATOM_WRITE_U32 (0); /* Data size */
|
||||
ATOM_WRITE_U16 (1); /* Frame count */
|
||||
ATOM_WRITE_U32 (0); /* Compressor name ... 32 octets of zeros */
|
||||
ATOM_WRITE_U32 (0); /* Compressor name ... 32 octets of zeros */
|
||||
ATOM_WRITE_U32 (0); /* Compressor name ... 32 octets of zeros */
|
||||
ATOM_WRITE_U32 (0); /* Compressor name ... 32 octets of zeros */
|
||||
ATOM_WRITE_U32 (0); /* Compressor name ... 32 octets of zeros */
|
||||
ATOM_WRITE_U32 (0); /* Compressor name ... 32 octets of zeros */
|
||||
ATOM_WRITE_U32 (0); /* Compressor name ... 32 octets of zeros */
|
||||
ATOM_WRITE_U32 (0); /* Compressor name ... 32 octets of zeros */
|
||||
ATOM_WRITE_U16 (0x18); /* Reserved */
|
||||
ATOM_WRITE_U16 (0xffff); /* Reserved */
|
||||
/* avcC tag */
|
||||
ATOM_WRITE_U32 (avcCSize); /* Size */
|
||||
ATOM_WRITE_4CC ('a', 'v', 'c', 'C'); /* avcC header */
|
||||
ATOM_WRITE_U8 (1); /* version */
|
||||
ATOM_WRITE_U8 (sps[1]); /* profile */
|
||||
ATOM_WRITE_U8 (sps[2]); /* profile compat */
|
||||
ATOM_WRITE_U8 (sps[3]); /* level */
|
||||
ATOM_WRITE_U8 (0xff); /* Reserved (6bits) -- NAL size length - 1 (2bits) */
|
||||
ATOM_WRITE_U8 (0xe1); /* Reserved (3 bits) -- Number of SPS (5 bits) */
|
||||
ATOM_WRITE_U16 (spsSize); /* Size of SPS */
|
||||
ATOM_WRITE_BYTES (sps, spsSize); /* SPS header */
|
||||
ATOM_WRITE_U8 (1); /* Number of PPS */
|
||||
ATOM_WRITE_U16 (ppsSize); /* Size of PPS */
|
||||
ATOM_WRITE_BYTES (pps, ppsSize); /* PPS Header */
|
||||
|
||||
movie_atom_t *retAtom = atomFromData (dataSize, "stsd", data);
|
||||
ATOM_FREE (data);
|
||||
return retAtom;
|
||||
movie_atom_t *retAtom = atomFromData (dataSize, "stsd", data);
|
||||
ATOM_FREE (data);
|
||||
data = NULL;
|
||||
return retAtom;
|
||||
}
|
||||
|
||||
movie_atom_t *sttsAtomWithNumFrames (uint32_t nbFrames)
|
||||
{
|
||||
uint8_t data [16] = {0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01};
|
||||
uint32_t networkEndianFrames = htonl (nbFrames);
|
||||
ATOM_MEMCOPY( &data[8], &networkEndianFrames, sizeof (uint32_t));
|
||||
return atomFromData (16, "stts", data);
|
||||
uint8_t data [16] = {0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01};
|
||||
uint32_t networkEndianFrames = htonl (nbFrames);
|
||||
ATOM_MEMCOPY( &data[8], &networkEndianFrames, sizeof (uint32_t));
|
||||
return atomFromData (16, "stts", data);
|
||||
}
|
||||
|
||||
movie_atom_t *stscAtomGen ()
|
||||
{
|
||||
uint8_t data [20] = {0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x01};
|
||||
return atomFromData (20, "stsc", data);
|
||||
uint8_t data [20] = {0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x01};
|
||||
return atomFromData (20, "stsc", data);
|
||||
}
|
||||
|
||||
movie_atom_t *metadataAtomFromTagAndValue (const char *tag, const char *value)
|
||||
{
|
||||
movie_atom_t *retAtom = NULL;
|
||||
char locTag [4] = {0};
|
||||
/* If tag have a length of 3 chars, the (c) sign is added by this function */
|
||||
if (3 == strlen (tag))
|
||||
movie_atom_t *retAtom = NULL;
|
||||
char locTag [4] = {0};
|
||||
/* If tag have a length of 3 chars, the (c) sign is added by this function */
|
||||
if (3 == strlen (tag))
|
||||
{
|
||||
locTag[0] = '\251'; // (c) sign
|
||||
strncpy (&locTag[1], tag, 3);
|
||||
locTag[0] = '\251'; // (c) sign
|
||||
strncpy (&locTag[1], tag, 3);
|
||||
}
|
||||
/* Custom tag */
|
||||
else if (4 == strlen (tag))
|
||||
/* Custom tag */
|
||||
else if (4 == strlen (tag))
|
||||
{
|
||||
strncpy (locTag, tag, 4);
|
||||
strncpy (locTag, tag, 4);
|
||||
}
|
||||
|
||||
/* Continue only if we got a valid tag */
|
||||
if (0 != locTag [0])
|
||||
|
||||
/* Continue only if we got a valid tag */
|
||||
if (0 != locTag [0])
|
||||
{
|
||||
uint16_t valLen = (uint16_t) strlen (value);
|
||||
uint16_t langCode = 0x55c4; /* 5-bit ascii for "und", undefined */
|
||||
uint32_t currentIndex = 0;
|
||||
uint32_t dataSize = valLen + 4;
|
||||
uint8_t *data = ATOM_MALLOC (dataSize);
|
||||
if (NULL != data)
|
||||
uint16_t valLen = (uint16_t) strlen (value);
|
||||
uint16_t langCode = 0x55c4; /* 5-bit ascii for "und", undefined */
|
||||
uint32_t currentIndex = 0;
|
||||
uint32_t dataSize = valLen + 4;
|
||||
uint8_t *data = ATOM_MALLOC (dataSize);
|
||||
if (NULL != data)
|
||||
{
|
||||
ATOM_WRITE_U16 (valLen); /* Length of the value field */
|
||||
ATOM_WRITE_U16 (langCode); /* Language code, set to "und" (undefined) */
|
||||
ATOM_WRITE_BYTES (value, valLen); /* Actual value */
|
||||
retAtom = atomFromData (dataSize, locTag, data);
|
||||
ATOM_FREE (data);
|
||||
ATOM_WRITE_U16 (valLen); /* Length of the value field */
|
||||
ATOM_WRITE_U16 (langCode); /* Language code, set to "und" (undefined) */
|
||||
ATOM_WRITE_BYTES (value, valLen); /* Actual value */
|
||||
retAtom = atomFromData (dataSize, locTag, data);
|
||||
ATOM_FREE (data);
|
||||
data = NULL;
|
||||
}
|
||||
}
|
||||
return retAtom;
|
||||
return retAtom;
|
||||
}
|
||||
|
||||
movie_atom_t *ardtAtomFromPathAndDroneVersion(const char *path, uint8_t droneVersion)
|
||||
@@ -627,14 +649,14 @@ movie_atom_t *ardtAtomFromPathAndDroneVersion(const char *path, uint8_t droneVer
|
||||
{
|
||||
pathLength = strlen(path);
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint32_t dataSize = pathLength + versionStringLen + 4; // 2 for version + 2 for string size without '\0'
|
||||
uint8_t *data = ATOM_MALLOC(dataSize);
|
||||
if (NULL != data)
|
||||
{
|
||||
uint32_t currentIndex = 0;
|
||||
|
||||
|
||||
ATOM_WRITE_U16 (0); /* Version */
|
||||
ATOM_WRITE_U16 (pathLength + versionStringLen); /* length of string */
|
||||
ATOM_WRITE_U8 ('0' + ((droneVersion / 100) % 10)); /* Drone version number */
|
||||
@@ -647,8 +669,9 @@ movie_atom_t *ardtAtomFromPathAndDroneVersion(const char *path, uint8_t droneVer
|
||||
}
|
||||
retAtom = atomFromData (dataSize, "ardt", data);
|
||||
ATOM_FREE (data);
|
||||
data = NULL;
|
||||
}
|
||||
// NO ELSE - malloc failed
|
||||
|
||||
|
||||
return retAtom;
|
||||
}
|
||||
|
||||
@@ -61,6 +61,7 @@ ardt -> specific
|
||||
movie_atom_t *atomFromData (uint32_t data_size, const char *_tag, const uint8_t *_data);
|
||||
void insertAtomIntoAtom (movie_atom_t *container, movie_atom_t **leaf); // will free leaf
|
||||
int writeAtomToFile (movie_atom_t **_atom, FILE *file); // Will free _atom
|
||||
void freeAtom (movie_atom_t **_atom);
|
||||
|
||||
/* SPECIFIC */
|
||||
movie_atom_t *ftypAtomForFormatAndCodecWithOffset (ardrone_video_type_t format, parrot_video_encapsulation_codecs_t codec, uint32_t *offset, movie_atom_t **freeAtom);
|
||||
|
||||
@@ -28,10 +28,15 @@
|
||||
#include <Winsock2.h>
|
||||
#else
|
||||
#include <arpa/inet.h>
|
||||
#ifndef USE_ANDROID
|
||||
#include <ftw.h> // For file cleanup in subdirs
|
||||
#else
|
||||
#include <utils/AR_Ftw.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define ENCAPSULER_SMALL_STRING_SIZE (30)
|
||||
#define ENCAPSULER_INFODATA_MAX_SIZE (256)
|
||||
|
||||
/* The structure is initialised to an invalid value
|
||||
so we won't set any position in videos unless we got a
|
||||
@@ -141,6 +146,7 @@ ardrone_video_t *ardrone_video_start (const char *videoPath, int fps, ardrone_vi
|
||||
*error = ARDRONE_VIDEO_GENERIC_ERROR;
|
||||
vp_os_mutex_unlock(&retVideo->mutex);
|
||||
vp_os_free (retVideo);
|
||||
retVideo = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -160,6 +166,7 @@ ardrone_video_t *ardrone_video_start (const char *videoPath, int fps, ardrone_vi
|
||||
fclose (retVideo->infoFile);
|
||||
vp_os_mutex_unlock(&retVideo->mutex);
|
||||
vp_os_free (retVideo);
|
||||
retVideo = NULL;
|
||||
return NULL;
|
||||
}
|
||||
retVideo->framesCount = 0;
|
||||
@@ -270,8 +277,16 @@ ardrone_video_error_t ardrone_video_addFrame (ardrone_video_t *video, uint8_t *f
|
||||
if (NULL == video->sps || NULL == video->pps)
|
||||
{
|
||||
ENCAPSULER_ERROR ("Unable to allocate SPS/PPS buffers");
|
||||
if (NULL != video->sps) vp_os_free (video->sps);
|
||||
if (NULL != video->pps) vp_os_free (video->pps);
|
||||
if (NULL != video->sps)
|
||||
{
|
||||
vp_os_free (video->sps);
|
||||
video->sps = NULL;
|
||||
}
|
||||
if (NULL != video->pps)
|
||||
{
|
||||
vp_os_free (video->pps);
|
||||
video->pps = NULL;
|
||||
}
|
||||
vp_os_mutex_unlock(&video->mutex);
|
||||
return ARDRONE_VIDEO_GENERIC_ERROR;
|
||||
}
|
||||
@@ -290,6 +305,7 @@ ardrone_video_error_t ardrone_video_addFrame (ardrone_video_t *video, uint8_t *f
|
||||
if (NULL != freeAtomIfNeeded)
|
||||
{
|
||||
vp_os_free (freeAtomIfNeeded);
|
||||
freeAtomIfNeeded = NULL;
|
||||
}
|
||||
return ARDRONE_VIDEO_GENERIC_ERROR;
|
||||
}
|
||||
@@ -300,6 +316,7 @@ ardrone_video_error_t ardrone_video_addFrame (ardrone_video_t *video, uint8_t *f
|
||||
if (NULL != freeAtomIfNeeded)
|
||||
{
|
||||
vp_os_free (freeAtomIfNeeded);
|
||||
freeAtomIfNeeded = NULL;
|
||||
}
|
||||
return ARDRONE_VIDEO_FILE_ERROR;
|
||||
}
|
||||
@@ -356,7 +373,7 @@ ardrone_video_error_t ardrone_video_addFrame (ardrone_video_t *video, uint8_t *f
|
||||
}
|
||||
}
|
||||
|
||||
// Normal operation : file pointer is at end of file
|
||||
// Normal operation : file pointer is at end of file
|
||||
if (video->videoCodec != PaVE->video_codec ||
|
||||
video->width != PaVE->display_width ||
|
||||
video->height != PaVE->display_height)
|
||||
@@ -386,7 +403,7 @@ ardrone_video_error_t ardrone_video_addFrame (ardrone_video_t *video, uint8_t *f
|
||||
return ARDRONE_VIDEO_GENERIC_ERROR;
|
||||
}
|
||||
vp_os_memcpy (myData, data, frameSize);
|
||||
// Modify frames before writing
|
||||
// Modify frames before writing
|
||||
if (FRAME_TYPE_I_FRAME != PaVE->frame_type &&
|
||||
FRAME_TYPE_IDR_FRAME != PaVE->frame_type)
|
||||
{
|
||||
@@ -418,6 +435,7 @@ ardrone_video_error_t ardrone_video_addFrame (ardrone_video_t *video, uint8_t *f
|
||||
if (frameSize != fwrite (myData, 1, frameSize, video->outFile))
|
||||
{
|
||||
vp_os_free (myData);
|
||||
myData = NULL;
|
||||
ENCAPSULER_ERROR ("Unable to write frame into data file");
|
||||
vp_os_mutex_unlock(&video->mutex);
|
||||
return ARDRONE_VIDEO_FILE_ERROR;
|
||||
@@ -427,15 +445,16 @@ ardrone_video_error_t ardrone_video_addFrame (ardrone_video_t *video, uint8_t *f
|
||||
ENCAPSULER_FFLUSH (video->outFile);
|
||||
}
|
||||
vp_os_free (myData);
|
||||
myData = NULL;
|
||||
|
||||
char infoData [50] = {0};
|
||||
char infoData [ENCAPSULER_INFODATA_MAX_SIZE] = {0};
|
||||
char fTypeChar = 'p';
|
||||
if (FRAME_TYPE_I_FRAME == PaVE->frame_type ||
|
||||
FRAME_TYPE_IDR_FRAME == PaVE->frame_type)
|
||||
{
|
||||
fTypeChar = 'i';
|
||||
}
|
||||
snprintf (infoData, 50, ARDRONE_VIDEO_INFO_PATTERN, frameSize, fTypeChar);
|
||||
snprintf (infoData, ENCAPSULER_INFODATA_MAX_SIZE, ARDRONE_VIDEO_INFO_PATTERN, frameSize, fTypeChar);
|
||||
uint32_t infoLen = strlen (infoData);
|
||||
if (infoLen != fwrite (infoData, 1, infoLen, video->infoFile))
|
||||
{
|
||||
@@ -552,8 +571,17 @@ ardrone_video_error_t ardrone_video_addSlice (ardrone_video_t *video, uint8_t *s
|
||||
if (NULL == video->sps || NULL == video->pps)
|
||||
{
|
||||
ENCAPSULER_ERROR ("Unable to allocate SPS/PPS buffers");
|
||||
if (NULL != video->sps) vp_os_free (video->sps);
|
||||
if (NULL != video->pps) vp_os_free (video->pps);
|
||||
if (NULL != video->sps)
|
||||
{
|
||||
vp_os_free (video->sps);
|
||||
video->sps = NULL;
|
||||
}
|
||||
|
||||
if (NULL != video->pps)
|
||||
{
|
||||
vp_os_free (video->pps);
|
||||
video->pps = NULL;
|
||||
}
|
||||
vp_os_mutex_unlock(&video->mutex);
|
||||
return ARDRONE_VIDEO_GENERIC_ERROR;
|
||||
}
|
||||
@@ -572,6 +600,7 @@ ardrone_video_error_t ardrone_video_addSlice (ardrone_video_t *video, uint8_t *s
|
||||
if (NULL != freeAtomIfNeeded)
|
||||
{
|
||||
vp_os_free (freeAtomIfNeeded);
|
||||
freeAtomIfNeeded = NULL;
|
||||
}
|
||||
return ARDRONE_VIDEO_GENERIC_ERROR;
|
||||
}
|
||||
@@ -582,6 +611,7 @@ ardrone_video_error_t ardrone_video_addSlice (ardrone_video_t *video, uint8_t *s
|
||||
if (NULL != freeAtomIfNeeded)
|
||||
{
|
||||
vp_os_free (freeAtomIfNeeded);
|
||||
freeAtomIfNeeded = NULL;
|
||||
}
|
||||
return ARDRONE_VIDEO_FILE_ERROR;
|
||||
}
|
||||
@@ -655,14 +685,14 @@ ardrone_video_error_t ardrone_video_addSlice (ardrone_video_t *video, uint8_t *s
|
||||
{
|
||||
if (FRAME_TYPE_UNKNNOWN != video->lastFrameType)
|
||||
{
|
||||
char infoData [50] = {0};
|
||||
char infoData [ENCAPSULER_INFODATA_MAX_SIZE] = {0};
|
||||
char fTypeChar = 'p';
|
||||
if (FRAME_TYPE_I_FRAME == video->lastFrameType ||
|
||||
FRAME_TYPE_IDR_FRAME == video->lastFrameType)
|
||||
{
|
||||
fTypeChar = 'i';
|
||||
}
|
||||
snprintf (infoData, 50, ARDRONE_VIDEO_INFO_PATTERN, video->currentFrameSize, fTypeChar);
|
||||
snprintf (infoData, ENCAPSULER_INFODATA_MAX_SIZE, ARDRONE_VIDEO_INFO_PATTERN, video->currentFrameSize, fTypeChar);
|
||||
uint32_t infoLen = strlen (infoData);
|
||||
if (infoLen != fwrite (infoData, 1, infoLen, video->infoFile))
|
||||
{
|
||||
@@ -788,6 +818,7 @@ ardrone_video_error_t ardrone_video_finish (ardrone_video_t **video)
|
||||
if (0 == myVideo->width)
|
||||
{
|
||||
// Video was not initialized
|
||||
ENCAPSULER_ERROR ("video was not initialized");
|
||||
localError = ARDRONE_VIDEO_BAD_ARGS;
|
||||
} // No else
|
||||
}
|
||||
@@ -799,14 +830,14 @@ ardrone_video_error_t ardrone_video_finish (ardrone_video_t **video)
|
||||
{
|
||||
if (FRAME_TYPE_UNKNNOWN != myVideo->lastFrameType)
|
||||
{
|
||||
char infoData [50] = {0};
|
||||
char infoData [ENCAPSULER_INFODATA_MAX_SIZE] = {0};
|
||||
char fTypeChar = 'p';
|
||||
if (FRAME_TYPE_I_FRAME == myVideo->lastFrameType ||
|
||||
FRAME_TYPE_IDR_FRAME == myVideo->lastFrameType)
|
||||
{
|
||||
fTypeChar = 'i';
|
||||
}
|
||||
snprintf (infoData, 50, ARDRONE_VIDEO_INFO_PATTERN, myVideo->currentFrameSize, fTypeChar);
|
||||
snprintf (infoData, ENCAPSULER_INFODATA_MAX_SIZE, ARDRONE_VIDEO_INFO_PATTERN, myVideo->currentFrameSize, fTypeChar);
|
||||
|
||||
uint32_t infoLen = strlen (infoData);
|
||||
if (infoLen != fwrite (infoData, 1, infoLen, myVideo->infoFile))
|
||||
@@ -847,10 +878,15 @@ ardrone_video_error_t ardrone_video_finish (ardrone_video_t **video)
|
||||
{
|
||||
ENCAPSULER_ERROR ("Unable to allocate buffers for video finish");
|
||||
vp_os_free (frameSizeBuffer);
|
||||
frameSizeBuffer = NULL;
|
||||
vp_os_free (frameSizeBufferNE);
|
||||
frameSizeBufferNE = NULL;
|
||||
vp_os_free (frameOffsetBuffer);
|
||||
frameOffsetBuffer = NULL;
|
||||
vp_os_free (iFrameIndexBuffer);
|
||||
iFrameIndexBuffer = NULL;
|
||||
vp_os_free (frameIsIFrame);
|
||||
frameIsIFrame = NULL;
|
||||
vp_os_mutex_unlock(&myVideo->mutex);
|
||||
localError = ARDRONE_VIDEO_GENERIC_ERROR;
|
||||
}
|
||||
@@ -877,7 +913,7 @@ ardrone_video_error_t ardrone_video_finish (ardrone_video_t **video)
|
||||
{
|
||||
fseek (myVideo->infoFile, descriptorSize, SEEK_CUR);
|
||||
}
|
||||
while (! feof (myVideo->infoFile) && nbFrames <= myVideo->framesCount)
|
||||
while (! feof (myVideo->infoFile) && nbFrames < myVideo->framesCount)
|
||||
{
|
||||
uint32_t fSize = -1;
|
||||
char fType = 'a';
|
||||
@@ -901,12 +937,13 @@ ardrone_video_error_t ardrone_video_finish (ardrone_video_t **video)
|
||||
// create atoms
|
||||
// Generating Atoms
|
||||
tzset ();
|
||||
struct tm *nowTm = localtime (&myVideo->creationTime);
|
||||
EMPTY_ATOM(moov);
|
||||
movie_atom_t *mvhdAtom = mvhdAtomFromFpsNumFramesAndDate (myVideo->fps, nbFrames, myVideo->creationTime - timezone);
|
||||
movie_atom_t *mvhdAtom = mvhdAtomFromFpsNumFramesAndDate (myVideo->fps, nbFrames, myVideo->creationTime - timezone + (3600 * nowTm->tm_isdst));
|
||||
EMPTY_ATOM(trak);
|
||||
movie_atom_t *tkhdAtom = tkhdAtomWithResolutionNumFramesFpsAndDate (myVideo->width, myVideo->height, nbFrames, myVideo->fps, myVideo->creationTime - timezone);
|
||||
movie_atom_t *tkhdAtom = tkhdAtomWithResolutionNumFramesFpsAndDate (myVideo->width, myVideo->height, nbFrames, myVideo->fps, myVideo->creationTime - timezone + (3600 * nowTm->tm_isdst));
|
||||
EMPTY_ATOM(mdia);
|
||||
movie_atom_t *mdhdAtom = mdhdAtomFromFpsNumFramesAndDate (myVideo->fps, nbFrames, myVideo->creationTime - timezone);
|
||||
movie_atom_t *mdhdAtom = mdhdAtomFromFpsNumFramesAndDate (myVideo->fps, nbFrames, myVideo->creationTime - timezone + (3600 * nowTm->tm_isdst));
|
||||
movie_atom_t *hdlrAtom = hdlrAtomForMdia ();
|
||||
EMPTY_ATOM(minf);
|
||||
movie_atom_t *vmhdAtom = vmhdAtomGen ();
|
||||
@@ -925,6 +962,7 @@ ardrone_video_error_t ardrone_video_finish (ardrone_video_t **video)
|
||||
memcpy (&stssBuffer[8], iFrameIndexBuffer, nbIFrames * sizeof (uint32_t));
|
||||
movie_atom_t *stssAtom = atomFromData (stssDataLen, "stss", stssBuffer);
|
||||
vp_os_free (stssBuffer);
|
||||
stssBuffer = NULL;
|
||||
|
||||
movie_atom_t *stscAtom = stscAtomGen ();
|
||||
|
||||
@@ -936,6 +974,7 @@ ardrone_video_error_t ardrone_video_finish (ardrone_video_t **video)
|
||||
memcpy (&stszBuffer[12], frameSizeBufferNE, nbFrames * sizeof (uint32_t));
|
||||
movie_atom_t *stszAtom = atomFromData (stszDataLen, "stsz", stszBuffer);
|
||||
vp_os_free (stszBuffer);
|
||||
stszBuffer = NULL;
|
||||
|
||||
// Generate stco atom from frameOffsetBuffer and nbFrames
|
||||
uint32_t stcoDataLen = (8 + (nbFrames * sizeof (uint32_t)));
|
||||
@@ -944,12 +983,12 @@ ardrone_video_error_t ardrone_video_finish (ardrone_video_t **video)
|
||||
memcpy (&stcoBuffer[8], frameOffsetBuffer, nbFrames * sizeof (uint32_t));
|
||||
movie_atom_t *stcoAtom = atomFromData (stcoDataLen, "stco", stcoBuffer);
|
||||
vp_os_free (stcoBuffer);
|
||||
stcoBuffer = NULL;
|
||||
|
||||
EMPTY_ATOM (udta);
|
||||
movie_atom_t *swrAtom = metadataAtomFromTagAndValue ("swr", "AR.Drone 2.0");
|
||||
|
||||
char dateInfoString[ENCAPSULER_SMALL_STRING_SIZE] = {0};
|
||||
struct tm *nowTm = localtime (&myVideo->creationTime);
|
||||
snprintf (dateInfoString, ENCAPSULER_SMALL_STRING_SIZE, "%04d-%02d-%02dT%02d:%02d:%02d%+03d%02d",
|
||||
nowTm->tm_year + 1900,
|
||||
nowTm->tm_mon + 1,
|
||||
@@ -957,7 +996,7 @@ ardrone_video_error_t ardrone_video_finish (ardrone_video_t **video)
|
||||
nowTm->tm_hour,
|
||||
nowTm->tm_min,
|
||||
nowTm->tm_sec,
|
||||
(int)(-timezone / 3600),
|
||||
(int)(-timezone / 3600) + nowTm->tm_isdst,
|
||||
(int)((-timezone % 3600) / 60));
|
||||
movie_atom_t *dayAtom = metadataAtomFromTagAndValue ("day", dateInfoString);
|
||||
|
||||
@@ -965,10 +1004,17 @@ ardrone_video_error_t ardrone_video_finish (ardrone_video_t **video)
|
||||
int gpsIsValid = generateGpsString (gpsInfoString, ENCAPSULER_SMALL_STRING_SIZE);
|
||||
ENCAPSULER_DEBUG ("Valid : %d, Gps info string : %s\n", gpsIsValid, gpsInfoString);
|
||||
movie_atom_t *xyzAtom = NULL;
|
||||
|
||||
/**
|
||||
* Android 4.0.3 and later don't support the (c)xyz atom in the videos
|
||||
* We won't generate it for any android versions
|
||||
*/
|
||||
#ifndef USE_ANDROID
|
||||
if (1 == gpsIsValid)
|
||||
{
|
||||
xyzAtom = metadataAtomFromTagAndValue ("xyz", gpsInfoString);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Create atom tree
|
||||
insertAtomIntoAtom (udtaAtom, &swrAtom);
|
||||
@@ -1043,6 +1089,7 @@ ardrone_video_error_t ardrone_video_finish (ardrone_video_t **video)
|
||||
localError = ARDRONE_VIDEO_FILE_ERROR;
|
||||
}
|
||||
vp_os_free (mediaPath);
|
||||
mediaPath = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1084,21 +1131,32 @@ ardrone_video_error_t ardrone_video_finish (ardrone_video_t **video)
|
||||
|
||||
vp_os_mutex_unlock(&myVideo->mutex);
|
||||
vp_os_free (myVideo);
|
||||
myVideo = NULL;
|
||||
*video = NULL;
|
||||
|
||||
vp_os_free (frameSizeBuffer);
|
||||
frameSizeBuffer = NULL;
|
||||
vp_os_free (frameSizeBufferNE);
|
||||
frameSizeBufferNE = NULL;
|
||||
vp_os_free (frameOffsetBuffer);
|
||||
frameOffsetBuffer = NULL;
|
||||
vp_os_free (iFrameIndexBuffer);
|
||||
iFrameIndexBuffer = NULL;
|
||||
vp_os_free (frameIsIFrame);
|
||||
frameIsIFrame = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
vp_os_free (frameSizeBuffer);
|
||||
frameSizeBuffer = NULL;
|
||||
vp_os_free (frameSizeBufferNE);
|
||||
frameSizeBufferNE = NULL;
|
||||
vp_os_free (frameOffsetBuffer);
|
||||
frameOffsetBuffer = NULL;
|
||||
vp_os_free (iFrameIndexBuffer);
|
||||
iFrameIndexBuffer = NULL;
|
||||
vp_os_free (frameIsIFrame);
|
||||
frameIsIFrame = NULL;
|
||||
vp_os_mutex_unlock(&myVideo->mutex);
|
||||
ardrone_video_cleanup (video);
|
||||
}
|
||||
@@ -1494,10 +1552,13 @@ bool_t ardrone_video_try_fix (const char *infoFilePath)
|
||||
{
|
||||
ENCAPSULER_DEBUG ("Freeing local copies");
|
||||
ENCAPSULER_CLEANUP (vp_os_free, video->sps);
|
||||
video->sps = NULL;
|
||||
ENCAPSULER_CLEANUP (vp_os_free, video->pps);
|
||||
video->pps = NULL;
|
||||
ENCAPSULER_CLEANUP (fclose, video->infoFile);
|
||||
ENCAPSULER_CLEANUP (fclose, video->outFile);
|
||||
ENCAPSULER_CLEANUP (vp_os_free ,video);
|
||||
video = NULL;
|
||||
}
|
||||
|
||||
if (NULL != infoFile)
|
||||
|
||||
@@ -30,12 +30,12 @@
|
||||
#define ARDRONE_VIDEO_NUM_MATCH_PATTERN (2)
|
||||
|
||||
typedef enum {
|
||||
ARDRONE_VIDEO_NO_ERROR = 0,
|
||||
ARDRONE_VIDEO_GENERIC_ERROR,
|
||||
ARDRONE_VIDEO_BAD_CODEC,
|
||||
ARDRONE_VIDEO_FILE_ERROR,
|
||||
ARDRONE_VIDEO_WAITING_FOR_IFRAME,
|
||||
ARDRONE_VIDEO_BAD_ARGS,
|
||||
ARDRONE_VIDEO_NO_ERROR = 0,
|
||||
ARDRONE_VIDEO_GENERIC_ERROR,
|
||||
ARDRONE_VIDEO_BAD_CODEC,
|
||||
ARDRONE_VIDEO_FILE_ERROR,
|
||||
ARDRONE_VIDEO_WAITING_FOR_IFRAME,
|
||||
ARDRONE_VIDEO_BAD_ARGS,
|
||||
} ardrone_video_error_t;
|
||||
|
||||
#if COUNT_WAITING_FOR_IFRAME_AS_AN_ERROR
|
||||
@@ -44,62 +44,62 @@ typedef enum {
|
||||
#else
|
||||
static inline int ARDRONE_VIDEO_FAILED (ardrone_video_error_t error)
|
||||
{
|
||||
if (ARDRONE_VIDEO_NO_ERROR == error ||
|
||||
ARDRONE_VIDEO_WAITING_FOR_IFRAME == error)
|
||||
if (ARDRONE_VIDEO_NO_ERROR == error ||
|
||||
ARDRONE_VIDEO_WAITING_FOR_IFRAME == error)
|
||||
{
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
static inline int ARDRONE_VIDEO_SUCCEEDED (ardrone_video_error_t error)
|
||||
{
|
||||
if (ARDRONE_VIDEO_NO_ERROR == error ||
|
||||
ARDRONE_VIDEO_WAITING_FOR_IFRAME == error)
|
||||
if (ARDRONE_VIDEO_NO_ERROR == error ||
|
||||
ARDRONE_VIDEO_WAITING_FOR_IFRAME == error)
|
||||
{
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
#endif // COUNT_WAITING_FOR_IFRAME_AS_AN_ERROR
|
||||
|
||||
|
||||
typedef enum {
|
||||
ARDRONE_VIDEO_MOV = 0,
|
||||
ARDRONE_VIDEO_QUICKTIME = ARDRONE_VIDEO_MOV, // Alias for mov file
|
||||
ARDRONE_VIDEO_MP4,
|
||||
ARDRONE_VIDEO_MOV = 0,
|
||||
ARDRONE_VIDEO_QUICKTIME = ARDRONE_VIDEO_MOV, // Alias for mov file
|
||||
ARDRONE_VIDEO_MP4,
|
||||
} ardrone_video_type_t;
|
||||
|
||||
typedef struct _ardrone_video_t {
|
||||
uint32_t version;
|
||||
// Provided to constructor
|
||||
uint32_t fps;
|
||||
ardrone_video_type_t videoType;
|
||||
// Read from frames PaVE
|
||||
parrot_video_encapsulation_codecs_t videoCodec;
|
||||
uint16_t width;
|
||||
uint16_t height;
|
||||
// Private datas
|
||||
char infoFilePath [ARDRONE_VIDEO_PATH_MAX_SIZE]; // Keep this so we can delete the file
|
||||
char outFilePath [ARDRONE_VIDEO_PATH_MAX_SIZE]; // Keep this so we can rename the output file
|
||||
char tempFilePath [ARDRONE_VIDEO_PATH_MAX_SIZE]; // Keep this so we can rename the output file
|
||||
FILE *infoFile;
|
||||
FILE *outFile;
|
||||
uint32_t framesCount; // Number of frames
|
||||
uint32_t mdatAtomOffset;
|
||||
uint32_t framesDataOffset;
|
||||
// Provided to constructor
|
||||
uint32_t fps;
|
||||
ardrone_video_type_t videoType;
|
||||
// Read from frames PaVE
|
||||
parrot_video_encapsulation_codecs_t videoCodec;
|
||||
uint16_t width;
|
||||
uint16_t height;
|
||||
// Private datas
|
||||
char infoFilePath [ARDRONE_VIDEO_PATH_MAX_SIZE]; // Keep this so we can delete the file
|
||||
char outFilePath [ARDRONE_VIDEO_PATH_MAX_SIZE]; // Keep this so we can rename the output file
|
||||
char tempFilePath [ARDRONE_VIDEO_PATH_MAX_SIZE]; // Keep this so we can rename the output file
|
||||
FILE *infoFile;
|
||||
FILE *outFile;
|
||||
uint32_t framesCount; // Number of frames
|
||||
uint32_t mdatAtomOffset;
|
||||
uint32_t framesDataOffset;
|
||||
|
||||
/* H.264 only values */
|
||||
uint8_t *sps;
|
||||
/* H.264 only values */
|
||||
uint8_t *sps;
|
||||
uint8_t *pps;
|
||||
uint16_t spsSize;
|
||||
uint16_t ppsSize;
|
||||
uint16_t spsSize;
|
||||
uint16_t ppsSize;
|
||||
|
||||
/* Slices recording values */
|
||||
uint32_t lastFrameNumber;
|
||||
parrot_video_encapsulation_frametypes_t lastFrameType;
|
||||
uint32_t currentFrameSize;
|
||||
|
||||
vp_os_mutex_t mutex;
|
||||
/* Slices recording values */
|
||||
uint32_t lastFrameNumber;
|
||||
parrot_video_encapsulation_frametypes_t lastFrameType;
|
||||
uint32_t currentFrameSize;
|
||||
|
||||
vp_os_mutex_t mutex;
|
||||
time_t creationTime;
|
||||
uint32_t droneVersion;
|
||||
} ardrone_video_t;
|
||||
@@ -187,6 +187,7 @@ void ardrone_video_set_gps_infos (double latitude, double longitude, double alti
|
||||
/**
|
||||
* Try fo fix an MP4 infovid file.
|
||||
* @param infoFilePath Full path to the .infovid file.
|
||||
* @return TRUE on success, FALSE on failure
|
||||
*/
|
||||
bool_t ardrone_video_try_fix (const char *infoFilePath);
|
||||
|
||||
|
||||
@@ -57,6 +57,8 @@ void p263_codec_free( video_controller_t* controller )
|
||||
p263_codec_t* p263_codec = (p263_codec_t*) controller->video_codec;
|
||||
|
||||
vp_os_free( p263_codec );
|
||||
controller->video_codec = NULL;
|
||||
|
||||
}
|
||||
|
||||
static INLINE video_macroblock_t* p263_unquantize_idct( video_controller_t* controller, video_macroblock_t* mb, int32_t num_macro_blocks )
|
||||
|
||||
@@ -94,9 +94,16 @@ void p264_codec_free( video_controller_t* controller )
|
||||
if( p264_codec != NULL )
|
||||
{
|
||||
if (p264_codec->ref_picture.y_buf != NULL)
|
||||
{
|
||||
vp_os_free(p264_codec->ref_picture.y_buf);
|
||||
p264_codec->ref_picture.y_buf = NULL;
|
||||
}
|
||||
if (p264_codec->decoded_picture.y_buf != NULL)
|
||||
{
|
||||
vp_os_free(p264_codec->decoded_picture.y_buf);
|
||||
p264_codec->decoded_picture.y_buf = NULL;
|
||||
}
|
||||
|
||||
vp_os_free( p264_codec );
|
||||
controller->video_codec = NULL;
|
||||
}
|
||||
@@ -300,17 +307,17 @@ C_RESULT p264_unpack_controller( video_controller_t* controller )
|
||||
// new picture
|
||||
p264_read_picture_layer( controller, stream );
|
||||
|
||||
if (((controller->num_frames == (last_frame_decoded + 1)) && (controller->last_frame_decoded == TRUE))
|
||||
|| (controller->picture_type == VIDEO_PICTURE_INTRA))
|
||||
{
|
||||
// new picture is decodable because it's an I frame or previous frame was decodable
|
||||
controller->last_frame_decoded = TRUE;
|
||||
if (((controller->num_frames == (last_frame_decoded + 1)) && (controller->last_frame_decoded == TRUE))
|
||||
|| (controller->picture_type == VIDEO_PICTURE_INTRA))
|
||||
{
|
||||
// new picture is decodable because it's an I frame or previous frame was decodable
|
||||
controller->last_frame_decoded = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
controller->last_frame_decoded = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
controller->last_frame_decoded = FALSE;
|
||||
}
|
||||
|
||||
|
||||
p264_realloc_ref(controller);
|
||||
picture_layer->gobs = (p264_gob_layer_t*) controller->gobs;
|
||||
gob = &picture_layer->gobs[controller->blockline];
|
||||
|
||||
@@ -2,13 +2,6 @@
|
||||
|
||||
#ifdef HAS_UVLC_WRITE_BLOCK
|
||||
|
||||
#ifdef _ECOS
|
||||
#include "config-tcm.h"
|
||||
|
||||
.section ".text.itcm","ax"
|
||||
#endif // ! _ECOS
|
||||
|
||||
|
||||
.global uvlc_write_block
|
||||
.type uvlc_write_block, %function
|
||||
|
||||
|
||||
@@ -2,12 +2,6 @@
|
||||
|
||||
#ifdef HAS_DO_QUANTIZE_INTRA_MB
|
||||
|
||||
#ifdef _ECOS
|
||||
#include "config-tcm.h"
|
||||
|
||||
.section ".text.itcm","ax"
|
||||
#endif // ! _ECOS
|
||||
|
||||
.global do_quantize_intra_mb
|
||||
.type do_quantize_intra_mb, %function
|
||||
|
||||
|
||||
@@ -235,7 +235,7 @@ C_RESULT uvlc_unpack_controller( video_controller_t* controller )
|
||||
{
|
||||
// new picture
|
||||
uvlc_read_picture_layer( controller, stream );
|
||||
controller->last_frame_decoded = TRUE;
|
||||
controller->last_frame_decoded = TRUE;
|
||||
|
||||
picture_layer->gobs = (uvlc_gob_layer_t*) controller->gobs;
|
||||
gob = &picture_layer->gobs[controller->blockline];
|
||||
|
||||
@@ -257,8 +257,8 @@ C_RESULT video_decode_blockline( video_controller_t* controller, vp_api_picture_
|
||||
if (C_OK == isCodecOK &&
|
||||
NULL != controller->video_codec)
|
||||
{
|
||||
return controller->video_codec->decode_blockline( controller, blockline, got_image );
|
||||
}
|
||||
return controller->video_codec->decode_blockline( controller, blockline, got_image );
|
||||
}
|
||||
else
|
||||
{
|
||||
return C_FAIL;
|
||||
|
||||
@@ -123,6 +123,7 @@ C_RESULT video_controller_cleanup( video_controller_t* controller )
|
||||
{
|
||||
gob = &controller->gobs[0];
|
||||
vp_os_free(gob->macroblocks);
|
||||
gob->macroblocks = NULL;
|
||||
vp_os_free( controller->gobs );
|
||||
controller->gobs = NULL;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ huffman_tree_t* huffman_alloc( int32_t num_max_codes, int32_t max_code_length )
|
||||
void huffman_free( huffman_tree_t* tree )
|
||||
{
|
||||
vp_os_free( tree );
|
||||
tree = NULL;
|
||||
}
|
||||
|
||||
C_RESULT huffman_add_codes( huffman_tree_t* tree, huffman_code_t* codes, int32_t num_codes )
|
||||
|
||||
@@ -295,7 +295,7 @@ ATcodec_Add_Defined_Message_Tree (ATcodec_Tree_t *tree, const char *str)
|
||||
void
|
||||
ATcodec_Init_Library (AT_CODEC_FUNCTIONS_PTRS *funcs)
|
||||
{
|
||||
ATcodec_Init_Library_Tree (&default_tree, funcs);
|
||||
ATcodec_Init_Library_Tree (&default_tree, funcs);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -341,7 +341,7 @@ ATcodec_Init_Library_Tree (ATcodec_Tree_t *tree, AT_CODEC_FUNCTIONS_PTRS *func
|
||||
void
|
||||
ATcodec_Shutdown_Library (void)
|
||||
{
|
||||
ATcodec_Shutdown_Library_Tree(&default_tree);
|
||||
ATcodec_Shutdown_Library_Tree(&default_tree);
|
||||
}
|
||||
|
||||
|
||||
@@ -699,15 +699,15 @@ ATcodec_Send_Messages()
|
||||
|
||||
if(!atcodec_lib_init_ok)
|
||||
return ATCODEC_FALSE;
|
||||
|
||||
|
||||
vp_os_mutex_lock(&ATcodec_cond_mutex);
|
||||
if(ATcodec_Message_len > INTERNAL_BUFFER_SIZE)
|
||||
printf("ATcodec_Send_Messages : buf=%s, len=%d\n", &ATcodec_Message_Buffer[0], ATcodec_Message_len);
|
||||
|
||||
PRINT("ATcodec_Send_Messages : buf=%s, len=%d\n", &ATcodec_Message_Buffer[0], ATcodec_Message_len);
|
||||
|
||||
if(ATcodec_Message_len && func_ptrs.write((uint8_t*)&ATcodec_Message_Buffer[0], (int32_t*)&ATcodec_Message_len) != AT_CODEC_WRITE_OK)
|
||||
res = ATCODEC_FALSE;
|
||||
|
||||
ATcodec_Message_len = 0;
|
||||
res = ATCODEC_FALSE;
|
||||
|
||||
ATcodec_Message_len = 0;
|
||||
|
||||
vp_os_mutex_unlock(&ATcodec_cond_mutex);
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ before_check:
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------------------------------------------------
|
||||
TARGETS=vlib parrotOS_core parrotOS_utils parrotOS_drivers parrotOS_devs parrotOS_codec libplf sdk lib app
|
||||
TARGETS=vlib libplf sdk lib app
|
||||
|
||||
# When building on Ubuntu, only the final application (USE_APP) depends on the above-mentioned libraries.
|
||||
# The iPhone applications do not use USE_APP; the above-mentioned libraries must therefore be built
|
||||
@@ -105,7 +105,8 @@ define ADD_RULE_TEMPLATE
|
||||
ifeq ($(USE_ANDROID),yes)
|
||||
build_lib: build_$(1)
|
||||
endif
|
||||
ifeq ($(USE_LINUX), yes)
|
||||
# Following three lines added after more than four hours of WTF debugging -- mani
|
||||
ifeq ($(USE_LINUX),yes)
|
||||
build_lib: build_$(1)
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -19,47 +19,10 @@ USE_VLIB=yes
|
||||
SWING_VERSION=head
|
||||
|
||||
# Check validity of script usage.
|
||||
if [ $1 ] && [ $1 = ecos ] ; then
|
||||
if [ ! $QUIET_BUILD = yes ] ; then
|
||||
echo ; echo "BUILD FOR ECOS" ; echo
|
||||
fi
|
||||
USE_ECOS=yes
|
||||
USE_LINUX=no
|
||||
USE_ELINUX=no
|
||||
USE_NDS=no
|
||||
USE_IPHONE=no
|
||||
# head ecos-stable-2006-11-21 ecos-stable-2007-07-23 CK5300_Version_20070928_Beta5
|
||||
ECOS_VERSION=Mykonos_Version_20090212
|
||||
PROJECT=mykonos_p5p
|
||||
MODE_TARGET=rls_ram_wifi_ap
|
||||
CUSTOM_PRIORITIES=$ALL_SOURCES/video/$SDK_VERSION/Video/VP_SDK/VP_Os/ecos/task_priorities.h
|
||||
# gnutools_2008_03_28 gnutools_2007_02_07 gnutools_2005_05_20
|
||||
GNUTOOLS_VERSION=gnutools_2008_03_28
|
||||
USE_ECOS_RELEASE=no
|
||||
NO_COM=no
|
||||
USE_BONJOUR=no
|
||||
USE_BLUES32=no
|
||||
# Stable_20070307 Stable_20060922 Stable_20061129_Blues_3_6_4 Version_KEA_1_00_RC5_200701131
|
||||
BLUES32_VERSION=Stable_20060922
|
||||
COMMONSOFT_VERSION=head
|
||||
USE_PVSP=yes
|
||||
USE_SOUL=no
|
||||
SOUL_VERSION=Stable_20070307
|
||||
USE_TANGO=no
|
||||
# Stable_20061222 Stable_20070509
|
||||
TANGO_VERSION=Stable_20070509
|
||||
DONT_USE_TTS=yes
|
||||
USE_CK5050=no
|
||||
CK5050_VERSION=head
|
||||
USE_BLUEZ=no
|
||||
# P5 Intel smdk2412
|
||||
FF_ARCH=P5
|
||||
USE_PARROTOS_CORE=no
|
||||
elif [ $1 ] && [ $1 = elinux ] ; then
|
||||
if [ $1 ] && [ $1 = elinux ] ; then
|
||||
if [ ! $QUIET_BUILD = yes ] ; then
|
||||
echo ; echo "BUILD FOR EMBEDDED LINUX" ; echo
|
||||
fi
|
||||
USE_ECOS=no
|
||||
USE_LINUX=no
|
||||
USE_ELINUX=yes
|
||||
USE_NDS=no
|
||||
@@ -80,7 +43,6 @@ elif [ $1 ] && [ $1 = linux ] ; then
|
||||
if [ ! $QUIET_BUILD = yes ] ; then
|
||||
echo ; echo "BUILD FOR LINUX" ; echo
|
||||
fi
|
||||
USE_ECOS=no
|
||||
USE_LINUX=yes
|
||||
USE_ELINUX=no
|
||||
USE_NDS=no
|
||||
@@ -96,7 +58,6 @@ elif [ $1 ] && [ $1 = nds ] ; then
|
||||
if [ ! $QUIET_BUILD = yes ] ; then
|
||||
echo ; echo "BUILD FOR NINTENDO DS" ; echo
|
||||
fi
|
||||
USE_ECOS=no
|
||||
USE_LINUX=no
|
||||
USE_ELINUX=no
|
||||
USE_NDS=yes
|
||||
@@ -112,7 +73,6 @@ elif [ $1 ] && [ ${1:0:6} = iphone ] ; then
|
||||
if [ ! $QUIET_BUILD = yes ] ; then
|
||||
echo ; echo "BUILD FOR IPHONE with platform $1 $IPHONE_SDK_VERSION" ; echo
|
||||
fi
|
||||
USE_ECOS=no
|
||||
USE_LINUX=no
|
||||
USE_ELINUX=no
|
||||
USE_NDS=no
|
||||
@@ -135,7 +95,6 @@ FLAGS="USE_APP=$USE_APP"
|
||||
FLAGS="IPHONE_SDK_VERSION=$IPHONE_SDK_VERSION $FLAGS"
|
||||
FLAGS="NO_EXAMPLES=$NO_EXAMPLES $FLAGS"
|
||||
FLAGS="GNUTOOLS_VERSION=$GNUTOOLS_VERSION $FLAGS"
|
||||
FLAGS="USE_ECOS=$USE_ECOS $FLAGS"
|
||||
FLAGS="USE_LINUX=$USE_LINUX $FLAGS"
|
||||
FLAGS="USE_ELINUX=$USE_ELINUX $FLAGS"
|
||||
FLAGS="USE_NDS=$USE_NDS $FLAGS"
|
||||
@@ -160,8 +119,6 @@ FLAGS="QUIET_BUILD=$QUIET_BUILD $FLAGS"
|
||||
FLAGS="RELEASE_BUILD=$RELEASE_BUILD $FLAGS"
|
||||
FLAGS="SDK_VERSION=$SDK_VERSION $FLAGS"
|
||||
|
||||
FLAGS="USE_ECOS_RELEASE=$USE_ECOS_RELEASE $FLAGS"
|
||||
FLAGS="ECOS_VERSION=$ECOS_VERSION $FLAGS"
|
||||
FLAGS="ELINUX_VERSION=$ELINUX_VERSION $FLAGS"
|
||||
FLAGS="PROJECT=$PROJECT $FLAGS"
|
||||
FLAGS="MODE_TARGET=$MODE_TARGET $FLAGS"
|
||||
@@ -181,17 +138,10 @@ FLAGS="USE_IWLIB=$USE_IWLIB $FLAGS"
|
||||
FLAGS="USE_PARROTOS_CORE=$USE_PARROTOS_CORE $FLAGS"
|
||||
FLAGS="COMMONSOFT_VERSION=$COMMONSOFT_VERSION $FLAGS"
|
||||
|
||||
if [ $USE_ECOS = yes ] ; then
|
||||
FLAGS="CUSTOM_PRIORITIES=$CUSTOM_PRIORITIES $FLAGS"
|
||||
fi
|
||||
|
||||
if [ $USE_ELINUX = yes ] ; then
|
||||
FLAGS="CONFIG_PARROTOS=$CONFIG_PARROTOS $FLAGS"
|
||||
fi
|
||||
|
||||
if [ $USE_ECOS = yes ] && [ $2 ] && ! [ $2 = check ] && ! [ $2 = clean ] || [ $USE_ECOS = yes ] && ! [ $2 ] ; then
|
||||
CHOOSE=yes
|
||||
fi
|
||||
if [ $2 ] && [ $2 = check ] ; then
|
||||
CHECK=yes
|
||||
fi
|
||||
@@ -212,38 +162,3 @@ if [ $CHECK ] && [ $CHECK = yes ] ; then
|
||||
else
|
||||
make -f Makefile $FLAGS $* 2>&1
|
||||
fi
|
||||
|
||||
#####################
|
||||
# Choose example ?
|
||||
#####################
|
||||
|
||||
if [ $CHOOSE ] && [ $CHOOSE = yes ] ; then
|
||||
j=1 ; for i in $( find . -type d -name "*Examples" | grep arm ) ; do j=$( expr $j + 1 ) ; done
|
||||
|
||||
if [ $j = 1 ] ; then
|
||||
echo No example directory found
|
||||
exit
|
||||
fi
|
||||
|
||||
if ! [ $j = 2 ] ; then
|
||||
j=1 ; for i in $( find . -type d -name "*Examples" | grep arm ) ; do echo -e "\t$j\t$i" ; j=$( expr $j + 1 ) ; done
|
||||
echo -n -e "\nChoose directory : "
|
||||
read var
|
||||
j=1 ; for i in $( find . -type d -name "*Examples" | grep arm ) ; do if [ $j = $var ] ; then ex_dir=$i ; fi ; j=$( expr $j + 1 ) ; done
|
||||
else
|
||||
ex_dir=$( find . -type d -name "*Examples" | grep arm )
|
||||
fi
|
||||
|
||||
echo -e "\nDirectory $ex_dir :"
|
||||
|
||||
j=1 ; for i in $( find $ex_dir -type f -exec basename \{\} \; ) ; do echo -e "\t$j\t$i" ; j=$( expr $j + 1 ) ; done
|
||||
echo -n -e "\nChoose example : "
|
||||
read var
|
||||
j=1 ; for i in $( find $ex_dir -type f ) ; do if [ $j = $var ] ; then ex_file=$i ; fi ; j=$( expr $j + 1 ) ; done
|
||||
|
||||
if [ ! -z $ex_file ] && [ -f $ex_file ] ; then
|
||||
cp $ex_file /srv/tftp/program.elf && echo -e "\n$ex_file copied to /srv/tftp/program.elf"
|
||||
else
|
||||
echo -e "\nBad choice !"
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -66,7 +66,6 @@ vp_os_cond_wait(vp_os_cond_t *cond)
|
||||
pthread_cond_wait(&cond->cond, (pthread_mutex_t *)cond->mutex);
|
||||
}
|
||||
|
||||
|
||||
C_RESULT
|
||||
vp_os_cond_timed_wait(vp_os_cond_t *cond, uint32_t ms)
|
||||
{
|
||||
|
||||
@@ -86,11 +86,13 @@ vp_os_cond_timed_wait(vp_os_cond_t *cond, uint32_t ms)
|
||||
gettimeofday(&tv, NULL);
|
||||
TIMEVAL_TO_TIMESPEC(&tv, &ts);
|
||||
ts.tv_sec += ms/1000;
|
||||
ts.tv_nsec += (ms%1000)*1000;
|
||||
ts.tv_nsec += (ms%1000)*1000000;
|
||||
if (ts.tv_nsec>1000000000) { ts.tv_sec++, ts.tv_nsec-=1000000000; }
|
||||
return ( pthread_cond_timedwait(&cond->cond, (pthread_mutex_t *)cond->mutex, &ts) == ETIMEDOUT ? FAIL : SUCCESS );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
vp_os_cond_signal(vp_os_cond_t *cond)
|
||||
{
|
||||
|
||||
@@ -23,20 +23,28 @@
|
||||
#endif // __MACOSX__
|
||||
|
||||
#ifdef USE_ANDROID
|
||||
#include <android/log.h>
|
||||
#undef PRINT
|
||||
#define PRINT(_fmt_, args...) \
|
||||
#include <android/log.h>
|
||||
#undef PRINT
|
||||
#ifdef DEBUG_MODE
|
||||
#define PRINT(_fmt_, args...) \
|
||||
__android_log_print(ANDROID_LOG_INFO, "ARDrone", _fmt_, ##args)
|
||||
#else
|
||||
#define PRINT(...)
|
||||
#endif //DEBUG_MODE
|
||||
#endif // USE_ANDROID
|
||||
|
||||
#ifndef PRINT
|
||||
#define PRINT printf
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_MODE
|
||||
#define DEBUG_PRINT_SDK(...) printf(__VA_ARGS__)
|
||||
#define DEBUG_PRINT_SDK(...) PRINT(__VA_ARGS__)
|
||||
#else
|
||||
#define DEBUG_PRINT_SDK(...)
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_MODE
|
||||
#define DEBUG_PRINT(...) printf(__VA_ARGS__)
|
||||
#define DEBUG_PRINT(...) PRINT(__VA_ARGS__)
|
||||
#else
|
||||
#define DEBUG_PRINT(...)
|
||||
#endif
|
||||
|
||||
@@ -2,9 +2,6 @@
|
||||
#include <VP_Stages/vp_stages_frame_pipe.h>
|
||||
#include <VP_Os/vp_os_print.h>
|
||||
|
||||
#ifdef USE_ELINUX
|
||||
#include <VP_Os/elinux/vp_os_ltt.h>
|
||||
#endif
|
||||
// Sender function
|
||||
C_RESULT
|
||||
vp_stages_frame_pipe_sender_open(vp_stages_frame_pipe_config_t *cfg)
|
||||
@@ -185,6 +182,7 @@ C_RESULT
|
||||
vp_stages_frame_pipe_receiver_close(vp_stages_frame_pipe_config_t *cfg)
|
||||
{
|
||||
vp_os_free (cfg->outPicture.raw);
|
||||
cfg->outPicture.raw = NULL;
|
||||
vp_os_cond_destroy (&(cfg->buffer_sent));
|
||||
vp_os_mutex_destroy (&(cfg->pipe_mut));
|
||||
return C_OK;
|
||||
|
||||
@@ -99,7 +99,10 @@ vp_stages_output_buffer_stage_transform(vp_stages_output_buffer_config_t *cfg, v
|
||||
}
|
||||
|
||||
if(in->status == VP_API_STATUS_ENDED)
|
||||
vp_os_free(out->buffers);
|
||||
{
|
||||
vp_os_free(out->buffers);
|
||||
out->buffers = NULL;
|
||||
}
|
||||
|
||||
out->status = in->status;
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ vp_stages_input_file_stage_open(vp_stages_input_file_config_t *cfg)
|
||||
cfg->buffers = vp_os_malloc(sizeof(*cfg->buffers)*cfg->nb_buffers);
|
||||
if (cfg->buffers==NULL)
|
||||
{
|
||||
printf("%s:%d - Failed preloading %s : not enough memory for buffer pointers(required %d pointers)\n",
|
||||
PRINT("%s:%d - Failed preloading %s : not enough memory for buffer pointers(required %d pointers)\n",
|
||||
__FUNCTION__,__LINE__,
|
||||
cfg->name,cfg->nb_buffers/(1024*1024));
|
||||
}
|
||||
@@ -113,7 +113,7 @@ vp_stages_input_file_stage_open(vp_stages_input_file_config_t *cfg)
|
||||
#endif
|
||||
if (cfg->data==NULL)
|
||||
{
|
||||
printf("Failed preloading %s : not enough memory (required %d MB)\n",
|
||||
PRINT("Failed preloading %s : not enough memory (required %d MB)\n",
|
||||
cfg->name,cfg->buffer_size*cfg->nb_buffers/(1024*1024));
|
||||
}
|
||||
|
||||
@@ -124,10 +124,12 @@ vp_stages_input_file_stage_open(vp_stages_input_file_config_t *cfg)
|
||||
|
||||
if (cfg->data && cfg->preload!=0)
|
||||
{
|
||||
printf("Preloading file %s to memory ...\n",cfg->name);
|
||||
PRINT("Preloading file %s to memory ...\n",cfg->name);
|
||||
for (i=0;i<cfg->nb_buffers;i++)
|
||||
{
|
||||
printf("."); fflush(stdout);
|
||||
#ifndef USE_ELINUX
|
||||
PRINT("."); fflush(stdout);
|
||||
#endif
|
||||
res = fread(cfg->buffers[i], cfg->buffer_size , 1 , cfg->f);
|
||||
if (res<1)
|
||||
{
|
||||
@@ -135,14 +137,14 @@ vp_stages_input_file_stage_open(vp_stages_input_file_config_t *cfg)
|
||||
cfg->nb_buffers=i; /* Store the number of successfully read frames */
|
||||
}
|
||||
}
|
||||
printf("ok.\n");
|
||||
PRINT("ok.\n");
|
||||
fclose(cfg->f);
|
||||
cfg->f=NULL;
|
||||
}
|
||||
|
||||
cfg->current_buffer=0;
|
||||
|
||||
printf("Using %s input file %s\n resolution %dx%d\n total size : %d MB\n",
|
||||
PRINT("Using %s input file %s\n resolution %dx%d\n total size : %d MB\n",
|
||||
(PIX_FMT_YUV420P==cfg->vp_api_picture.format)?"420P":"422",
|
||||
cfg->name,
|
||||
cfg->width,cfg->height,filesize/(1024*1024));
|
||||
@@ -156,7 +158,7 @@ vp_stages_input_file_stage_transform(vp_stages_input_file_config_t *cfg, vp_api_
|
||||
vp_os_mutex_lock(&out->lock);
|
||||
|
||||
#ifdef VERBOSE
|
||||
printf("%s:%d Reading a frame from YUV file %s ...\n",__FUNCTION__,__LINE__,cfg->name);
|
||||
PRINT("%s:%d Reading a frame from YUV file %s ...\n",__FUNCTION__,__LINE__,cfg->name);
|
||||
#endif
|
||||
|
||||
/* Init */
|
||||
@@ -170,7 +172,7 @@ vp_stages_input_file_stage_transform(vp_stages_input_file_config_t *cfg, vp_api_
|
||||
|
||||
|
||||
#ifdef VERBOSE
|
||||
printf("%s:%d Frames stored at address %p.\n",__FUNCTION__,__LINE__,cfg->data);
|
||||
PRINT("%s:%d Frames stored at address %p.\n",__FUNCTION__,__LINE__,cfg->data);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -197,7 +199,7 @@ vp_stages_input_file_stage_transform(vp_stages_input_file_config_t *cfg, vp_api_
|
||||
/* Read a frame from the disk file */
|
||||
|
||||
#ifdef VERBOSE
|
||||
printf("%s:%d Requesting %d bytes ...\n",__FUNCTION__,__LINE__,cfg->buffer_size);
|
||||
PRINT("%s:%d Requesting %d bytes ...\n",__FUNCTION__,__LINE__,cfg->buffer_size);
|
||||
#endif
|
||||
|
||||
out->buffers=cfg->buffers;
|
||||
@@ -205,7 +207,7 @@ vp_stages_input_file_stage_transform(vp_stages_input_file_config_t *cfg, vp_api_
|
||||
out->size = fread(out->buffers[0], cfg->buffer_size, 1 , cfg->f);
|
||||
|
||||
#ifdef VERBOSE
|
||||
printf("%s:%d Read %d bytes ...\n",__FUNCTION__,__LINE__,out->size);
|
||||
PRINT("%s:%d Read %d bytes ...\n",__FUNCTION__,__LINE__,out->size);
|
||||
#endif
|
||||
|
||||
/* Go back at the beginning of the file if we reached the end of the video */
|
||||
@@ -282,7 +284,7 @@ vp_stages_output_file_stage_open(vp_stages_output_file_config_t *cfg)
|
||||
cfg->f = fopen(cfg->name, "wb");
|
||||
if(NULL == cfg->f)
|
||||
{
|
||||
printf("%s:%d - Error opening file %s\n",__FUNCTION__,__LINE__,cfg->name);perror("");
|
||||
PRINT("%s:%d - Error opening file %s\n",__FUNCTION__,__LINE__,cfg->name);perror("");
|
||||
return VP_FAILURE;
|
||||
}
|
||||
return (VP_SUCCESS);
|
||||
|
||||
@@ -355,10 +355,11 @@ vp_stages_output_sdl_stage_transform(vp_stages_output_sdl_config_t *cfg, vp_api_
|
||||
|
||||
// not managed
|
||||
if(in->status == VP_API_STATUS_ENDED)
|
||||
{
|
||||
{
|
||||
pipeline_opened = 0;
|
||||
vp_os_free(out->buffers);
|
||||
}
|
||||
out->buffers = NULL;
|
||||
}
|
||||
|
||||
vp_os_mutex_unlock(&out->lock);
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ rosbuild_gensrv()
|
||||
#rosbuild_link_boost(${PROJECT_NAME} thread)
|
||||
#target_link_libraries(example ${PROJECT_NAME})
|
||||
|
||||
rosbuild_add_boost_directories()
|
||||
set(SDK ARDroneLib/)
|
||||
link_directories(${PROJECT_SOURCE_DIR}/lib/)
|
||||
include_directories(${SDK} ${SDK}/FFMPEG/Includes ${SDK}/Soft/Common ${SDK}/Soft/Lib ${SDK}/VP_SDK ${SDK}/VP_SDK/VP_Os/linux )
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
include $(shell rospack find mk)/cmake.mk
|
||||
@@ -1,4 +1,5 @@
|
||||
Copyright (C) 2007-2011, PARROT SA, all rights reserved.
|
||||
|
||||
DISCLAIMER
|
||||
The APIs is provided by PARROT and contributors "AS IS" and any express or implied warranties, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose are disclaimed. In no event shall PARROT and contributors be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including, but not limited to, procurement of substitute goods or services; loss of use, data, or profits; or business interruption) however caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this software, even if advised of the possibility of such damage.
|
||||
The APIs is provided by PARROT and contributors "AS IS" and any express or implied warranties, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose are disclaimed. In no event shall PARROT and contributors be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including, but not limited to, procurement of substitute goods or services; loss of use, data, or profits; or business interruption) however caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this software, even if advised of the possibility of such damage.
|
||||
|
||||
|
||||
+99
-86
@@ -1,22 +1,22 @@
|
||||
IMPORTANT: INSTRUCTION TO USE AND TO APPLY THE TERMS OF THE LICENSE TO ANY NEW PROGRAM
|
||||
|
||||
READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING
|
||||
|
||||
|
||||
|
||||
Copyright (C) 2007-2011, PARROT SA, all rights reserved.
|
||||
|
||||
|
||||
You may use, copy, modify the PARROT AR.Drone SDK and APIs or any portion of it, and thus form a work based on Parrot SDK and APIs, and copy and redistribute in source code and binary forms, with or without modification, provided that you comply with following conditions:
|
||||
|
||||
• Redistribution in source code, with or without modification, must retain Parrot copyright notice, the following disclaimer and the license to develop and use in a text file named “Parrot License”.
|
||||
* Redistribution in source code, with or without modification, must retain Parrot copyright notice, the following disclaimer and the license to develop and use in a text file named “Parrot License”.
|
||||
|
||||
• Redistribution in binary form must reproduce Parrot copyright notice, the following disclaimer in the product documentation or legal notice.
|
||||
* Redistribution in binary form must reproduce Parrot copyright notice, the following disclaimer in the product documentation or legal notice.
|
||||
|
||||
• The name of Parrot may not be used to endorse or promote products derived from the APIs without specific prior written permission.
|
||||
* The name of Parrot may not be used to endorse or promote products derived from the APIs without specific prior written permission.
|
||||
|
||||
|
||||
DISCLAIMER
|
||||
The APIs is provided by PARROT and contributors "AS IS" and any express or implied warranties, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose are disclaimed. In no event shall PARROT and contributors be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including, but not limited to, procurement of substitute goods or services; loss of use, data, or profits; or business interruption) however caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this software, even if advised of the possibility of such damage.
|
||||
The APIs is provided by PARROT and contributors "AS IS" and any express or implied warranties, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose are disclaimed. In no event shall PARROT and contributors be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including, but not limited to, procurement of substitute goods or services; loss of use, data, or profits; or business interruption) however caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this software, even if advised of the possibility of such damage.
|
||||
|
||||
|
||||
DEVELOPMENT LICENSE OF THE PARROT AR.DRONE SDK and APIs V2.0
|
||||
@@ -25,101 +25,98 @@ DEVELOPMENT LICENSE OF THE PARROT AR.DRONE SDK and APIs V2.0
|
||||
|
||||
|
||||
|
||||
Article 1: Purpose
|
||||
Article 1: Purpose
|
||||
The purpose of the present Development License is to define the terms and conditions under which the Developer is authorized to use the source codes of the PARROT SDK and APIs to create under its own responsibility a Game for the AR.Drone and to market it for free or against payment.
|
||||
|
||||
Article 2: Definitions
|
||||
The terms defined hereunder, used in singular or plural, shall have the following meaning:
|
||||
|
||||
- «PARROT SDK and APIs »: means the AR.Drone software development kit and AR.Drone APIs and associated documentation, allowing to pilot the PARROT AR.Drone, from a mobile phone, a console game, a computer or any other electronic device, and which source codes are provided for free to the Developer;
|
||||
- « Developer » means a physical person, of age, having the capacity to accept the terms of the present License or a person, representing a company and having all powers to that effect to bind the company;
|
||||
- “PARROT AR.Drone” or “PARROT AR.Drone” or « PARROT Drone» means the augmented reality drone developed by PARROT, without pilot, remote-controlled by a mobile phone, a console game, a computer or any other electronic device;
|
||||
- « Interoperability »: means the ability of an application to exchange information with the Parrot AR.Drone or any it’s accessories;
|
||||
- “ Game for AR.Drone” : means a software or a video game, created by the Developer from the PARROT SDK and APIs or any modified version, and which functionalities shall exclusively be dedicated to the use of the PARROT AR.Drone for entertaining, game, leisure or training purpose or any other purpose compatible with the terms of the present license;
|
||||
- « License » means the present license of development and use of the API’s;
|
||||
- «PARROT SDK and APIs »: means the AR.Drone software development kit and AR.Drone APIs and associated documentation, allowing to pilot the PARROT AR.Drone, from a mobile phone, a console game, a computer or any other electronic device, and which source codes are provided for free to the Developer;
|
||||
- « Developer » means a physical person, of age, having the capacity to accept the terms of the present License or a person, representing a company and having all powers to that effect to bind the company;
|
||||
- “PARROT AR.Drone” or “PARROT AR.Drone” or « PARROT Drone» means the augmented reality drone developed by PARROT, without pilot, remote-controlled by a mobile phone, a console game, a computer or any other electronic device;
|
||||
- « Interoperability »: means the ability of an application to exchange information with the Parrot AR.Drone or any it’s accessories;
|
||||
- “ Game for AR.Drone” : means a software or a video game, created by the Developer from the PARROT SDK and APIs or any modified version, and which functionalities shall exclusively be dedicated to the use of the PARROT AR.Drone for entertaining, game, leisure or training purpose or any other purpose compatible with the terms of the present license;
|
||||
- « License » means the present license of development and use of the API’s;
|
||||
- « User Account» means the information relating to the identification of a Developer, such as first name, surname, email address, login, password, company, title;
|
||||
- « User »: means any physical person using the PARROT Drone or a Game for AR.Drone.
|
||||
- « User »: means any physical person using the PARROT Drone or a Game for AR.Drone.
|
||||
|
||||
ARTICLE 3 – Identification
|
||||
3.1 The downloading of the API’s is subject to the Identification of the Developer by filling in the online registration form and accept the terms of the License by clicking the acceptance box on https://projects.ardrone.org .
|
||||
3.2 The Developer commits to provide accurate information and to update the information, if necessary.
|
||||
|
||||
3.3 The User Account is personal and confidential; it cannot be assigned to a third party.
|
||||
3.4 The User Account is personal and confidential; it cannot be assigned to a third party.
|
||||
|
||||
3.4 The Developer commits to inform PARROT immediately of any disclosure, non authorized use by a third party of the login and/or password of its User Account. In such case, PARROT shall be entitled to invalid the login and the password.
|
||||
3.5 The Developer commits to inform PARROT immediately of any disclosure, non authorized use by a third party of the login and/or password of its User Account. In such case, PARROT shall be entitled to invalid the login and the password.
|
||||
|
||||
|
||||
ARTICLE 4 – Conditions of Use
|
||||
Notwithstanding the limitation and restrictions mentioned in article 5, PARROT grants to the Developer, who accepts, a personal, non-assignable, non-exclusive, worldwide, free license of development of the PARROT SDK and APIs authorizing the Developer to:
|
||||
• reproduce, without number limitation, the API’s on any device under its responsibility, and necessary to create the Game for AR.Drone;
|
||||
• translate, adapt, arrange, modify the API’s in order to create a Game for AR.Drone in the software and hardware environment chosen by the Developer;
|
||||
• to market, for free or against fees, copies of the Game for AR.Drone created ;
|
||||
• to grant licenses of the Game for AR.Drone to the Users of the PARROT Drone.
|
||||
ARTICLE 4 – Conditions of Use
|
||||
Notwithstanding the limitation and restrictions mentioned in article 5, PARROT grants to the Developer, who accepts, a personal, non-assignable, non-exclusive, worldwide, free license of development of the PARROT SDK and APIs authorizing the Developer to:
|
||||
* reproduce, without number limitation, the API’s on any device under its responsibility, and necessary to create the Game for AR.Drone;
|
||||
* translate, adapt, arrange, modify the API’s in order to create a Game for AR.Drone in the software and hardware environment chosen by the Developer;
|
||||
* to market, for free or against fees, copies of the Game for AR.Drone created ;
|
||||
* to grant licenses of the Game for AR.Drone to the Users of the PARROT Drone.
|
||||
|
||||
|
||||
ARTICLE 5 – Restrictions to the license
|
||||
5.1 The License of development and use of the API’s is subject to the acceptance and to the respect by the Developer without any reserves of all restrictions and limitations listed hereafter:
|
||||
5.1 The License of development and use of the API’s is subject to the acceptance and to the respect by the Developer without any reserves of all restrictions and limitations listed hereafter:
|
||||
|
||||
Consequently, PARROT expressly forbids the Developer:
|
||||
(i) To access or use of the PARROT SDK and APIs from a technology or means others than those provided with the API’s;
|
||||
(ii) To market copies of the API’s, for free or against fees, and to distribute, sub-license, rent, sell, transfer, commercialize, publish or generally put the API’s to a third party disposal;
|
||||
(iii) To do reverse engineering, decompile or attempt to extract the Source Codes of the PARROT Drone; under special legal conditions, necessary information for interoperability purpose might be requested from PARROT ;
|
||||
(iv) To destroy, or alter any warning and copyrights notices;
|
||||
(v) To use the PARROT SDK and APIs to develop an application other than a Game for AR.Drone. The Game for AR.Drone, shall have for sole purpose to be used by a User for entertaining, game, leisure or training. The creation of applications for the use of the PARROT Drone for professional use or use such as but not limited to military, and, without limitation, security, watching, spying, defence, cartography, is strictly forbidden.
|
||||
(vi) To use the PARROT SDK and APIs or to create a Game for AR.Drone breaching the terms of:
|
||||
i. To do reverse engineering, decompile or attempt to extract the Source Codes of the PARROT Drone; under special legal conditions, necessary information for interoperability purpose might be requested from PARROT ;
|
||||
ii. To destroy, or alter any warning and copyrights notices;
|
||||
iii. To use the PARROT SDK and APIs to develop an application other than a Game for AR.Drone. The Game for AR.Drone shall have for sole purpose to be used by a User for entertaining, game, leisure or training. The creation of applications for the use of the PARROT AR.Drone for professional use or use such as but not limited to military, and, without limitation, security, watching, spying, defence, cartography, is strictly forbidden.
|
||||
iv. To use the PARROT SDK and APIs or to create a Game for AR.Drone breaching the terms of:
|
||||
(1) The License;
|
||||
(2) Third party rights;
|
||||
(3) Applicable laws and regulations;
|
||||
(4) Any instruction provided by PARROT.
|
||||
|
||||
5.2 Therefore, and without limitation, the Developer commits when using the API’s or when creating a Game for AR.Drone:
|
||||
a) not to infringe any applicable laws and regulation which the Developer shall determine whatever the country where he intends to develop and/or market the Game for AR.Drone ;
|
||||
b) not to reproduce, represent, put contents which infringe copyrights, patents, trademarks, design, model, know-how, commercial secret and any intellectual property rights belonging to PARROT or to third parties ;
|
||||
a) not to infringe any applicable laws and regulation which the Developer shall determine whatever the country where he intends to develop and/or market the Game for AR.Drone ;
|
||||
b) not to reproduce, represent, put contents which infringe copyrights, patents, trademarks, design, model, know-how, commercial secret and any intellectual property rights belonging to PARROT or to third parties ;
|
||||
c) not to falsify or remove copyrights, trademarks notices of any other proprietary rights of PARROT figuring in the Application;
|
||||
d) not to display a Game for AR.Drone which falsely or implied would suggest an endorsement or any approbation from PARROT ;
|
||||
e) not to collect or treat, or store, with the Game for AR.Drone, personal data from third, especially User of the Game for AR.Drone without having previously asked for their consent. Shall the Game for AR.Drone store personal data, it should be in compliance with the applicable law
|
||||
|
||||
5.3 PARROT is sole judge of the compliance of the Game for AR.Drone with the terms and conditions of the present License.
|
||||
|
||||
5.4 PARROT reserves the right to correct or modify the PARROT SDK and APIs during the License duration.
|
||||
5.5 PARROT reserves the right to correct or modify the PARROT SDK and APIs during the License duration.
|
||||
|
||||
ARTICLE 6 – Duration of the License
|
||||
|
||||
The License of the PARROT SDK and APIs is granted for the duration of the intellectual property rights of the Game for AR.Drone. It enters into force upon acceptance by the Developers by clicking the acceptance box or using a modified release of the PARROT SDK and APIs.
|
||||
The License of the PARROT SDK and APIs is granted for the duration of the intellectual property rights of the Game for AR.Drone. It enters into force upon acceptance by the Developers by clicking the acceptance box or using a modified release of the PARROT SDK and APIs.
|
||||
|
||||
|
||||
ARTICLE 7 – Termination of the License
|
||||
|
||||
7.1 PARROT reserves the right to terminate the present License, without notice, in following cases:
|
||||
7.1. Termination of the License
|
||||
7.1.1 PARROT reserves the right to terminate the present License, without notice, in following cases:
|
||||
|
||||
i. The Developer has created a Game for AR.Drone in violation of the present License terms, any applicable law and regulation or PARROT has objective reasons to believe that the Game for AR.Drone is infringing the License or any applicable law and regulation ;
|
||||
ii. The Developer has created a Game for AR.Drone in violation of PARROT’s intellectual property rights or PARROT has objective reasons to believe that the Game for AR.Drone is infringing it’s rights ;
|
||||
iii. The Developer has created a Game for AR.Drone in violation of a third party’s intellectual property rights or PARROT has objective reasons to believe that the Game for AR.Drone is infringing a third party’s rights ;
|
||||
iv. The Developer has created a Game for AR.Drone containing bugs, viruses, worms, defects, Trojan horses, or any items of a destructive nature or PARROT has objective reasons to believe that the Game for AR.Drone contains of this item;
|
||||
i. The Developer has created a Game for AR.Drone in violation of the present License terms, any applicable law and regulation or PARROT has objective reasons to believe that the Game for AR.Drone is infringing the License or any applicable law and regulation ;
|
||||
ii. The Developer has created a Game for AR.Drone in violation of PARROT’s intellectual property rights or PARROT has objective reasons to believe that the Game for AR.Drone is infringing it’s rights ;
|
||||
iii. The Developer has created a Game for AR.Drone in violation of a third party’s intellectual property rights or PARROT has objective reasons to believe that the Game for AR.Drone is infringing a third party’s rights ;
|
||||
iv. The Developer has created a Game for AR.Drone containing bugs, viruses, worms, defects, Trojan horses, or any items of a destructive nature or PARROT has objective reasons to believe that the Game for AR.Drone contains of this item;
|
||||
|
||||
7.2 Termination of the License shall be notified by email to any user breaching the terms of the License.
|
||||
7.1.2 Termination of the License shall be notified by email to any user breaching the terms of the License.
|
||||
|
||||
7.3 In case of closing of a User Account or termination of the License, for whatever reason, articles which by their nature shall survive shall continue to be applicable, in particular articles 11.RIGHTS OF PARROT; 12.DISCLAIMER; 13.LIMITATION OF RESPONSIBILITY; 14.INDEMNITY; 17.GENERALS PROVISIONS.
|
||||
7.1.3 In case of closing of a User Account or termination of the License, for whatever reason, articles which by their nature shall survive shall continue to be applicable, in particular articles 11.RIGHTS OF PARROT; 12.EXCLUSION OF WARRANTIES; 13.LIMITATION OF RESPONSIBILITY; 14.INDEMNITY; 15.GENERALS TERMS.
|
||||
|
||||
ARTICLE 8 – Specific Development
|
||||
|
||||
Upon request of a video game editor, PARROT may perform specific development of the PARROT SDK and APIs, in order to enable the creation of a Game for AR.Drone for commercial purpose by such editor. The development services provide by PARROT shall be subject to a separate agreement between PARROT and the editor. PARROT and the editor shall share the revenues gained from the sale of games created thanks to the specific development for an amount to be determined by agreement between the parties.
|
||||
Upon request of a video game editor, PARROT may perform specific development of the PARROT SDK and APIs, in order to enable the creation of a Game for AR.Drone for commercial purpose by such editor. The development services provide by PARROT shall be subject to a separate agreement between PARROT and the editor. PARROT and the editor shall share the revenues gained from the sale of games created thanks to the specific development for an amount to be determined by agreement between the parties.
|
||||
|
||||
|
||||
ARTICLE 9 – Upgrade of the API’s
|
||||
ARTICLE 9 – Upgrade of the API’s
|
||||
9.1 Due to technological innovations and for quality and/ or security reasons, the Developer acknowledges and agrees that PARROT may at any time modify the API’s, namely by adjunction, removal, improvement of functionalities, or that PARROT may temporarily or definitely suspend the access to the API’s, at its sole discretion and without notice. PARROT warrants – as far as possible and with no result obligation, the ascendant compatibility of the API’s.
|
||||
|
||||
9.2 PARROT shall notify any modification by publication on https://projects.ardrone.org, or per email, or by any other appropriate mean in PARROT judgment. From the notification, the use of the API’s by the Developer to create new Game for AR.Drone shall be deemed as the acceptance by the Developer of the modified License of the PARROT SDK and APIs.
|
||||
9.2 PARROT shall notify any modification by publication on https://projects.ardrone.org, or per email, or by any other appropriate mean in PARROT judgment. From the notification, the use of the API’s by the Developer to create new Game for AR.Drone shall be deemed as the acceptance by the Developer of the modified License of the PARROT SDK and APIs.
|
||||
|
||||
|
||||
|
||||
|
||||
ARTICLE 10 – License granted to Parrot by the Developper
|
||||
10.1 The Developer is owner of all copyrights and other intellectual property rights on the Game for AR.Drone that he creates. If the Developer is posting his Game for AR.Drone on https://projects.ardrone.org , he grants PARROT a perpetual, irrevocable, worldwide, free and non-exclusive license to reproduce, represent, adapt, arrange , modify, translate, publish, operate and display the Game for AR.Drone by any means of communication, numerical, analogical, electronic..to the public and namely by any network(internet, intranet), wireless or not, by mobile phone, email, by satellite, par optical fibre, par television and on any media.
|
||||
10.1 The Developer is owner of all copyrights and other intellectual property rights on the Game for AR.Drone that he creates. If the Developer is posting his Game for AR.Drone on https://projects.ardrone.org , he grants PARROT a perpetual, irrevocable, worldwide, free and non-exclusive license to reproduce, represent, adapt, arrange , modify, translate, publish, operate and display the Game for AR.Drone by any means of communication, numerical, analogical, electronic..to the public and namely by any network(internet, intranet), wireless or not, by mobile phone, email, by satellite, par optical fibre, par television and on any media.
|
||||
|
||||
10.2 This license shall be granted in order to allow PARROT to display, promote, and distribute the PARROT SDK and APIs and/or the PARROT AR.Drone.
|
||||
10.2 This license shall be granted in order to allow PARROT to display, promote, and distribute the PARROT SDK and APIs and/or the PARROT AR.Drone.
|
||||
|
||||
10.3 This license includes the right for PARROT to make the Game for AR.Drone available – totally or partially – to any Users of the AR.DRONE PARROT or to any person with who PARROT is in relationship, and to use the Game for AR.Drone for information or advertisement purpose.
|
||||
10.3 This license includes the right for PARROT to make the Game for AR.Drone available – totally or partially – to any Users of the AR.DRONE PARROT or to any person with who PARROT is in relationship, and to use the Game for AR.Drone for information or advertisement purpose.
|
||||
|
||||
10.4 The Developer agrees that PARROT for technical or for improvement purpose, may (a) transmit or communicate the Game for AR.Drone on public network others than internet (wireless or not, namely mobile telephony) and various media (graphic, magnetic, optical, numerical, analogical); and (b) make any modification necessary to adapt and make the Game for AR.Drone compliant to technical specifications so to make it interoperable with networks or devices.
|
||||
|
||||
@@ -128,103 +125,119 @@ ARTICLE 10
|
||||
|
||||
ARTICLE 11: Parrot Rights
|
||||
11.1 Intellectual and industrial property rights.
|
||||
PARROT is and remains the owner of all rights and interests on the PARROT SDK and APIs and on the PARROT AR.Drone, including without limitation all rights of intellectual and industrial property (copyrights, database rights, patents, trademark, design and model, semi-conductor topography) and/or any rights on the know-how, schemes, plans, algorythme, technologies, ideas, concepts.
|
||||
PARROT is and remains the owner of all rights and interests on the PARROT SDK and APIs and on the PARROT AR.Drone, including without limitation all rights of intellectual and industrial property (copyrights, database rights, patents, trademark, design and model, semi-conductor topography) and/or any rights on the know-how, schemes, plans, algorythme, technologies, ideas, concepts.
|
||||
|
||||
It is expressly specified that PARROT is owner of patents on the PARROT AR.Drone and that a right to use such patent is granted within the frame of the present License. No other rights on the patents are granted to the Developer who commits no to use the technologies issued from those patents for purpose not in the scope of the present License.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
11.2 Trademarks and logos.
|
||||
11.2.1 PARROT is owner of the intellectual property rights on its commercial trade name, trademarks, logos, domain names and any others brand features. PARROT grants the Developer a non-exclusive, non assignable, non transferable, non sub-licensable, free license to use PARROT trademarks and logos for the sole purpose of mentioning that he uses the PARROT SDK and APIs.
|
||||
11.2.1 PARROT is owner of the intellectual property rights on its commercial trade name, trademarks, logos, domain names and any others brand features. PARROT grants the Developer a non-exclusive, non assignable, non transferable, non sub-licensable, free license to use PARROT trademarks and logos for the sole purpose of mentioning that he uses the PARROT SDK and APIs.
|
||||
|
||||
11.2.2 When using PARROT’s trademarks and logos, the Developer undertakes:
|
||||
i. Not to display a trademark or a logo in any manner that implies a relationship or affiliation with, sponsorship, or endorsement by PARROT or that can be reasonably interpreted to suggest editorial content has been authored by, or represents the views or opinions of PARROT;
|
||||
ii. Not to use PARROT brand features to disparage PARROT or its products;
|
||||
iii. Not to display a trademark or a logo on its website if it contains or displays adult content or promotes illegal activities, gambling, or the sale of tobacco or alcohol to persons under eighteen (18) years of age;
|
||||
iv. Not to display the PARROT trademark and logo as the most prominent element in any part of the Game for AR.Drone created by the Developer or its packaging;
|
||||
v. Not to display the PARROT logo as the most prominent logo in the Game for AR.Drone ;
|
||||
vi. Not to display PARROT trademark or logo in a manner that is misleading, defamatory, infringing, libelous, disparaging, obscene or otherwise objectionable to PARROT;
|
||||
vii. Not to display a PARROT trademark or logo on a site that violates any law or regulation ;
|
||||
viii. Not to remove, distort or alter any element of a PARROT brand feature (including squeezing, stretching, inverting, discoloring, etc.).
|
||||
i. Not to display a trademark or a logo in any manner that implies a relationship or affiliation with, sponsorship, or endorsement by PARROT or that can be reasonably interpreted to suggest editorial content has been authored by, or represents the views or opinions of PARROT;
|
||||
ii. Not to use PARROT brand features to disparage PARROT or its products;
|
||||
iii. Not to display a trademark or a logo on its website if it contains or displays adult content or promotes illegal activities, gambling, or the sale of tobacco or alcohol to persons under eighteen (18) years of age;
|
||||
iv. Not to display the PARROT trademark and logo as the most prominent element in any part of the Game for AR.Drone created by the Developer or its packaging;
|
||||
v. Not to display the PARROT logo as the most prominent logo in the Game for AR.Drone ;
|
||||
vi. Not to display PARROT trademark or logo in a manner that is misleading, defamatory, infringing, libelous, disparaging, obscene or otherwise objectionable to PARROT;
|
||||
vii. Not to display a PARROT trademark or logo on a site that violates any law or regulation ;
|
||||
viii. Not to remove, distort or alter any element of a PARROT brand feature (including squeezing, stretching, inverting, discoloring, etc.).
|
||||
|
||||
11.3 The Developer undertakes during the term of the License and after its expiration, not to register or attempt to register any trademark, logo, domain name similar to or confusing with PARROT trademark or logo, in any manner (phonetic, intellectual, visual). PARROT reserves the right to sue for counterfeiting and unfair competition, any Developer who would not respect this commitment and use the trademarks and/or domain name PARROT AR.DRONE OU AR.DRONE in breach of the License.
|
||||
|
||||
11.4 The Developer undertakes to immediately remedy to any breach notified by PARROT per email or any other mean concerning any infringement to PARROT intellectual property rights.
|
||||
|
||||
11.5 The Developer, company or physical person, is owner, as applicable, on the intellectual property rights on his name, commercial name, trademarks, logos and any other brand features. He expressly grants PARROT a non exclusive, worldwide and free license to mention his name, commercial name, trademarks, logos, as applicable, to mention that he uses the PARROT SDK and APIs and/or that he has created a Game for AR.Drone.
|
||||
11.5 The Developer, company or physical person, is owner, as applicable, on the intellectual property rights on his name, commercial name, trademarks, logos and any other brand features. He expressly grants PARROT a non exclusive, worldwide and free license to mention his name, commercial name, trademarks, logos, as applicable, to mention that he uses the PARROT SDK and APIs and/or that he has created a Game for AR.Drone.
|
||||
|
||||
|
||||
ARTICLE 12: DISCLAIMER
|
||||
12.1 THE PARROT SDK AND APIs IS PROVIDED «AS IS ». IN PARTICULAR, PARROT, IT’S SUBSIDIARIES, LICENSORS AND THEIR SUPPLIERS, DO NOT REPRESENT OR WARRANT THE DEVELOPER THAT:
|
||||
12.1 THE PARROT SDK AND APIs IS PROVIDED «AS IS ». IN PARTICULAR, PARROT, IT’S SUBSIDIARIES, LICENSORS AND THEIR SUPPLIERS, DO NOT REPRESENT OR WARRANT THE DEVELOPER THAT:
|
||||
1. ITS USE OF THE API’s WILL MEET ITS REQUIREMENTS;
|
||||
2. ITS USE OF THE API’s WILL BE UNINTERRUPTED, TIMELY, SECURE OR FREE FROM ERROR OR WILL OFFER CONSTANT PERFORMANCE;
|
||||
3. THAT DEFECTS OR ERRORS WILL BE CORRECTED OR THAT THE API’s WILL BE UPGRADE, PARROT HAVING NO OBLIGATION TO PROVIDE CURATIVE OR EVOLUTIVE SUPPORT;
|
||||
4. THE API’s IS COMPLIANT TO ANY SPECIFICATIONS;
|
||||
5. ANY UPGRADE OF THE PARROT SDK AND APIs WILL BE COMPATIBLE WITH PREVIOUS RELEASE.
|
||||
|
||||
5. ANY UPGRADE OF THE PARROT SDK AND APIs WILL BE COMPATIBLE WITH PREVIOUS RELEASE.
|
||||
|
||||
12.2 PARROT, ITS SUBSIDIARIES, LICENSORS AND THEIR SUPPLIERS, DO NOT REPRESENT OR WARRANT THE DEVELOPER THAT ITS USER ACCOUNT WILL BE AVAILABLE WITHOUT INTERRUPTION.
|
||||
|
||||
12.3 NO ADVICE OR INFORMATION, WHETHER ORAL OR WRITTEN, OBTAINED BY THE DEVELOPER FROM PARROT, ITS SUBSIDIARERIES, OR THROUGH THE API’s, SHALL BE CONSTRUED A WARRANTY PROVIDED BY PARROT.
|
||||
|
||||
12.4 PARROT, IT’S SUBSIDIARIES, ITS LICENSORS DO NOT WARRANT, ANY RESULT, EXPRESS OR IMPLIED, OF ANY NATURE (TECHNICAL, COMMERCIAL, FINANCIAL OR OTHER) FROM THE USE OF THE APPLICATION.
|
||||
|
||||
12.5 PARROT DECLARES THAT TO THE BEST OF ITS KNOWLEDGE THE PARROT SDK AND APIs DOES NOT INFRINGE ANY THIRD PARTY INTELLECTUAL PROPERTY RIGHTS.
|
||||
12.5 PARROT DECLARES THAT TO THE BEST OF ITS KNOWLEDGE THE PARROT SDK AND APIs DOES NOT INFRINGE ANY THIRD PARTY INTELLECTUAL PROPERTY RIGHTS.
|
||||
|
||||
|
||||
ARTICLE 13: LIMITATION OF RESPONSABILITY
|
||||
13.1 THE PROVISION EXCLUSING OR LIMITING PARROT’S LIABILITY SHALL ONLY BE APPLICABLE IN COUNTRIES WHERE SUCH PROVISIONS ARE LEGAL. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF CERTAIN WARRANTIES OR THE LIMITATION OR EXCLUSION OF LIABILITY FOR CERTAIN TYPES OF LOSS OR DAMAGES. ACCORDINGLY, PARROT’S LIABILITY WILL BE LIMITED TO THE MAXIMUM EXTENT PERMITTED BY LAW.
|
||||
|
||||
|
||||
|
||||
|
||||
13.2 THE DEVELOPER EXPRESSLY ACKNOWLEDGES AND AGREES THAT THE USE HE DOES OF ITS USER ACCOUNT, THE API’s, THE GAME FOR AR.DRONE THAT HE CREATES, ARE AT ITS SOLE RISK AND RESPONSABILITY. IN PARTICULAR, THE DEVELOPER SHALL BE SOLELY RESPONSIBLE FOR ANY DAMAGE TO ITS COMPUTER SYSTEM OR OTHER DEVICE, LOSS OF DATA, OR ANY OTHER DAMAGE OR INJURY THAT RESULTS FROM THE DOWNLOAD OR USE OF THE API’s.
|
||||
|
||||
13.3 THE DEVELOPER EXPRESSLY ACKNOWLEDGES AND AGREES THAT HE SHALL BE SOLELY RESPONSIBLE FOR ALL COSTS, EXPENSES INCURRING FOR THE USE OF ITEMS MENTIONED ABOVE AS WELL AS ANY DEVELOPMENT AND PRODUCTION COSTS ASSOCIATED TO THE GAME OF AR.DRONE THAT HE IS CREATING.
|
||||
|
||||
13.4 PARROT, ITS SUPPLIERS, LICENSORS, AFFILIATES, ARE NOT RESPONSIBLE FOR ANY DIRECTS OR INDIRECTS, MATERIALS OR IMMATERIALS, CONSECUTIVES OR NON CONSECUTIVES DAMAGES, INCLUDING, BUT NOT BE LIMITED TO, ANY LOSS OF PROFIT (WHETHER INCURRED DIRECTLY OR INDIRECTLY), ANY LOSS OF GOODWILL OR BUSINESS REPUTATION, ANY LOSS OF DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR OTHER INTANGIBLE LOSS, THAT DEVELOPER OR A THIRD PARTY MAY INCURR FROM:
|
||||
|
||||
1- THE USE BY THE DEVELOPER OF ITS USER ACCOUNT, THE PARROT SDK AND APIs, THE GAME FOR AR.DRONE THAT HE CREATES;
|
||||
1- THE USE BY THE DEVELOPER OF ITS USER ACCOUNT, THE PARROT SDK AND APIs, THE GAME FOR AR.DRONE THAT HE CREATES;
|
||||
2- THE MARKETING OF THE GAME FOR AR.DRONE FOR FREE OR AGAINST FEES;
|
||||
3- THE MODIFICATION OF THE API’s BY PARROT;
|
||||
4- THE CLOSING OF THE USER ACCOUNT, THE MODIFICATION OR THE EXPIRATION OR TERMINATION OF THE LICENSE;
|
||||
5- ANY NON ACCURATE OR NON UPDATED INFORMATION PROVIDED BY PARROT,
|
||||
|
||||
|
||||
|
||||
ARTICLE 14: INDEMNITY
|
||||
ARTICLE 15: Indemnification
|
||||
The Developer warrants and hereby agrees to indemnify, defend and hold PARROT harmless from and against any claim or liability arising out of: (a) the use of the API’s in breach of the License and/or any instruction provided by PARROT; (b) the Game for AR.Drone; (c) any use by Users of the Game for AR.Drone; (d) any claim that the Game for AR.Drone breaches laws or infringes third party rights; consequently, assume all costs and damages to which PARROT could be condemned by a jurisdiction on such a basis. The Developer shall cooperate as fully as reasonably required in the defence of any claim and PARROT reserves the right, at its own expense, to assume the exclusive defence and control of any matter subject to indemnification by the Developer. And if necessary, to seek equitable relief, including but not limited to preliminary injunction and injunction, in addition to all other remedies.
|
||||
|
||||
ARTICLE 15: Hyperlinks
|
||||
15.1. The https://project.ardrone.org ardrone.org website may include hyperlinks to other web sites or content or resources provided by third parties and companies. PARROT has no control or authority over any web sites, resources, third parties. The Developer acknowledges and agrees that PARROT is not responsible for the availability of any such external sites or resources, and does not endorse any advertising, products or other materials on or available from such web sites or resources.
|
||||
ARTICLE 16: Hyperlinks
|
||||
16.1. The https://project.ardrone.org ardrone.org website may include hyperlinks to other web sites or content or resources provided by third parties and companies. PARROT has no control or authority over any web sites, resources, third parties. The Developer acknowledges and agrees that PARROT is not responsible for the availability of any such external sites or resources, and does not endorse any advertising, products or other materials on or available from such web sites or resources.
|
||||
|
||||
15.2. The Developer acknowledges and agrees that PARROT is not liable for any loss or damage that may be incurred by the Developer as a result of the availability of those external sites or resources, or as a result of any reliance placed by you on the completeness, accuracy or existence of any advertising, products, or other materials on, or available from, such web sites or resources.
|
||||
16.2. The Developer acknowledges and agrees that PARROT is not liable for any loss or damage that may be incurred by the Developer as a result of the availability of those external sites or resources, or as a result of any reliance placed by you on the completeness, accuracy or existence of any advertising, products, or other materials on, or available from, such web sites or resources.
|
||||
|
||||
|
||||
ARTICLE 16: Language and interpretation
|
||||
16.1 The English version of the License shall prevail over any translation, which might only be provided for convenience purpose. Therefore any translation might be provided only for convenience purpose.
|
||||
ARTICLE 17: Language and interpretation
|
||||
17.1 The English version of the License shall prevail over any translation, which might only be provided for convenience purpose. Therefore any translation might be provided only for convenience purpose.
|
||||
|
||||
16.2 If there is any contradiction between the English language version of the License and a translation of the License, the English language version will take precedence.
|
||||
17.2 If there is any contradiction between the English language version of the License and a translation of the License, the English language version will take precedence.
|
||||
|
||||
16.3 Titles are provided for convenience purpose only; the content of an article shall have precedence on the title.
|
||||
17.3 Titles are provided for convenience purpose only; the content of an article shall have precedence on the title.
|
||||
|
||||
ARTICLE 17: General provisions
|
||||
17.1 The License constitutes the entire legal agreement between Parrot and the Developer and completely replace and supersede any prior agreements between PARROT and the Developer.
|
||||
ARTICLE 18: General provisions
|
||||
18.1 The License constitutes the entire legal agreement between Parrot and the Developer and completely replace and supersede any prior agreements between PARROT and the Developer.
|
||||
|
||||
17.2 The waiver by PARROT to prevail itself from a provision of the License shall not be construed as a waiver to prevail itself of any right obligation under the License in the future.
|
||||
18.2 The waiver by PARROT to prevail itself from a provision of the License shall not be construed as a waiver to prevail itself of any right obligation under the License in the future.
|
||||
|
||||
17.3 If any court of law having jurisdiction rules that any provision of this License is invalid, then that provision will be removed from the License without affecting the rest of the License. The remaining provisions of the License will continue to be valid and enforceable.
|
||||
18.3 If any court of law having jurisdiction rules that any provision of this License is invalid, then that provision will be removed from the License without affecting the rest of the License. The remaining provisions of the License will continue to be valid and enforceable.
|
||||
|
||||
17.4 Any notice sent by PARROT to the Developer or exchange between the Parties will be validly delivered per email at the address provided by the Developer in its User Account and at legal@ardrone.org for PARROT.
|
||||
18.4 Any notice sent by PARROT to the Developer or exchange between the Parties will be validly delivered per email at the address provided by the Developer in its User Account and at legal@ardrone.org for PARROT.
|
||||
|
||||
ARTICLE 18: Applicable law and jurisdiction
|
||||
|
||||
ARTICLE 19: Applicable law and jurisdiction
|
||||
The License is governed by French Law, without regard to its conflict of Laws provisions. Any dispute arising out of its interpretation, execution or termination shall be submitted to the exclusive jurisdiction of the relevant court of Paris, even for urgency proceedings or plurality of defendants. Notwithstanding this, PARROT shall be allowed to apply for injunctive remedies (or an equivalent type of urgent legal relief) in any jurisdiction
|
||||
|
||||
|
||||
ARTICLE 19 - Privacy
|
||||
19.1 All information about our privacy policy are provided on www.parrot.com . This policy explains how PARROT treats any personal data which are disclosed to her and protect your privacy.
|
||||
ARTICLE 20 - Privacy
|
||||
20.1 All information about our privacy policy are provided on www.parrot.com . This policy explains how PARROT treats any personal data which are disclosed to her and protect your privacy.
|
||||
|
||||
19.2 The Developer agrees that PARROT may use its personal data in compliance with its privacy policy.
|
||||
20.2 The Developer agrees that PARROT may use its personal data in compliance with its privacy policy.
|
||||
|
||||
|
||||
ARTICLE 20 – Acceptance of the license
|
||||
By clicking the acceptance box, downloading or using the PARROT SDK and APIs or an adapted or modified release of the PARROT SDK and APIs, the Developer or any user accepts without reserve all terms and conditions of the License concluded between him and PARROT SA – registered under N° 394 149 496 and located 174 quai de Jemmapes FRANCE - which he commits to respect.
|
||||
ARTICLE 21 – Acceptance of the license
|
||||
By clicking the acceptance box, downloading or using the PARROT SDK and APIs or an adapted or modified release of the PARROT SDK and APIs, the Developer or any user accepts without reserve all terms and conditions of the License concluded between him and PARROT SA – registered under N° 394 149 496 and located 174 quai de Jemmapes FRANCE - which he commits to respect.
|
||||
|
||||
|
||||
|
||||
Last update: November 2010
|
||||
Document revision V2.0
|
||||
Last update: June 2011
|
||||
Document revision V2.1
|
||||
|
||||
|
||||
|
||||
|
||||
1
|
||||
|
||||
PARROT SA – Capital 1 961 863,21 € - RCS B 394 149 496 – 174 QUAI DE JEMMAPES 75010 FRANCE
|
||||
|
||||
|
||||
|
||||
+444
-4
@@ -1,7 +1,447 @@
|
||||
ardrone_brown_mod
|
||||
=================
|
||||
# ardrone_autonomy : A ROS Driver for ARDrone 1.0 & 2.0
|
||||
|
||||
The fork of ardrone_brown ROS driver from
|
||||
"ardrone_autonomy" is a [ROS](http://ros.org/ "Robot Operating System") driver for [Parrot AR-Drone](http://http://ardrone.parrot.com/parrot-ar-drone/select-site) quadrocopter. This driver is based on official [AR-Drone SDK](https://projects.ardrone.org/) version 2.0 and supports both AR-Drone 1.0 and 2.0. "ardrone_autonomy" is a fork of [AR-Drone Brown](http://code.google.com/p/brown-ros-pkg/wiki/ardrone_brown) driver. This package has been developed in [Autonomy Lab](http://autonomy.cs.sfu.ca) of [Simon Fraser University](http://www.sfu.ca) by [Mani Monajjemi](http://sfu.ca/~mmonajje) ( +other [contributors](#contributors)).
|
||||
|
||||
http://brown-ros-pkg.googlecode.com/svn/trunk/experimental/ardrone_brown --revision 2775
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Updates](#updates)
|
||||
- [Installation](#installation)
|
||||
- [Pre-requirements](#pre-requirements)
|
||||
- [Installation Steps](#installation-steps)
|
||||
- [How to Run](#how-to-run)
|
||||
- [Reading from AR-Drone](#reading-from-ar-drone)
|
||||
- [Update Frequencies ](#update-frequencies-new)
|
||||
- [Legacy Navigation Data](#legacy-navigation-data)
|
||||
- [IMU data](#imu-data)
|
||||
- [Magnetometer Data](#magnetometer-data)
|
||||
- [Selective Navdata (Advanced) ](#selective-navdata-advanced-new)
|
||||
- [Cameras](#cameras)
|
||||
- [Tag Detection](#tag-detection)
|
||||
- [Update Frequencies](#update-frequencies)
|
||||
- [Sending Commands to AR-Drone](#sending-commands-to-ar-drone)
|
||||
- [Hover Modes ](#hover-modes-new) :new:
|
||||
- [Coordinate Frames](#coordinate-frames)
|
||||
- [Services](#services)
|
||||
- [Toggle AR-Drone's Camera](#toggle-ar-drones-camera)
|
||||
- [LED Animations](#led-animations)
|
||||
- [Flight Animations ](#flight-animations-new)
|
||||
- [IMU Calibration](#imu-calibration)
|
||||
- [Flat Trim](#flat-trim)
|
||||
- [Record to USB Stick](#record-to-usb-stick) :new:
|
||||
- [Parameters](#parameters)
|
||||
- [AR-Drone Specific Parameters](#ar-drone-specific-parameters)
|
||||
- [Other Parameters](#other-parameters)
|
||||
- [License](#license)
|
||||
- [Contributors](#contributors)
|
||||
- [FAQ](#faq) :new:
|
||||
|
||||
|
||||
|
||||
## Updates
|
||||
|
||||
- *October 22 2013*: Update to Parrot SDK 2.0.1 (Fixes crashes on 2.4.x firmwares, no support for flight recorder (yet). **Please check the FAQ section for instructions on how to re-compile the SDK**. (Tested on 2.3.3 and 2.4.x firmwares)
|
||||
- *February 13 2013*: Support for USB key recording ([More info](https://github.com/AutonomyLab/ardrone_autonomy/pull/53)). Motor PWM added to legacy Navdata.
|
||||
- *January 9 2013*: ROS Groovy support. Support for zero-command without hovering ([More info](https://github.com/AutonomyLab/ardrone_autonomy/pull/34)). Full configurable Navdata support ([More info](https://github.com/AutonomyLab/ardrone_autonomy/pull/31)). Support for "Flight Animations". Support for Real-time navdata and video publishing ([More info](https://github.com/AutonomyLab/ardrone_autonomy/pull/44)). Support for configurable data publishing rate.
|
||||
- *November 9 2012*: Critical Bug in sending configurations to drone fixed and more parameters are supported ([More info](https://github.com/AutonomyLab/ardrone_autonomy/issues/24)). Separate topic for magnetometer data added ([More info](https://github.com/AutonomyLab/ardrone_autonomy/pull/25)).
|
||||
- *September 5 2012*: Experimental automatic IMU bias removal.
|
||||
- *August 27 2012*: Thread-safe SDK data access. Synchronized `navdata` and `camera` topics.
|
||||
- *August 20 2012*: The driver is now provides ROS standard camera interface.
|
||||
- *August 17 2012*: Experimental `tf` support added. New published topic `imu`.
|
||||
- *August 1 2012*: Enhanced `Navdata` message. `Navdata` now includes magnetometer data, barometer data, temperature and wind information for AR-Drone 2. [Issue #2](https://github.com/AutonomyLab/ardrone_autonomy/pull/2)
|
||||
- *July 27 2012*: LED Animation Support added to the driver as a service
|
||||
- *July 19 2012*: Initial Public Release
|
||||
|
||||
## Installation
|
||||
|
||||
### Pre-requirements
|
||||
|
||||
This driver has been tested on Linux machines running Ubuntu 11.10, 12.04 & 12.10 (32 bit and 64 bit). However it should also work on any other mainstream Linux distribution. The driver has been tested on both ROS "electric" and "fuerte". The AR-Drone SDK has its own build system which usually handles system wide dependencies itself. The ROS package depends on these standard ROS packages: `roscpp`, `image_transport`, `sensor_msgs`, `tf`, `camera_info_manager` and `std_srvs`.
|
||||
|
||||
### Installation Steps
|
||||
|
||||
The installation follows the same steps needed usually to compile a ROS driver.
|
||||
|
||||
* Get the code: Clone (or download and unpack) the driver to your personal ROS stacks folder (e.g. ~/ros/stacks) and `cd` to it. Please make sure that this folder is in your `ROS_PACKAGE_PATH` environmental variable.
|
||||
|
||||
```bash
|
||||
$ cd ~/ros/stacks
|
||||
$ git clone https://github.com/AutonomyLab/ardrone_autonomy.git
|
||||
$ rosstack profile && rospack profile
|
||||
$ roscd ardrone_autonomy
|
||||
```
|
||||
|
||||
**NOTE (For advanced users):** Instead of the `master` branch you can use the `dev-unstable` branch for the latest _unstable_ code which may contain bug fixes or new features. This is the branch that all developments happen on. Please use this branch to submit pull requests.
|
||||
|
||||
* Compile the AR-Drone SDK: The driver contains a slightly patched version of AR-Drone 2.0 SDK which is located in `ARDroneLib` directory. To compile it, execute the `./build_sdk.sh`. Any system-wide dependency will be managed by the SDK's build script. You may be asked to install some packages during the installation procedure (e.g `daemontools`). You can verify the success of the SDK's build by checking the `lib` folder.
|
||||
|
||||
```bash
|
||||
$ ./build_sdk.sh
|
||||
$ [After a couple of minutes]
|
||||
$ ls ./lib
|
||||
|
||||
libavcodec.a libavformat.a libpc_ardrone_notool.a libvlib.a
|
||||
libavdevice.a libavutil.a libsdk.a
|
||||
libavfilter.a libpc_ardrone.a libswscale.a
|
||||
```
|
||||
|
||||
* Compile the driver: You can easily compile the driver by using `rosmake ardrone_autonomy` command.
|
||||
|
||||
## How to Run
|
||||
|
||||
The driver's executable node is `ardrone_driver`. You can either use `rosrun ardrone_autonomy ardrone_driver` or put it in a custom launch file with your desired parameters.
|
||||
|
||||
## Reading from AR-Drone
|
||||
|
||||
### Update Frequencies :new:
|
||||
|
||||
**Drone Update Frequencies**: The drone's data transmission update frequency depends on `navdata_demo` parameter. When it is 1, the transmission frequency will be 15Hz, otherwise it will be 200Hz. (`navdata_demo` is a numeric parameter not Boolean, so use 1 and 0 (not True/False) to set/unset it)
|
||||
|
||||
**Driver Update Frequencies**: The driver can operate in two modes: real-time or fixed rate. When the `realtime_navdata` parameter is set to True, the driver will publish the received information instantly. However when it is set to False, the driver will cache the most recent received data, then it will publish that at a fixed rate, configured by `looprate` parameter. The default configuration is: `realtime_navdata=False` and `looprate=50`.
|
||||
|
||||
Please note that if the `looprate` is smaller than the drone's transmission frequency, there will be data loss. The driver's start-up output shows the current configuration. You can also use `rostopic hz` command to check the publish rate of the driver.
|
||||
|
||||
<pre>
|
||||
# Default Setting - 50Hz non-realtime update, the drone transmission rate is 200Hz
|
||||
rosrun ardrone_autonomy ardrone_driver _realtime_navdata:=False _navdata_demo:=0
|
||||
|
||||
# 200Hz real-time update
|
||||
rosrun ardrone_autonomy ardrone_driver _realtime_navdata:=True _navdata_demo:=0
|
||||
|
||||
# 15Hz real-rime update
|
||||
rosrun ardrone_autonomy ardrone_driver _realtime_navdata:=True _navdata_demo:=1
|
||||
</pre>
|
||||
|
||||
### Legacy Navigation Data
|
||||
|
||||
Information received from the drone will be published to the `ardrone/navdata` topic. The message type is `ardrone_autonomy::Navdata` and contains the following information:
|
||||
|
||||
* `header`: ROS message header
|
||||
* `batteryPercent`: The remaining charge of the drone's battery (%)
|
||||
* `state`: The Drone's current state:
|
||||
* 0: Unknown
|
||||
* 1: Inited
|
||||
* 2: Landed
|
||||
* 3,7: Flying
|
||||
* 4: Hovering
|
||||
* 5: Test (?)
|
||||
* 6: Taking off
|
||||
* 8: Landing
|
||||
* 9: Looping (?)
|
||||
* `rotX`: Left/right tilt in degrees (rotation about the X axis)
|
||||
* `rotY`: Forward/backward tilt in degrees (rotation about the Y axis)
|
||||
* `rotZ`: Orientation in degrees (rotation about the Z axis)
|
||||
* `magX`, `magY`, `magZ`: Magnetometer readings (AR-Drone 2.0 Only) (TBA: Convention)
|
||||
* `pressure`: Pressure sensed by Drone's barometer (AR-Drone 2.0 Only) (TBA: Unit)
|
||||
* `temp` : Temperature sensed by Drone's sensor (AR-Drone 2.0 Only) (TBA: Unit)
|
||||
* `wind_speed`: Estimated wind speed (AR-Drone 2.0 Only) (TBA: Unit)
|
||||
* `wind_angle`: Estimated wind angle (AR-Drone 2.0 Only) (TBA: Unit)
|
||||
* `wind_comp_angle`: Estimated wind angle compensation (AR-Drone 2.0 Only) (TBA: Unit)
|
||||
* `altd`: Estimated altitude (mm)
|
||||
* `motor1..4`: Motor PWM values
|
||||
* `vx`, `vy`, `vz`: Linear velocity (mm/s) [TBA: Convention]
|
||||
* `ax`, `ay`, `az`: Linear acceleration (g) [TBA: Convention]
|
||||
* `tm`: Timestamp of the data returned by the Drone returned as number of micro-seconds passed since Drone's boot-up.
|
||||
|
||||
|
||||
**NOTE:** The legacy Navdata publishing can be disabled by setting the `enable_legacy_navdata` parameter to `False` (legacy navdata is enabled by default).
|
||||
|
||||
### IMU data
|
||||
|
||||
The linear acceleration, angular velocity and orientation from the `Navdata` is also published to a standard ROS [`sensor_msgs/Imu`](http://www.ros.org/doc/api/sensor_msgs/html/msg/Imu.html) message. The units are all metric and the reference frame is in `Base` frame. This topic is experimental. The covariance values are specified by specific parameters.
|
||||
|
||||
### Magnetometer Data
|
||||
|
||||
The normalized magnetometer readings are also published to `ardrone/mag` topic as a standard ROS [`geometry_msgs/Vector3Stamped`](http://www.ros.org/doc/api/geometry_msgs/html/msg/Vector3Stamped.html) message.
|
||||
|
||||
### Selective Navdata (Advanced) :new:
|
||||
|
||||
You can access almost all sensor readings, debug values and status reports sent from the AR-Drone by using "Selective Navdata". If you set any of following parameters to "True", their corresponding `Navdata` information will be published to a separate topic. For example if you enable `enable_navdata_time`, the driver will publish AR-Drone time information to `ardrone/navdata_time` topic. Most of the names are self-explanatory. Please consult AR-Drone SDK 2.0's documentation (or source code) for more information. All parameters are set to False by default.
|
||||
|
||||
<pre>
|
||||
enable_navdata_trims enable_navdata_rc_references enable_navdata_pwm enable_navdata_altitude
|
||||
enable_navdata_vision_raw enable_navdata_vision_of enable_navdata_vision enable_navdata_vision_perf
|
||||
enable_navdata_trackers_send enable_navdata_vision_detect enable_navdata_watchdog enable_navdata_adc_data_frame
|
||||
enable_navdata_video_stream enable_navdata_games enable_navdata_pressure_raw enable_navdata_magneto
|
||||
enable_navdata_wind_speed enable_navdata_kalman_pressure enable_navdata_hdvideo_stream enable_navdata_wifi enable_navdata_zimmu_3000
|
||||
</pre>
|
||||
|
||||
**HINT:** You can `rostopic type ardrone/navdata_time | rosmsg show` command for each topic to inspect its published message's data structure.
|
||||
|
||||
### Cameras
|
||||
|
||||
Both AR-Drone 1.0 and 2.0 are equipped with two cameras. One frontal camera pointing forward and one vertical camera pointing downward. This driver will create three topics for each drone: `ardrone/image_raw`, `ardrone/front/image_raw` and `ardrone/bottom/image_raw`. Each of these three are standard [ROS camera interface](http://ros.org/wiki/camera_drivers) and publish messages of type [image transport](http://www.ros.org/wiki/image_transport). The driver is also a standard [ROS camera driver](http://www.ros.org/wiki/camera_drivers), therefor if camera calibration information is provided either as a set of ROS parameters or appropriate `ardrone_front.yaml` and/or `ardrone_bottom.yaml`, the information will be published in appropriate `camera_info` topics. Please check the FAQ section for more information.
|
||||
|
||||
* The `ardrone/*` will always contain the selected camera's video stream and information.
|
||||
|
||||
* The way that the other two streams work depend on the type of Drone.
|
||||
|
||||
* Drone 1
|
||||
|
||||
Drone 1 supports four modes of video streams: Front camera only, bottom camera only, front camera with bottom camera inside (picture in picture) and bottom camera with front camera inside (picture in picture). According to active configuration mode, the driver decomposes the PIP stream and publishes pure front/bottom streams to corresponding topics. The `camera_info` topic will include the correct image size.
|
||||
|
||||
* Drone 2
|
||||
|
||||
Drone 2 does not support PIP feature anymore, therefore only one of `ardrone/front` or `ardrone/bottom` topics will be updated based on which camera is selected at the time.
|
||||
|
||||
### Tag Detection
|
||||
|
||||
The `Navdata` message also returns the special tags that are detected by the Drone's on-board vision processing system. To learn more about the system and the way it works please consult AR-Drone SDK 2.0's [developers guide](https://projects.ardrone.org/projects/show/ardrone-api/). These tags are being detected on both drone's video cameras on-board at 30fps. To configure (or disable) this feature look at the "Parameters" section in this documentation.
|
||||
|
||||
The detected tags' type and position in Drone's camera frame will be published to the following variables in `Navdata` message:
|
||||
|
||||
* `tags_count`: The number of detected tags.
|
||||
* `tags_type[]`: Vector of types of detected tags (details below)
|
||||
* `tags_xc[]`, `tags_yc[]`, `tags_width[]`, `tags_height[]`: Vector of position components and size components for each tag. These numbers are expressed in numbers between [0,1000]. You need to convert them back to pixel unit using the corresponding camera's resolution (can be obtained front `camera_info` topic).
|
||||
* `tags_orientation[]`: For the tags that support orientation, this is the vector that contains the tag orientation expressed in degrees [0..360).
|
||||
|
||||
By default, the driver will configure the drone to look for _oriented roundels_ using bottom camera and _2D tags v2_ on indoor shells (_orange-yellow_) using front camera. For information on how to extract information from `tags_type` field. Check the FAQ section in the end.
|
||||
|
||||
### Update Frequencies
|
||||
|
||||
TBA.
|
||||
|
||||
## Sending Commands to AR-Drone
|
||||
|
||||
The drone will *takeoff*, *land* or *emergency stop/reset* by publishing an `Empty` ROS messages to the following topics: `ardrone/takeoff`, `ardrone/land` and `ardrone/reset` respectively.
|
||||
|
||||
In order to fly the drone after takeoff, you can publish a message of type [`geometry_msgs::Twist`](http://www.ros.org/doc/api/geometry_msgs/html/msg/Twist.html) to the `cmd_vel` topic.
|
||||
|
||||
-linear.x: move backward
|
||||
+linear.x: move forward
|
||||
-linear.y: move right
|
||||
+linear.y: move left
|
||||
-linear.z: move down
|
||||
+linear.z: move up
|
||||
|
||||
-angular.z: turn left
|
||||
+angular.z: turn right
|
||||
|
||||
The range for each component should be between -1.0 and 1.0. The maximum range can be configured using ROS parameters discussed later in this document.
|
||||
|
||||
### Hover Modes :new:
|
||||
|
||||
`geometry_msgs::Twist` has two other member variable called `angular.x` and `angular.y` which can be used to enable/disable "auto-hover" mode. "auto-hover" is enabled when all six components are set to **zero**. If you want the drone not to enter "auto hover" mode in cases you set the first four components to zero, set `angular.x` and `angular.y` to arbitrary **non-zero** values.
|
||||
|
||||
## Coordinate Frames
|
||||
|
||||
The driver publishes two [`tf`](http://www.ros.org/wiki/tf) transforms between three reference frames: `${tf_prefix}/${base_prefix}_link`, `${tf_prefix}/${base_prefix}_frontcam` and `${tf_prefix}/${base_prefix}_bottomcam`. The `${tf_prefix}` is ROS standard way to handle multi-robot `tf` trees and can be set using `tf_prefix` parameters, by default it is empty. The `${base_link}` is the shared name prefix of all three reference frames and can also be set using parameters, by default it has the value of `ardrone_base`. Using default parameters, the three frames would be: `ardrone_base_link`, `ardrone_base_frontcam` and `ardrone_base_bottomcam`. By default the root frame is `ardrone_base_link`. Therefor `ardrone_base_frontcam` and `ardrone_base_bottomcam` are children of `ardrone_base_link` in the published `tf` tree. This can be changed using `root_frame` parameter.
|
||||
|
||||
The `frame_id` field in header of all published topics (navdata, imu, cameras) will have the appropriate frame names. All frames are [ROS REP 103](http://www.ros.org/reps/rep-0103.html) compatible.
|
||||
|
||||
## Services
|
||||
|
||||
### Toggle AR-Drone's Camera
|
||||
|
||||
Calling `ardrone/togglecam` service with no parameters will change the active video camera stream. (e.g `rosservice call /ardrone/togglecam`).
|
||||
|
||||
`ardrone/setcamchannel` service directly sets the current active camera channel. One parameter (`uint8 channel
|
||||
`) should be sent to this service. For AR-Drone 1.0 the valid values are [0..3] and for AR-Drone 2.0 the valid values are [0..1]. The order is similar to the order described in "Cameras" section.
|
||||
|
||||
### LED Animations
|
||||
|
||||
Calling `ardrone/setledanimation` service will invoke one of 14 pre-defined LED animations for the drone. The parameters are
|
||||
|
||||
* `uint8 type`: The type of animation which is a number in range [0..13]
|
||||
* `float32 freq`: The frequency of the animation in Hz
|
||||
* `uint8 duration`: The duration of the animation in Seconds.
|
||||
|
||||
The `type` parameter will map [in order] to one of these animations (check `srv/LedAnim.srv` for more details):
|
||||
|
||||
BLINK_GREEN_RED, BLINK_GREEN, BLINK_RED, BLINK_ORANGE,
|
||||
SNAKE_GREEN_RED, FIRE, STANDARD, RED, GREEN, RED_SNAKE,BLANK,
|
||||
LEFT_GREEN_RIGHT_RED, LEFT_RED_RIGHT_GREEN, BLINK_STANDARD`
|
||||
|
||||
You can test these animations in command line using commands like `rosservice call /ardrone/setledanimation 1 4 5`
|
||||
|
||||
### Flight Animations :new:
|
||||
|
||||
Calling `ardrone/setflightanimation` service will execute one of 20 pre-defined flight animations for the drone. The parameters are:
|
||||
|
||||
* `uint8 type`: The type of flight animation, a number in range [0..19]
|
||||
* `uint16 duration`: The duration of the animation. Use 0 for default duration (recommended)
|
||||
|
||||
The `type` parameter will map [in order] to one of these pre-defined animations (check `srv/FlightAnim.srv` for more details):
|
||||
|
||||
ARDRONE_ANIM_PHI_M30_DEG, ARDRONE_ANIM_PHI_30_DEG, ARDRONE_ANIM_THETA_M30_DEG, ARDRONE_ANIM_THETA_30_DEG,
|
||||
ARDRONE_ANIM_THETA_20DEG_YAW_200DEG, ARDRONE_ANIM_THETA_20DEG_YAW_M200DEG, ARDRONE_ANIM_TURNAROUND,
|
||||
ARDRONE_ANIM_TURNAROUND_GODOWN, ARDRONE_ANIM_YAW_SHAKE, ARDRONE_ANIM_YAW_DANCE, ARDRONE_ANIM_PHI_DANCE,
|
||||
ARDRONE_ANIM_THETA_DANCE, ARDRONE_ANIM_VZ_DANCE, ARDRONE_ANIM_WAVE, ARDRONE_ANIM_PHI_THETA_MIXED,
|
||||
ARDRONE_ANIM_DOUBLE_PHI_THETA_MIXED, ARDRONE_ANIM_FLIP_AHEAD, ARDRONE_ANIM_FLIP_BEHIND, ARDRONE_ANIM_FLIP_LEFT,
|
||||
ARDRONE_ANIM_FLIP_RIGHT
|
||||
|
||||
You can test these animations in command line using commands like `rosservice call /ardrone/setflightanimation 1 0` while drone is flying.
|
||||
|
||||
Please be extra cautious about using animations, especially flip animations.
|
||||
|
||||
### IMU Calibration
|
||||
|
||||
If `do_imu_caliberation` parameter is set to true, calling `ardrone/imu_recalib` service will make the driver recalculate the biases in IMU data based on data from a short sampling period.
|
||||
|
||||
### Flat Trim
|
||||
|
||||
Calling `ardrone/flattrim` service without any parameter will send a "Flat Trim" request to AR-Drone to re-calibrate its rotation estimates assuming that it is on a flat surface. Do not call this service while Drone is flying or while the drone is not actually on a flat surface.
|
||||
|
||||
### Record to USB Stick
|
||||
|
||||
Calling `ardrone/setrecord` service will enable and disable recording to the USB stick. The service takes a simple `1` to enable or `0` to disable. So you can turn on recording to the USB stick with `rosservice call /ardrone/setrecord 1`
|
||||
|
||||
## Parameters
|
||||
|
||||
### AR-Drone Specific Parameters
|
||||
|
||||
The parameters listed below are named according to AR-Drone's SDK 2.0 configuration. Unless you set the parameters using `rosparam` or in your `launch` file, the default values will be used. These values are applied during driver's initialization phase. Please refer to AR-Drone SDK 2.0's [developer's guide](https://projects.ardrone.org/projects/show/ardrone-api/) for information about valid values. Not all the parameters will be needed during regular usage of the AR-Drone, please consult the example launch file `launch/ardrone.launch` for frequent parameters.
|
||||
|
||||
altitude, altitude_max, altitude_min, ardrone_name, autonomous_flight, bitrate, bitrate_ctrl_mode,
|
||||
bitrate_storage, codec_fps, com_watchdog, control_iphone_tilt, control_level, control_vz_max,
|
||||
control_yaw, detect_type, detections_select_h, detections_select_v, detections_select_v_hsync,
|
||||
enemy_colors, enemy_without_shell, euler_angle_max, flight_anim, flight_without_shell, flying_mode,
|
||||
groundstripe_colors, hovering_range, indoor_control_vz_max, indoor_control_yaw, indoor_euler_angle_max,
|
||||
latitude, leds_anim, longitude, manual_trim, max_bitrate, max_size, navdata_demo, navdata_options,
|
||||
nb_files, outdoor, outdoor_control_vz_max, outdoor_control_yaw, outdoor_euler_angle_max, output,
|
||||
owner_mac, ssid_multi_player, ssid_single_player, travelling_enable, travelling_mode, ultrasound_freq,
|
||||
ultrasound_watchdog, userbox_cmd, video_channel, video_codec, video_enable, video_file_index,
|
||||
video_live_socket, video_on_usb, video_slices, vision_enable, wifi_mode, wifi_rate
|
||||
|
||||
[This wiki page](https://github.com/AutonomyLab/ardrone_autonomy/wiki/AR-Drone-Parameters) includes more information about each of above parameters.
|
||||
|
||||
### Other Parameters
|
||||
|
||||
These parameters control the behaviour of the driver.
|
||||
|
||||
* `drone_frame_id` - The "frame_id" prefix to be used in all `tf` frame names - default: "ardrone_base"
|
||||
* `root_frame` - The default root in drone's `tf` tree (0: _link, 1: _frontcam, 2: _bottomcam) - Default: 0
|
||||
* `cov/imu_la`, `cov/imu_av` & `cov/imu_or`: List of 9 covariance values to be used in `imu`'s topic linear acceleration, angular velocity and orientation fields respectively - Default: 0.0 for all members (Please check the FAQ section for a sample launch file that shows how to set these values)
|
||||
* `do_imu_calibration`: [EXPERIMENTAL] Should the drone cancel the biases in IMU data - Default: 0
|
||||
* `enable_legacy_navdata`: Enable legacy `Navdata` publish - Default: True
|
||||
|
||||
## License
|
||||
|
||||
The Parrot's license, copyright and disclaimer for `ARDroneLib` are included with the package and can be found in `ParrotLicense.txt` and `ParrotCopyrightAndDisclaimer.txt` files respectively. The other parts of the code are subject to `BSD` license.
|
||||
|
||||
## Contributors
|
||||
|
||||
[List of all commiters to the repository](http://autonomylab.org/ardrone_autonomy/contribution.html).
|
||||
|
||||
- [Mike Hamer](https://github.com/mikehamer) - Added support for proper SDK2 way of configuring the Drone via parameter (critical bug fix) ([More Info](https://github.com/AutonomyLab/ardrone_autonomy/pull/26)). Support for zero-command without hovering ([More info](https://github.com/AutonomyLab/ardrone_autonomy/pull/34)). Full configurable Navdata support ([More info](https://github.com/AutonomyLab/ardrone_autonomy/pull/31)). Support for Real-time navdata and video publishing ([More info](https://github.com/AutonomyLab/ardrone_autonomy/pull/44)). Support for configurable data publishing rate.
|
||||
- [Jacokb Engel](https://github.com/JakobEngel)
|
||||
- [Sameer Parekh](https://github.com/sameerparekh) - [Turn on and off USB stick recording](https://github.com/AutonomyLab/ardrone_autonomy/pull/53) - [Seperate Magnetometer Topic](https://github.com/AutonomyLab/ardrone_autonomy/pull/25)
|
||||
- [Devmax](https://github.com/devmax) - [Flat Trim](https://github.com/AutonomyLab/ardrone_autonomy/issues/18) + Various
|
||||
comments for enhancements
|
||||
- [Rachel Brindle](https://github.com/younata) - [Enhanced Navdata for AR-Drone 2.0](https://github.com/AutonomyLab/ardrone_autonomy/pull/2)
|
||||
|
||||
## FAQ
|
||||
|
||||
### Where should I go next? Is there any ROS package or stack that can be used as a tutorial/sample to use ardrone_autonomy?
|
||||
|
||||
Absolutely. Here are some examples:
|
||||
|
||||
- [falkor_ardrone](https://github.com/FalkorSystems/falkor_ardrone)
|
||||
|
||||
"falkor_ardrone" is a ROS package which uses the "ardrone_autonomy" package to implement autonomous control functionality on an AR.Drone.
|
||||
|
||||
- [tum_ardrone](http://www.ros.org/wiki/tum_ardrone)
|
||||
|
||||
State Estimation, Autopilot and GUI for ardrone.
|
||||
|
||||
- [arl_ardrone_examples](https://github.com/parcon/arl_ardrone_examples)
|
||||
|
||||
This ROS stack includes a series of very basic nodes to show users how to develop applications that use the ardrone_autonomy drivers for the AR drone 1.0 and 2.0 quadrotor robot.
|
||||
|
||||
- [AR Drone Tutorials](https://github.com/mikehamer/ardrone_tutorials)
|
||||
|
||||
This repository contains the source-code for the Up and flying with the AR.Drone and ROS tutorial series, published on [Robohub](http://www.robohub.org).
|
||||
|
||||
|
||||
### How can I report a bug, submit patches or ask for a feature?
|
||||
|
||||
`github` offers a nice and convenient issue tracking and social coding platform, it can be used for bug reports and pull/feature request. This is the preferred method. You can also contact the author directly.
|
||||
|
||||
If you want to submit a pull request, please submit to `dev-unstable` branch.
|
||||
|
||||
### Why the `ARDroneLib` has been patched?
|
||||
|
||||
The ARDrone 2.0 SDK has been patched to 1) Enable the lib only build 2) Make its command parsing compatible with ROS and 3) To fix its weird `main()` function issue
|
||||
|
||||
### Why the wifi bandwidth usage is too much?
|
||||
|
||||
The driver has been configured by default to use the maximum bandwidth allowed to ensure the best quality video stream possible (please take a look at default values in parameters section). That is the reason why the picture quality received from Drone 2.0 using this driver is far better than what you usually get using other software. If for any reason you prefer the lower quality* video stream, change `bitrate_ctrl_mode`, `max_bitrate` and `bitrate` parameters to the default values provided by the AR-Drone developer guide.
|
||||
|
||||
(*) Please note that lower quality does not mean lower resolution. By configuring AR-Drone to use bitrate control with limits, the picture gets blurry when there is a movement.
|
||||
|
||||
### What is the default configuration for the front camera video stream?
|
||||
|
||||
_Drone 1_: 320x240@15fps UVLC Codec
|
||||
_Drone 2_: 640x360@20fps H264 codec with no record stream
|
||||
|
||||
### How can I extract camera information and tag type from `tags_type[]`?
|
||||
|
||||
`tag_type` contains information for both source and type of each detected tag. In order to extract information from them you can use the following c macros and enums (taken from `ardrone_api.h`)
|
||||
|
||||
```c++
|
||||
#define DETECTION_EXTRACT_SOURCE(type) ( ((type)>>16) & 0x0FF )
|
||||
#define DETECTION_EXTRACT_TAG(type) ( (type) & 0x0FF )
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DETECTION_SOURCE_CAMERA_HORIZONTAL=0, /*<! Tag was detected on the front camera picture */
|
||||
DETECTION_SOURCE_CAMERA_VERTICAL, /*<! Tag was detected on the vertical camera picture at full speed */
|
||||
DETECTION_SOURCE_CAMERA_VERTICAL_HSYNC, /*<! Tag was detected on the vertical camera picture inside the horizontal pipeline */
|
||||
DETECTION_SOURCE_CAMERA_NUM,
|
||||
} DETECTION_SOURCE_CAMERA;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TAG_TYPE_NONE = 0,
|
||||
TAG_TYPE_SHELL_TAG ,
|
||||
TAG_TYPE_ROUNDEL ,
|
||||
TAG_TYPE_ORIENTED_ROUNDEL ,
|
||||
TAG_TYPE_STRIPE ,
|
||||
TAG_TYPE_CAP ,
|
||||
TAG_TYPE_SHELL_TAG_V2 ,
|
||||
TAG_TYPE_TOWER_SIDE ,
|
||||
TAG_TYPE_BLACK_ROUNDEL ,
|
||||
TAG_TYPE_NUM
|
||||
} TAG_TYPE;
|
||||
|
||||
```
|
||||
|
||||
### How can I calibrate the ardrone front/bottom camera?
|
||||
|
||||
It is easy to calibrate both cameras using ROS [Camera Calibration](http://www.ros.org/wiki/camera_calibration) package.
|
||||
|
||||
First, run the camera_calibration node with appropriate arguments: (For the bottom camera, replace front with bottom)
|
||||
|
||||
```bash
|
||||
rosrun camera_calibration cameracalibrator.py --size [SIZE] --square [SQUARESIZE] image:=/ardrone/front/image_raw camera:=/ardrone/front
|
||||
```
|
||||
|
||||
After successful calibration, press the `commit` button in the UI. The driver will receive the data from the camera calibration node, then will save the information by default in `~/.ros/camera_info/ardrone_front.yaml`. From this point on, whenever you run the driver on the same computer this file will be loaded automatically by the driver and its information will be published to appropriate `camera_info` topic. Sample calibration files for AR-Drone 2.0's cameras are provided in `data/camera_info` folder.
|
||||
|
||||
### Can I see a sample ardrone node in a launch file to learn how to set parameters?
|
||||
|
||||
Yes, you can check the `launch` folder for sample lanuch file.
|
||||
|
||||
### Can I control multiple drones using a single PC? or can I make my drone connect to a wireless router?
|
||||
|
||||
With some hacking yes! This [wiki page](https://github.com/AutonomyLab/ardrone_autonomy/wiki/Multiple-AR-Drones) contains some information regarding this issue.
|
||||
|
||||
### How to re-compile parrot SDK?
|
||||
|
||||
If the `git` updates include a SDK upgrade, you'd better cleanup previous vuild files.
|
||||
|
||||
```bash
|
||||
cd ARDroneLib/Soft/Build
|
||||
make clean
|
||||
rm -rf targets_versions
|
||||
```
|
||||
|
||||
Build the SDK and driver again.
|
||||
|
||||
## TODO
|
||||
|
||||
* Make the `tf` publish optional.
|
||||
* Add the currently selected camera name to `Navdata`
|
||||
* [DONE] Add separate topic for drone's debug stream (`navdata_demo`)
|
||||
* [DONE] Make the `togglecam` service accept parameters
|
||||
* [DONE] Enrich `Navdata` with magneto meter and baro meter information
|
||||
|
||||
Arquivo executável
+5
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
rm -rf ./lib
|
||||
rm -rf ARDroneLib/Soft/Build/targets_versions
|
||||
mkdir ./lib
|
||||
make -f sdk.makefile
|
||||
@@ -0,0 +1,20 @@
|
||||
image_width: 640
|
||||
image_height: 360
|
||||
camera_name: ardrone_bottom
|
||||
camera_matrix:
|
||||
rows: 3
|
||||
cols: 3
|
||||
data: [700.490828918144, 0, 319.508832099787, 0, 701.654116650887, 218.740253550967, 0, 0, 1]
|
||||
distortion_model: plumb_bob
|
||||
distortion_coefficients:
|
||||
rows: 1
|
||||
cols: 5
|
||||
data: [0.0182389759532889, 0.0520276742502367, 0.00651075732801101, 0.000183496184521575, 0]
|
||||
rectification_matrix:
|
||||
rows: 3
|
||||
cols: 3
|
||||
data: [1, 0, 0, 0, 1, 0, 0, 0, 1]
|
||||
projection_matrix:
|
||||
rows: 3
|
||||
cols: 4
|
||||
data: [706.46533203125, 0, 319.100033140348, 0, 0, 704.728332519531, 219.675699140967, 0, 0, 0, 1, 0]
|
||||
@@ -0,0 +1,20 @@
|
||||
image_width: 640
|
||||
image_height: 360
|
||||
camera_name: ardrone_front
|
||||
camera_matrix:
|
||||
rows: 3
|
||||
cols: 3
|
||||
data: [569.883158064802, 0, 331.403348466206, 0, 568.007065238522, 135.879365106014, 0, 0, 1]
|
||||
distortion_model: plumb_bob
|
||||
distortion_coefficients:
|
||||
rows: 1
|
||||
cols: 5
|
||||
data: [-0.526629354780687, 0.274357114262035, 0.0211426202132638, -0.0063942451330052, 0]
|
||||
rectification_matrix:
|
||||
rows: 3
|
||||
cols: 3
|
||||
data: [1, 0, 0, 0, 1, 0, 0, 0, 1]
|
||||
projection_matrix:
|
||||
rows: 3
|
||||
cols: 4
|
||||
data: [463.275726318359, 0, 328.456687172518, 0, 0, 535.977355957031, 134.693732992726, 0, 0, 0, 1, 0]
|
||||
@@ -0,0 +1,27 @@
|
||||
<!-- This is a sample lanuch file, please change it based on your needs -->
|
||||
<launch>
|
||||
<node name="ardrone_driver" pkg="ardrone_autonomy" type="ardrone_driver" output="screen" clear_params="true">
|
||||
<param name="outdoor" value="1" />
|
||||
<param name="max_bitrate" value="4000" />
|
||||
<param name="bitrate" value="4000" />
|
||||
<param name="navdata_demo" value="0" />
|
||||
<param name="flight_without_shell" value="0" />
|
||||
<param name="altitude_max" value="3000" />
|
||||
<param name="altitude_min" value="50" />
|
||||
<param name="euler_angle_max" value="0.21" />
|
||||
<param name="control_vz_max" value="700" />
|
||||
<param name="control_yaw" value="1.75" />
|
||||
<param name="detect_type" value="10" />
|
||||
<param name="enemy_colors" value="3" />
|
||||
<param name="detections_select_h" value="32" />
|
||||
<param name="detections_select_v_hsync" value="128" />
|
||||
<param name="enemy_without_shell" value="0" />
|
||||
<param name="do_imu_caliberation" value="false" />
|
||||
<param name="tf_prefix" value="mydrone" />
|
||||
<!-- Covariance Values (3x3 matrices reshaped to 1x9)-->
|
||||
<rosparam param="cov/imu_la">[0.1, 0.0, 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.1]</rosparam>
|
||||
<rosparam param="cov/imu_av">[1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0]</rosparam>
|
||||
<rosparam param="cov/imu_or">[1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 100000.0]</rosparam>
|
||||
</node>
|
||||
</launch>
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
<!-- This is a sample lanuch file, please change it based on your needs -->
|
||||
<launch>
|
||||
<node name="ardrone_driver" pkg="ardrone_autonomy" type="ardrone_driver" output="screen" clear_params="true">
|
||||
|
||||
<!-- Modifies the drone's onboard parameters. If not specified, drone default will be used (consult SDK or ardrone_autonomy wiki) -->
|
||||
<param name="outdoor" value="1" />
|
||||
<param name="flight_without_shell" value="1" />
|
||||
<param name="navdata_demo" value="0" />
|
||||
|
||||
<param name="max_bitrate" value="2000" />
|
||||
<param name="bitrate" value="2000" />
|
||||
<param name="video_codec" value="129" />
|
||||
|
||||
<param name="altitude_max" value="5000" />
|
||||
<param name="altitude_min" value="300" />
|
||||
|
||||
<param name="control_vz_max" value="2000" />
|
||||
<param name="control_yaw" value="6.11" />
|
||||
<param name="euler_angle_max" value="0.35" />
|
||||
|
||||
<param name="detect_type" value="10" />
|
||||
<param name="detections_select_h" value="128" />
|
||||
<param name="detections_select_v_hsync" value="32" />
|
||||
<param name="enemy_colors" value="3" />
|
||||
<param name="enemy_without_shell" value="0" />
|
||||
<param name="do_imu_caliberation" value="false" />
|
||||
<param name="tf_prefix" value="mydrone" />
|
||||
|
||||
<!-- Enables the standard /ardrone/navdata, imu and mag topics. If not specified, defaults to TRUE -->
|
||||
<param name="enable_legacy_navdata" value="true" />
|
||||
|
||||
<!-- Enables the new-style, full information navdata packets. If not specified, defaults to FALSE -->
|
||||
<param name="enable_navdata_demo" value="true" />
|
||||
<param name="enable_navdata_time" value="true" />
|
||||
<param name="enable_navdata_raw_measures" value="true" />
|
||||
<param name="enable_navdata_phys_measures" value="true" />
|
||||
<param name="enable_navdata_gyros_offsets" value="true" />
|
||||
<param name="enable_navdata_euler_angles" value="true" />
|
||||
<param name="enable_navdata_references" value="true" />
|
||||
<param name="enable_navdata_trims" value="true" />
|
||||
<param name="enable_navdata_rc_references" value="true" />
|
||||
<param name="enable_navdata_pwm" value="true" />
|
||||
<param name="enable_navdata_altitude" value="true" />
|
||||
<param name="enable_navdata_vision_raw" value="true" />
|
||||
<param name="enable_navdata_vision_of" value="true" />
|
||||
<param name="enable_navdata_vision" value="true" />
|
||||
<param name="enable_navdata_vision_perf" value="true" />
|
||||
<param name="enable_navdata_trackers_send" value="true" />
|
||||
<param name="enable_navdata_vision_detect" value="true" />
|
||||
<param name="enable_navdata_watchdog" value="true" />
|
||||
<param name="enable_navdata_adc_data_frame" value="true" />
|
||||
<param name="enable_navdata_video_stream" value="true" />
|
||||
<param name="enable_navdata_games" value="true" />
|
||||
<param name="enable_navdata_pressure_raw" value="true" />
|
||||
<param name="enable_navdata_magneto" value="true" />
|
||||
<param name="enable_navdata_wind_speed" value="true" />
|
||||
<param name="enable_navdata_kalman_pressure" value="true" />
|
||||
<param name="enable_navdata_hdvideo_stream" value="true" />
|
||||
<param name="enable_navdata_wifi" value="true" />
|
||||
<param name="enable_navdata_zimmu_3000" value="true" />
|
||||
|
||||
<!-- Tunes the speed at which the ros loop runs, and thus, the rate at which navdata is published -->
|
||||
<param name="looprate" value="50" />
|
||||
|
||||
<!-- Do we want to publish new-style navdata when received (true), or every time the ros-loop runs (false)? -->
|
||||
<!-- (does not affect legacy navdata, which is always published at ros-loop rate) -->
|
||||
<param name="realtime_navdata" value="true" />
|
||||
<param name="realtime_video" value="true" />
|
||||
|
||||
<!-- Covariance Values (3x3 matrices reshaped to 1x9)-->
|
||||
<rosparam param="cov/imu_la">[0.1, 0.0, 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.1]</rosparam>
|
||||
<rosparam param="cov/imu_av">[1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0]</rosparam>
|
||||
<rosparam param="cov/imu_or">[1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 100000.0]</rosparam>
|
||||
</node>
|
||||
</launch>
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
\mainpage
|
||||
\htmlinclude manifest.html
|
||||
|
||||
\b ardrone_brown is ...
|
||||
\b ardrone_autonomy is ...
|
||||
|
||||
<!--
|
||||
Provide an overview of your package.
|
||||
|
||||
+14
-9
@@ -1,19 +1,24 @@
|
||||
<package>
|
||||
<description brief="ardrone_brown">
|
||||
|
||||
A driver for the Parrot AR Drone developed by Brown University. It includes furll ROS support for both motion control and video.
|
||||
|
||||
<description brief="ardrone_autonomy">
|
||||
"ardrone_autonomy" is a ROS driver for Parrot AR-Drone quadrocopter.
|
||||
This driver is based on official AR-Drone SDK version 2.0 and supports both
|
||||
AR-Drone 1.0 and 2.0.
|
||||
"ardrone_autonomy" is a fork of AR-Drone Brown driver. This package has
|
||||
been developed in Autonomy Lab of Simon Fraser University
|
||||
</description>
|
||||
<author>Paul Kernfeld and Christopher Crick</author>
|
||||
<email>pkernfel@cs.brown.edu chriscrick@cs.brown.edu</email>
|
||||
<author>Mani Monajjemi</author>
|
||||
<email>mmonajje@cs.sfu.ca</email>
|
||||
<license>BSD</license>
|
||||
<review status="unreviewed" notes=""/>
|
||||
<url>http://ros.org/wiki/ardrone_brown</url>
|
||||
<url>http://ros.org/wiki/ardrone_autonomy</url>
|
||||
<export>
|
||||
<rosdoc config="rosdoc.yaml" />
|
||||
</export>
|
||||
<rosdep name="libsdl-dev" />
|
||||
<depend package="roscpp"/>
|
||||
<depend package="image_transport"/>
|
||||
<depend package="sensor_msgs"/>
|
||||
<depend package="std_srvs"/>
|
||||
<depend package="tf"/>
|
||||
<depend package="camera_info_manager"/>
|
||||
</package>
|
||||
|
||||
|
||||
|
||||
+29
-1
@@ -1,8 +1,31 @@
|
||||
Header header
|
||||
|
||||
# Navdata including the ARDrone 2 specifica sensors
|
||||
# (magnetometer, barometer)
|
||||
|
||||
# 0 means no battery, 100 means full battery
|
||||
float32 batteryPercent
|
||||
|
||||
# 0: Unknown, 1: Init, 2: Landed, 3: Flying, 4: Hovering, 5: Test
|
||||
# 6: Taking off, 7: Goto Fix Point, 8: Landing, 9: Looping
|
||||
# Note: 3,7 seems to discriminate type of flying (isFly = 3 | 7)
|
||||
uint32 state
|
||||
|
||||
int32 magX
|
||||
int32 magY
|
||||
int32 magZ
|
||||
|
||||
# pressure sensor
|
||||
int32 pressure
|
||||
|
||||
# apparently, there was a temperature sensor added as well.
|
||||
int32 temp
|
||||
|
||||
# wind sensing...
|
||||
float32 wind_speed
|
||||
float32 wind_angle
|
||||
float32 wind_comp_angle
|
||||
|
||||
# left/right tilt in degrees (rotation about the X axis)
|
||||
float32 rotX
|
||||
|
||||
@@ -29,6 +52,12 @@ float32 ax
|
||||
float32 ay
|
||||
float32 az
|
||||
|
||||
#motor commands (unit 0 to 255)
|
||||
uint8 motor1
|
||||
uint8 motor2
|
||||
uint8 motor3
|
||||
uint8 motor4
|
||||
|
||||
#Tags in Vision Detectoion
|
||||
uint32 tags_count
|
||||
uint32[] tags_type
|
||||
@@ -41,4 +70,3 @@ float32[] tags_distance
|
||||
|
||||
#time stamp
|
||||
float32 tm
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
float32 m11
|
||||
float32 m12
|
||||
float32 m13
|
||||
float32 m21
|
||||
float32 m22
|
||||
float32 m23
|
||||
float32 m31
|
||||
float32 m32
|
||||
float32 m33
|
||||
@@ -0,0 +1,6 @@
|
||||
Header header
|
||||
float64 drone_time
|
||||
uint16 tag
|
||||
uint16 size
|
||||
uint32 version
|
||||
uint8[] data_frame
|
||||
@@ -0,0 +1,14 @@
|
||||
Header header
|
||||
float64 drone_time
|
||||
uint16 tag
|
||||
uint16 size
|
||||
int32 altitude_vision
|
||||
float32 altitude_vz
|
||||
int32 altitude_ref
|
||||
int32 altitude_raw
|
||||
float32 obs_accZ
|
||||
float32 obs_alt
|
||||
vector31 obs_x
|
||||
uint32 obs_state
|
||||
vector21 est_vb
|
||||
uint32 est_state
|
||||
@@ -0,0 +1,15 @@
|
||||
Header header
|
||||
float64 drone_time
|
||||
uint16 tag
|
||||
uint16 size
|
||||
uint32 ctrl_state
|
||||
uint32 vbat_flying_percentage
|
||||
float32 theta
|
||||
float32 phi
|
||||
float32 psi
|
||||
int32 altitude
|
||||
float32 vx
|
||||
float32 vy
|
||||
float32 vz
|
||||
uint32 num_frames
|
||||
uint32 detection_camera_type
|
||||
@@ -0,0 +1,6 @@
|
||||
Header header
|
||||
float64 drone_time
|
||||
uint16 tag
|
||||
uint16 size
|
||||
float32 theta_a
|
||||
float32 phi_a
|
||||
@@ -0,0 +1,6 @@
|
||||
Header header
|
||||
float64 drone_time
|
||||
uint16 tag
|
||||
uint16 size
|
||||
uint32 double_tap_counter
|
||||
uint32 finish_line_counter
|
||||
@@ -0,0 +1,5 @@
|
||||
Header header
|
||||
float64 drone_time
|
||||
uint16 tag
|
||||
uint16 size
|
||||
float32[] offset_g
|
||||
@@ -0,0 +1,11 @@
|
||||
Header header
|
||||
float64 drone_time
|
||||
uint16 tag
|
||||
uint16 size
|
||||
uint32 hdvideo_state
|
||||
uint32 storage_fifo_nb_packets
|
||||
uint32 storage_fifo_size
|
||||
uint32 usbkey_size
|
||||
uint32 usbkey_freespace
|
||||
uint32 frame_number
|
||||
uint32 usbkey_remaining_time
|
||||
@@ -0,0 +1,21 @@
|
||||
Header header
|
||||
float64 drone_time
|
||||
uint16 tag
|
||||
uint16 size
|
||||
float32 offset_pressure
|
||||
float32 est_z
|
||||
float32 est_zdot
|
||||
float32 est_bias_PWM
|
||||
float32 est_biais_pression
|
||||
float32 offset_US
|
||||
float32 prediction_US
|
||||
float32 cov_alt
|
||||
float32 cov_PWM
|
||||
float32 cov_vitesse
|
||||
int32 bool_effet_sol
|
||||
float32 somme_inno
|
||||
int32 flag_rejet_US
|
||||
float32 u_multisinus
|
||||
float32 gaz_altitude
|
||||
int32 Flag_multisinus
|
||||
int32 Flag_multisinus_debut
|
||||
@@ -0,0 +1,18 @@
|
||||
Header header
|
||||
float64 drone_time
|
||||
uint16 tag
|
||||
uint16 size
|
||||
int16 mx
|
||||
int16 my
|
||||
int16 mz
|
||||
vector31 magneto_raw
|
||||
vector31 magneto_rectified
|
||||
vector31 magneto_offset
|
||||
float32 heading_unwrapped
|
||||
float32 heading_gyro_unwrapped
|
||||
float32 heading_fusion_unwrapped
|
||||
uint8 magneto_calibration_ok
|
||||
uint32 magneto_state
|
||||
float32 magneto_radius
|
||||
float32 error_mean
|
||||
float32 error_var
|
||||
@@ -0,0 +1,11 @@
|
||||
Header header
|
||||
float64 drone_time
|
||||
uint16 tag
|
||||
uint16 size
|
||||
float32 accs_temp
|
||||
uint16 gyro_temp
|
||||
float32[] phys_accs
|
||||
float32[] phys_gyros
|
||||
uint32 alim3V3
|
||||
uint32 vrefEpson
|
||||
uint32 vrefIDG
|
||||
@@ -0,0 +1,8 @@
|
||||
Header header
|
||||
float64 drone_time
|
||||
uint16 tag
|
||||
uint16 size
|
||||
int32 up
|
||||
int16 ut
|
||||
int32 Temperature_meas
|
||||
int32 Pression_meas
|
||||
@@ -0,0 +1,29 @@
|
||||
Header header
|
||||
float64 drone_time
|
||||
uint16 tag
|
||||
uint16 size
|
||||
uint8 motor1
|
||||
uint8 motor2
|
||||
uint8 motor3
|
||||
uint8 motor4
|
||||
uint8 sat_motor1
|
||||
uint8 sat_motor2
|
||||
uint8 sat_motor3
|
||||
uint8 sat_motor4
|
||||
float32 gaz_feed_forward
|
||||
float32 gaz_altitude
|
||||
float32 altitude_integral
|
||||
float32 vz_ref
|
||||
int32 u_pitch
|
||||
int32 u_roll
|
||||
int32 u_yaw
|
||||
float32 yaw_u_I
|
||||
int32 u_pitch_planif
|
||||
int32 u_roll_planif
|
||||
int32 u_yaw_planif
|
||||
float32 u_gaz_planif
|
||||
uint16 current_motor1
|
||||
uint16 current_motor2
|
||||
uint16 current_motor3
|
||||
uint16 current_motor4
|
||||
float32 altitude_der
|
||||
@@ -0,0 +1,19 @@
|
||||
Header header
|
||||
float64 drone_time
|
||||
uint16 tag
|
||||
uint16 size
|
||||
int16[] raw_gyros
|
||||
int16[] raw_gyros_110
|
||||
uint32 vbat_raw
|
||||
uint16 us_debut_echo
|
||||
uint16 us_fin_echo
|
||||
uint16 us_association_echo
|
||||
uint16 us_distance_echo
|
||||
uint16 us_courbe_temps
|
||||
uint16 us_courbe_valeur
|
||||
uint16 us_courbe_ref
|
||||
uint16 flag_echo_ini
|
||||
uint16 nb_echo
|
||||
uint32 sum_echo
|
||||
int32 alt_temp_raw
|
||||
int16 gradient
|
||||
@@ -0,0 +1,9 @@
|
||||
Header header
|
||||
float64 drone_time
|
||||
uint16 tag
|
||||
uint16 size
|
||||
int32 rc_ref_pitch
|
||||
int32 rc_ref_roll
|
||||
int32 rc_ref_yaw
|
||||
int32 rc_ref_gaz
|
||||
int32 rc_ref_ag
|
||||
@@ -0,0 +1,25 @@
|
||||
Header header
|
||||
float64 drone_time
|
||||
uint16 tag
|
||||
uint16 size
|
||||
int32 ref_theta
|
||||
int32 ref_phi
|
||||
int32 ref_theta_I
|
||||
int32 ref_phi_I
|
||||
int32 ref_pitch
|
||||
int32 ref_roll
|
||||
int32 ref_yaw
|
||||
int32 ref_psi
|
||||
float32 vx_ref
|
||||
float32 vy_ref
|
||||
float32 theta_mod
|
||||
float32 phi_mod
|
||||
float32 k_v_x
|
||||
float32 k_v_y
|
||||
uint32 k_mode
|
||||
float32 ui_time
|
||||
float32 ui_theta
|
||||
float32 ui_phi
|
||||
float32 ui_psi
|
||||
float32 ui_psi_accuracy
|
||||
int32 ui_seq
|
||||
@@ -0,0 +1,5 @@
|
||||
Header header
|
||||
float64 drone_time
|
||||
uint16 tag
|
||||
uint16 size
|
||||
uint32 time
|
||||
@@ -0,0 +1,6 @@
|
||||
Header header
|
||||
float64 drone_time
|
||||
uint16 tag
|
||||
uint16 size
|
||||
int32[] locked
|
||||
vector21[] point
|
||||
@@ -0,0 +1,7 @@
|
||||
Header header
|
||||
float64 drone_time
|
||||
uint16 tag
|
||||
uint16 size
|
||||
float32 angular_rates_trim_r
|
||||
float32 euler_angles_trim_theta
|
||||
float32 euler_angles_trim_phi
|
||||
@@ -0,0 +1,17 @@
|
||||
Header header
|
||||
float64 drone_time
|
||||
uint16 tag
|
||||
uint16 size
|
||||
uint8 quant
|
||||
uint32 frame_size
|
||||
uint32 frame_number
|
||||
uint32 atcmd_ref_seq
|
||||
uint32 atcmd_mean_ref_gap
|
||||
float32 atcmd_var_ref_gap
|
||||
uint32 atcmd_ref_quality
|
||||
uint32 desired_bitrate
|
||||
int32 data2
|
||||
int32 data3
|
||||
int32 data4
|
||||
int32 data5
|
||||
uint32 fifo_queue_level
|
||||
Alguns arquivos não foram exibidos porque demasiados arquivos foram alterados neste diff Mostrar Mais
Referência em uma Nova Issue
Bloquear um usuário