Upgrading to Parrot SDK 2.0.1

Esse commit está contido em:
Mani Monajjemi
2013-10-21 11:07:21 -07:00
commit a3f9cff1a6
68 arquivos alterados com 3072 adições e 3166 exclusões
+1 -1
Ver Arquivo
@@ -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.
+8 -8
Ver Arquivo
@@ -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
+1 -1
Ver Arquivo
@@ -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.
+1 -1
Ver Arquivo
@@ -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_
-16
Ver Arquivo
@@ -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
-51
Ver Arquivo
@@ -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
-1
Ver Arquivo
@@ -14,7 +14,6 @@
#include <win32_custom.h>
#else
#include <generated_custom.h>
#include <autoconf.h>
#endif
#undef ARDRONE_PIC_VERSION
-4
Ver Arquivo
@@ -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)
+1 -1
Ver Arquivo
@@ -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
+3 -4
Ver Arquivo
@@ -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;
+4 -4
Ver Arquivo
@@ -31,10 +31,10 @@ NAVDATA_OPTION( navdata_watchdog_t , navdata_watchdog , NAVDATA_WATC
NAVDATA_OPTION( navdata_adc_data_frame_t, navdata_adc_data_frame , NAVDATA_ADC_DATA_FRAME_TAG )
NAVDATA_OPTION( navdata_video_stream_t, navdata_video_stream , NAVDATA_VIDEO_STREAM_TAG )
NAVDATA_OPTION( navdata_games_t, navdata_games , NAVDATA_GAMES_TAG )
NAVDATA_OPTION( navdata_pressure_raw_t, navdata_pressure_raw , NAVDATA_PRESSURE_RAW_TAG )
NAVDATA_OPTION( navdata_magneto_t, navdata_magneto , NAVDATA_MAGNETO_TAG )
NAVDATA_OPTION( navdata_wind_speed_t, navdata_wind_speed , NAVDATA_WIND_TAG )
NAVDATA_OPTION( navdata_kalman_pressure_t,navdata_kalman_pressure , NAVDATA_KALMAN_PRESSURE_TAG )
NAVDATA_OPTION( navdata_pressure_raw_t, navdata_pressure_raw , NAVDATA_PRESSURE_RAW_TAG )
NAVDATA_OPTION( navdata_magneto_t, navdata_magneto , NAVDATA_MAGNETO_TAG )
NAVDATA_OPTION( navdata_wind_speed_t, navdata_wind_speed , NAVDATA_WIND_TAG )
NAVDATA_OPTION( navdata_kalman_pressure_t,navdata_kalman_pressure , NAVDATA_KALMAN_PRESSURE_TAG )
NAVDATA_OPTION( navdata_hdvideo_stream_t ,navdata_hdvideo_stream , NAVDATA_HDVIDEO_STREAM_TAG )
NAVDATA_OPTION( navdata_wifi_t ,navdata_wifi , NAVDATA_WIFI_TAG )
+4
Ver Arquivo
@@ -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)
+5 -4
Ver Arquivo
@@ -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);
}
+1 -1
Ver Arquivo
@@ -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;
}
case ACADEMY_RESULT_FAILED:
strncat(msg, "FAILED", DISPLAY_STRING_LENGTH - strlen (msg));
break;
}
if(strlen(msg) != 0)
PA_DEBUG("===========> %s\n", msg);
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;
while( academy_download_started && !shouldGoInPause)
{
academy_status = FTP_FAIL;
switch(academy.state.state)
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;
break;
case ACADEMY_STATE_CONNECTION:
if(academy_ftp == NULL)
academy_ftp = ftpConnect(&wifi_ardrone_ip[0], ACADEMY_PORT, "anonymous", "", &academy_status);
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(academy_ftp != NULL)
academy_status = FTP_SUCCESS;
break;
// If directory is empty, we consider that it is an error
if(academy_status == FTP_SAMESIZE)
academy_status = FTP_FAIL;
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(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(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(fileList != NULL)
{
vp_os_free(fileList);
fileList = NULL;
}
if(academy_ftp)
ftpClose(&academy_ftp);
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;
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;
retry = 0;
current_event = NULL;
DEBUG_PRINT_SDK("Thread control in progress...\n");
control_socket.is_disable = TRUE;
DEBUG_PRINT_SDK("Thread control in progress...\n");
control_socket.is_disable = TRUE;
ardrone_control_connect_to_drone();
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(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(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( 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( 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;
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;
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;
bool_t result = FALSE;
if(1 == ARDRONE_VERSION())
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;
PRINT("Userbox started\n");
navdata_state.userbox_state = USERBOX_STATE_STARTED;
switch (navdata_state.takeoff_state)
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,55 +391,55 @@ 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();
@@ -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;
navdata_state.wasEmergency = (pnd->ardrone_state & ARDRONE_EMERGENCY_MASK) ? TRUE : FALSE;
// Video record management
// 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(...)
@@ -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 */
@@ -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);
vlib_stage_decoding_open (cfg->vlibConf);
mp4h264_open (cfg->mp4h264Conf);
return C_OK;
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;
parrot_video_encapsulation_t *PaVE = (parrot_video_encapsulation_t *)buffer;
video_stage_decoder_lastDetectedCodec = PaVE->video_codec;
video_stage_decoder_lastDetectedCodec = PaVE->video_codec;
if (lastDecodedStreamID!=-1 && lastDecodedStreamID!=PaVE->stream_id)
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;
cfg->vlibConf->num_picture_decoded = cfg->num_picture_decoded;
retVal = vlib_stage_decoding_transform (cfg->vlibConf, in, cfg->vlibOut);
if (C_FAIL == retVal)
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->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->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;
parrot_video_encapsulation_t *PaVE = (parrot_video_encapsulation_t *)buffer;
cfg->mp4h264Conf->num_picture_decoded = cfg->num_picture_decoded;
cfg->mp4h264Conf->num_picture_decoded = cfg->num_picture_decoded;
retVal = mp4h264_transform (cfg->mp4h264Conf, in, cfg->mp4h264Out);
if (C_FAIL == retVal)
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->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->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);
vp_os_free (neonCheckStrBuf);
neonCheckStrBuf = NULL;
fclose (cpuInfo);
neonStatus = loc_neonStat;
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);
void (*recorder_callback)(video_stage_encoded_recorder_config_t*) = callback;
#ifndef USE_ELINUX
vp_os_mutex_lock (&cfg->videoMutex);
#endif
void (*recorder_callback)(video_stage_encoded_recorder_config_t*) = callback;
switch (msg_id)
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);
}
#ifndef USE_ELINUX
vp_os_mutex_unlock (&cfg->videoMutex);
#endif
vp_os_mutex_unlock (&cfg->videoMutex);
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, &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, &timestamp);
}
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 */
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;
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;
@@ -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;
@@ -399,6 +400,7 @@ C_RESULT ffmpeg_stage_decoding_transform(ffmpeg_stage_decoding_config_t *cfg, vp
packet.size = in->size;
FFMPEG_DEBUG("Size : %d", packet.size);
#ifdef NUM_SAMPLES
struct timeval end_time;
static float32_t frame_decoded_time = 0;
@@ -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;
}
+2 -4
Ver Arquivo
@@ -332,14 +332,11 @@ int ardrone_tool_main(int argc, char **argv)
argc--; argv++;
}
// Making the driver ROS compatible
/*
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();
}
+1 -1
Ver Arquivo
@@ -66,7 +66,7 @@ C_RESULT ardrone_tool_shutdown(void);
void ardrone_tool_init_timers_and_mutex();
void ardrone_tool_send_com_watchdog(void); // To send it only once
//int main();
int main();
// There because not defined in embedded
void api_configuration_get_ctrl_mode(void);
@@ -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
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+1
Ver Arquivo
@@ -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;
/**
+34 -34
Ver Arquivo
@@ -3,16 +3,16 @@
#include <utils/ardrone_time.h>
#if defined(_WIN32)
#include <sys/timeb.h>
#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;
}
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)
@@ -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;
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))
{
retVal = ardrone_timer_elapsed_us(&timer_current) - ardrone_timer_elapsed_us(timer);
}
}
return retVal;
}
+3
Ver Arquivo
@@ -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;
+327 -304
Ver Arquivo
@@ -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)
@@ -647,6 +669,7 @@ movie_atom_t *ardtAtomFromPathAndDroneVersion(const char *path, uint8_t droneVer
}
retAtom = atomFromData (dataSize, "ardt", data);
ATOM_FREE (data);
data = NULL;
}
// NO ELSE - malloc failed
@@ -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;
/* Slices recording values */
uint32_t lastFrameNumber;
parrot_video_encapsulation_frametypes_t lastFrameType;
uint32_t currentFrameSize;
vp_os_mutex_t mutex;
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);
+2
Ver Arquivo
@@ -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 )
+16 -9
Ver Arquivo
@@ -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,15 +307,15 @@ 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;
}
else
{
controller->last_frame_decoded = FALSE;
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;
}
p264_realloc_ref(controller);
@@ -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
+1 -1
Ver Arquivo
@@ -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];
+2 -2
Ver Arquivo
@@ -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;
+1
Ver Arquivo
@@ -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;
}
+1
Ver Arquivo
@@ -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 )
+5 -5
Ver Arquivo
@@ -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);
}
@@ -702,12 +702,12 @@ ATcodec_Send_Messages()
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;
res = ATCODEC_FALSE;
ATcodec_Message_len = 0;
ATcodec_Message_len = 0;
vp_os_mutex_unlock(&ATcodec_cond_mutex);
+1 -4
Ver Arquivo
@@ -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,9 +105,6 @@ define ADD_RULE_TEMPLATE
ifeq ($(USE_ANDROID),yes)
build_lib: build_$(1)
endif
ifeq ($(USE_LINUX), yes)
build_lib: build_$(1)
endif
endif
endif
endif
+1 -86
Ver Arquivo
@@ -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)
{
+3 -1
Ver Arquivo
@@ -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)
{
+13 -5
Ver Arquivo
@@ -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;
+13 -11
Ver Arquivo
@@ -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);
+3 -2
Ver Arquivo
@@ -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);