/* ===========================================================================
* Copyright (c) 2017-2022 Qualcomm Technologies, Inc.
* All Rights Reserved.
* Confidential and Proprietary - Qualcomm Technologies, Inc.
=========================================================================== */
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <unistd.h>
#include <time.h>
#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include <sys/select.h>
#include <queue>
#ifndef C2D_DISABLED
#include "c2d2.h"
#endif
#include "vendor_ext_properties.h"
#include "qcarcam.h"
#include "test_util.h"
#include "qcarcam_diag_types.h"
#ifdef POST_PROCESS
#include "post_process.h"
#endif
#define NUM_MAX_CAMERAS 28
#define NUM_MAX_DISP_BUFS 3
/*1sec delay before restart */
#define PAUSE_RESUME_USLEEP 1000000
#define START_STOP_USLEEP 1000000
/*print input state as frozen if start and no frames after 1 sec*/
#define QCARCAMTEST_SOF_FREEZE_TIMEOUT 1.0f
#define QCARCAM_TEST_DEFAULT_GET_FRAME_TIMEOUT 500000000
#define DEFAULT_PRINT_DELAY_SEC 10
#define SIGNAL_CHECK_DELAY 33333;
#define CSI_ERR_CHECK_DELAY 100000;
#define NS_TO_MS 0.000001F
#define QCARCAM_TEST_INPUT_INJECTION 11
#define BUFSIZE 10
#define SIGWAIT_TIMEOUT_MS 100
#define TIMER_THREAD_USLEEP 1000000
#define USR_PROCESS_THREAD_USLEEP 1000
#define USR_PROCESS_WAIT_USLEEP 1000
#if defined(__INTEGRITY)
#ifndef CLOCK_MONOTONIC
#define CLOCK_MONOTONIC CLOCK_REALTIME
#endif
extern "C" const Value __PosixServerPriority = CAM_POSIXSERVER_PRIORITY;
#endif
#define SET_BIT(num, nbit) ((num) |= (0x1<<(nbit)))
#define CHECK_BIT(num, nbit) ((num) & (0x1<<(nbit)))
#define QCARCAMTEST_BUFFER_STALE_BIT 4
typedef enum
{
QCARCAMTEST_BUFFER_STATE_INIT,
QCARCAMTEST_BUFFER_STATE_QCARCAM,
QCARCAMTEST_BUFFER_STATE_GET_FRAME,
QCARCAMTEST_BUFFER_STATE_USR_PROCESS,
QCARCAMTEST_BUFFER_STATE_USR_PROCESS_DONE,
QCARCAMTEST_BUFFER_STATE_POST_DISPLAY,
QCARCAMTEST_BUFFER_STATE_MAX = 0x7FFFFFF
}qcarcam_test_buffer_state_t;
typedef enum
{
QCARCAM_TEST_BUFFERS_OUTPUT = 0,
QCARCAM_TEST_BUFFERS_DISPLAY,
QCARCAM_TEST_BUFFERS_INPUT,
QCARCAM_TEST_BUFFERS_MAX
} qcarcam_test_buffers_t;
typedef struct
{
qcarcam_buffers_t p_buffers;
qcarcam_color_fmt_t format;
unsigned int n_buffers;
unsigned int width;
unsigned int height;
} qcarcam_buffers_param_t;
typedef enum
{
QCARCAMTEST_STATE_INVALID = 0,
QCARCAMTEST_STATE_INIT,
QCARCAMTEST_STATE_OPEN,
QCARCAMTEST_STATE_START,
QCARCAMTEST_STATE_STOP,
QCARCAMTEST_STATE_PAUSE,
QCARCAMTEST_STATE_PAUSE_STOP_PENDING,
QCARCAMTEST_STATE_ERROR,
QCARCAMTEST_STATE_CLOSED,
QCARCAMTEST_STATE_SUSPEND,
QCARCAMTEST_STATE_RECOVERY,
}qcarcamtest_state_t;
typedef struct
{
uint32 buf_idx;
void *p_data;
}timer_usr_data;
typedef struct
{
timer_usr_data usr_data;
CameraTimer ptimer;
}qcarcam_test_buf_timer;
typedef struct
{
qcarcam_event_t event_id;
qcarcam_event_payload_t payload;
} qcarcam_event_msg_t;
typedef struct
{
CameraThread thread_handle;
CameraThread process_cb_event_handle;
CameraSignal m_eventHandlerSignal;
unsigned int idx;
int query_inputs_idx;
pthread_mutex_t mutex;
qcarcamtest_state_t state;
bool is_fatal_error;
/*qcarcam context*/
qcarcam_hndl_t qcarcam_context;
qcarcam_input_desc_t qcarcam_input_id;
qcarcam_buffers_param_t buffers_param[QCARCAM_TEST_BUFFERS_MAX];
qcarcam_buffers_t p_buffers_output;
qcarcam_buffers_t p_buffers_disp;
qcarcam_buffers_t p_buffers_input;
qcarcam_res_t resolution;
unsigned long long int frame_timeout;
int use_event_callback;
qcarcam_opmode_type op_mode;
unsigned int num_isp_instances;
qcarcam_isp_usecase_config_t isp_config[QCARCAM_MAX_ISP_INSTANCES];
bool recovery;
/* test util objects */
test_util_ctxt_t *test_util_ctxt;
test_util_window_t *qcarcam_window;
test_util_window_t *display_window;
test_util_window_param_t window_params;
/* buffer management tracking */
int get_frame_buf_idx;
int buf_idx_qcarcam;
std::list<uint32> release_buf_idx;
int buf_idx_disp;
int prev_buf_idx_disp;
/* diag */
int frameCnt;
int releaseframeCnt;
int prev_frameCnt;
int prev_releaseframeCnt;
bool is_first_start;
bool is_injection;
unsigned long long t_start; //start command
unsigned long long t_start_success;
unsigned long long t_firstFrame; //first frame time
unsigned long long t_before;
unsigned long long t_after;
test_util_diag_t diag;
bool dumpNextFrame;
/* Exposure values */
float exp_time;
float gain;
int manual_exposure;
/* frame rate parameters */
qcarcam_frame_rate_t frame_rate_config;
unsigned int num_batch_frames;
unsigned int frame_increment;
qcarcam_test_buffer_state_t buf_state[QCARCAM_MAX_NUM_BUFFERS];
bool skip_post_display;
qcarcam_field_t field_type_previous;
bool signal_lost;
int fatal_err_cnt;
#ifdef ENABLE_CL_CONVERTER
void* g_converter = NULL;
ClConverter_surface_t source_surface;
ClConverter_surface_t target_surface;
#endif
/* subscription for changed setting events notification */
uint64 subscribe_parameter_change;
bool is_master;
/* user process */
uint32 delay_time;
qcarcam_test_buf_timer buf_timer[QCARCAM_MAX_NUM_BUFFERS];
std::list<uint32> usr_process_buf_idx;
int usr_process_frameCnt;
CameraThread usr_process_thread_handle;
std::queue<qcarcam_event_msg_t> eventqueue;
pthread_mutex_t queue_mutex;
#ifdef POST_PROCESS
void *pPostProcessing;
void *pSource_surface;
void *pTarget_surface;
#endif
} qcarcam_test_input_t;
typedef struct
{
int numInputs;
qcarcam_test_input_t inputs[NUM_MAX_CAMERAS];
int opened_stream_cnt;
/* 0 : post buffers directly to screen
* 1 : blit buffers to display buffers through c2d
*/
int enable_c2d;
#ifndef C2D_DISABLED
pthread_mutex_t mutex_c2d;
#endif
int dumpFrame;
int enablePauseResume;
int enableStartStop;
int multithreaded;
int enableStats;
int enableMenuMode;
int enableBridgeErrorDetect;
int enableFatalErrorRecover;
int enableIFEOverflowhandle;
int enableRetry;
int gpioNumber;
int gpioMode;
int disable_display;
int checkDualCsi;
int enable_csc;
int enable_cache;
int exitSeconds;
int fps_print_delay;
int vis_value;
int check_buffer_state;
/*abort condition*/
pthread_mutex_t mutex_abort;
pthread_cond_t cond_abort;
pthread_mutex_t mutex_csi_err;
pthread_mutex_t mutex_open_cnt;
unsigned long long t_start; //program start
testutil_deinterlace_t enable_deinterlace;
#ifdef POST_PROCESS
int enable_post_processing; // enable post processing path
const IPostProcessing *post_processing_interface;
GetPostProcessingInterfaceType pfnGetPostProcessingInterface;
void *pPost_processing;
test_util_pp_ctxt_t post_processing_ctx[NUM_MAX_CAMERAS] = {};
#endif
} qcarcam_test_ctxt_t;
typedef enum
{
QCARCAM_TEST_MENU_FIRST_ITEM = 1,
QCARCAM_TEST_MENU_STREAM_OPEN = QCARCAM_TEST_MENU_FIRST_ITEM,
QCARCAM_TEST_MENU_STREAM_CLOSE,
QCARCAM_TEST_MENU_STREAM_STOP,
QCARCAM_TEST_MENU_STREAM_START,
QCARCAM_TEST_MENU_STREAM_PAUSE,
QCARCAM_TEST_MENU_STREAM_RESUME,
QCARCAM_TEST_MENU_STREAM_STOP_ALL,
QCARCAM_TEST_MENU_STREAM_START_ALL,
QCARCAM_TEST_MENU_STREAM_PAUSE_ALL,
QCARCAM_TEST_MENU_STREAM_RESUME_ALL,
QCARCAM_TEST_MENU_STREAM_ENABLE_CALLBACK,
QCARCAM_TEST_MENU_STREAM_DISABLE_CALLBACK,
QCARCAM_TEST_MENU_STREAM_SET_FRAMERATE,
QCARCAM_TEST_MENU_STREAM_SET_EXPOSURE,
QCARCAM_TEST_MENU_STREAM_SET_SENSORMODE,
QCARCAM_TEST_MENU_STREAM_GET_SENSORMODE,
QCARCAM_TEST_MENU_STREAM_SET_COLOR_PARAM,
QCARCAM_TEST_M