

#ifndef __SAMPLE_H__
#define __SAMPLE_H__

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <sys/time.h>

#include "hb_mem_mgr.h"
#include "hb_media_codec.h"
#include "hb_media_error.h"

#ifdef __cplusplus
extern "C" {
#endif				/* __cplusplus */
#include <libavformat/avformat.h>
#include <libavutil/timestamp.h>
#ifdef __cplusplus
}
#endif				/* __cplusplus */

#ifndef TRUE
#define TRUE			1
#endif /* TRUE */
#ifndef FALSE
#define FALSE		   0
#endif /* FALSE */

#define MAX_FILE_PATH 256
#define MAX_FILE_PATH_X2 (MAX_FILE_PATH + 32)
#define MAX_FILE_PATH_X4 1400

#define MAX_MEDIA_MUXER_TASK  32
#define MAX_VPU_INSTANCE  32
#define MAX_JPU_INSTANCE  64
#define MAX_FEEDING_SIZE  0x400000		/* 4MBytes */
#define MAX_CODEC_NUM	 20

typedef uint8_t 		Uint8;
typedef uint32_t		Uint32;
typedef uint16_t		Uint16;
typedef int8_t			Int8;
typedef int32_t 		Int32;
typedef int16_t 		Int16;
typedef uint64_t		Uint64;
typedef int64_t 		Int64;

typedef struct ion_buffer_t {
	int32_t size;
	uint64_t phys_addr;
	uint64_t virt_addr;
	int fd;
	int64_t handle;
} ion_buffer_t;

typedef struct ExternalFrameBuffer {
	ion_buffer_t buf;
	int32_t valid;
	int32_t src_idx;
} ExternalFrameBuffer;

typedef struct ExternalStreamBuffer {
	ion_buffer_t buf;
	int32_t valid;
	int32_t src_idx;
	int32_t onceflags;
	int32_t readsize;
} ExternalStreamBuffer;

typedef struct MediaCodecTestContext {
	media_codec_context_t *context;
	// resource
	FILE *inFile;
	FILE *outFile;
	FILE *inMd5File;
	FILE *outMd5File;
	int ionFd;
	char *inputFileName;
	char *outputFileName;
	char *inputMd5FileName;
	ExternalFrameBuffer *exFb;
	ExternalStreamBuffer *exBs;
	int abnormal;
	int workMode;

	// encode parameters
	// ENC_CONFIG_MESSAGE message;make
	mc_video_longterm_ref_mode_t ref_mode;
	mc_rate_control_params_t rc_params;
	hb_u32 max_bitrate;
	mc_video_intra_refresh_params_t intra_refr;
	mc_video_deblk_filter_params_t deblk_filter;
	mc_h265_sao_params_t sao;
	mc_h264_entropy_params_t entropy;
	mc_video_vui_params_t vui;
	mc_video_vui_timing_params_t vui_timing;
	mc_video_slice_params_t slice;
	mc_video_3dnr_enc_params_t noise_reduction;
	mc_video_smart_bg_enc_params_t smart_bg;
	mc_video_pred_unit_params_t pred_unit;
	mc_video_transform_params_t transform;
	mc_video_roi_params_t roi;
	hb_u32 roi_avg_qp;
	mc_video_roi_params_ex_t roiEx;
	mc_video_mode_decision_params_t mode_decision;
	uint32_t force_idr_header_num;
	uint32_t force_idr_header;
	int enable_idr_num;
	int req_idr_num;
	int skip_pic_num;
	int insert_userData_num;
	int enable_explicit_header;
	int qpmap_enable;
	hb_byte qpmap_array;
	hb_u32 qpmap_count;

	// for dynamic parameters
	// ENC_CONFIG_MESSAGE dynamicMessage;
	mc_video_longterm_ref_mode_t ref_mode_dynamic;
	mc_rate_control_params_t rc_params_dynamic;
	hb_u32 max_bitrate_dynamic;
	mc_video_deblk_filter_params_t deblk_filter_dynamic;
	mc_h265_sao_params_t sao_dynamic;
	mc_h264_entropy_params_t entropy_dynamic;
	mc_video_vui_params_t vui_dynamic;
	mc_video_vui_timing_params_t vui_timing_dynamic;
	mc_video_slice_params_t slice_dynamic;
	mc_video_3dnr_enc_params_t noise_reduction_dynamic;
	mc_video_smart_bg_enc_params_t smart_bg_dynamic;
	mc_video_pred_unit_params_t pred_unit_dynamic;
	mc_video_transform_params_t transform_dynamic;
	mc_video_roi_params_t roi_dynamic;
	hb_u32 roi_avg_qp_dynamic;
	mc_video_roi_params_ex_t roiEx_dynamic;
	mc_video_mode_decision_params_t mode_decision_dynamic;
	uint32_t force_idr_header_num_dynamic;
	uint32_t force_idr_header_dynamic;
	int enable_idr_num_dynamic;
	int enable_explicit_header_dynamic;
	int qpmap_enable_dynamic;
	hb_byte qpmap_array_dynamic;
	hb_u32 qpmap_count_dynamic;

	// decode parameters
	int enable_get_userdata;
	uint32_t feedingSize;

	// test parameters
	int md5Test;
	int pfTest;
	int stabilityTest;
	int stabilityParaTest;
	int targetFps;
	int testLog;
	int testAbnormalQuit;
	int32_t duration; // s
	int vlc_buf_size;
	int pollEncFd;
	int pollDecFd;
	Uint64 testStartTime;
	Uint64 initTime;
	int input_num;
	int32_t delaytest;
	int32_t delaytime; //ms
	int bitfullTest;
	int dynamicTest;
	Uint64 frametime;
	int32_t readonce;

	// async parameters
	AVFormatContext* avContext; //decoder
	AVPacket avpacket; //decoder
	int videoIndex; //decoder
	int firstPacket; //decoder
	int lastStream; // encoder and decoder
	int lastFrame; // encoder
} MediaCodecTestContext;

int allocate_ion_mem(int fd, ion_buffer_t *vb);
int release_ion_mem(int fd, ion_buffer_t *vb);
int check_and_init_test(MediaCodecTestContext *ctx);
int check_and_release_test(MediaCodecTestContext *ctx);
int get_rc_params(media_codec_context_t *context, mc_rate_control_params_t *rc_params);

void do_sync_encoding(void *arg);
void do_sync_decoding(void *arg);

#endif
