MutliSourceVideoProcess.h 7.43 KB
//#pragma once
#ifndef __MutliSourceVideoProcess_H__
#define __MutliSourceVideoProcess_H__

#include <stdlib.h>
#include <iostream>

#include "../DxDecoder/DxDecoderWrap.h"
#include "nvml.h"
#include "time.h"
//#include "opencv2/opencv.hpp"
#include "opencv2/highgui/highgui.hpp"
//#include "opencv2/imgproc/imgproc.hpp"
#include "VPTProcess.h"
#include <queue>
#include <set>
#include <boost/thread/thread.hpp>
#include "common.h"
#include "../DxDecoder/ImageSaveGPU.h"

#include "mvpt_process_assist.h"
#include <boost/thread/thread_pool.hpp>
#include "snapshot_helper.h"
#include <atomic>
#ifdef _MSC_VER
#ifdef _DEBUG
#pragma comment(lib, "opencv_world310d.lib")
#else
#pragma comment(lib, "opencv_world310.lib")
#endif
#endif
using namespace cv;
using namespace std;

#ifndef _MSC_VER
	#ifndef TRUE
	#define    TRUE         1
	#endif
	#ifndef FALSE
	#define    FALSE        0
	#endif
	#define Sleep(a) usleep((a)*1000)
	//typedef    int    BOOL;
#define BOOL bool
	typedef    unsigned int    DWORD;
	typedef    void*	LPVOID;
#endif

#ifdef _DEBUG
#define DEBUG_MSG(msg,...) \
	{ \
        printf("%s %s [%d]: ", __FILE__, __FUNCTION__, __LINE__); \
        printf(msg,##__VA_ARGS__); \
        printf("\n"); \
	}
#else
#define DEBUG_MSG(msg,...)
#endif

#define MAXLENGTH 416
#define MINLENGTH 224

//#define PROCESSHEIGHT 224
//#define PROCESSWIDTH 416
//#define DATASIZE PROCESSWIDTH * PROCESSHEIGHT * 3
#define THREAD_COUNT 30
#define SNAPSHOTFRAME 15
#define LOSTMAXFRAMECCOUNT 4

#define SCALE_OUT 10 //判断目标框初始位置时,在最小距离的基础上适当外扩


#define MAX_BATCH 10

extern int minDistance[];

enum TaskState
{
	PLAY,
	PAUSE,
	FINISH,
	DECODEERROR    //解码线程可能报错,报错之后直接结束掉该路解码
};



struct VideoHeightWidth{
	double height;
	double width;
};

struct VideoObjectSS
{
	unsigned char * obj_person;
	unsigned char * obj_bike;
	unsigned char * obj_car;

	VideoObjectSS() : obj_person(NULL), obj_bike(NULL), obj_car(NULL){}
};
template <typename T> class MyAtomic;
template<typename T>
bool operator == (MyAtomic<T> & d1, T &d2);

template<typename T>
bool operator == (MyAtomic<T> & d1, MyAtomic<T> &d2);
template <typename T>
class MyAtomic
{
public:
	MyAtomic() {};
	MyAtomic(const T & d) { data.store(d); };
	MyAtomic(const MyAtomic & d) { data.store(d.data.load()); };
	MyAtomic& operator =(T d) { data.store(d); return *this; };
	MyAtomic& operator =(MyAtomic & d) { data.store(d.data.load()); return *this; };
	MyAtomic& operator +=(T d) { data.fetch_add(d); return *this; };
	MyAtomic& operator +=(MyAtomic & d) { data.fetch_add(d); return *this; };
	operator int() { return data.load(); }
	friend bool operator ==<T> (MyAtomic<T> &d1, T &d2);
	friend bool operator ==<T> (MyAtomic<T> &d1, MyAtomic<T> &d2);
private:
	std::atomic<T> data;
};
template<typename T>
bool operator == (MyAtomic<T> & d1, T &d2)
{
	if (d1.data.load() == d2)
		return true;
	else
		return false;
}

template<typename T>
bool operator == (MyAtomic<T> & d1, MyAtomic<T> & d2)
{
	if (d1.data.load() == d2.load())
		return true;
	else
		return false;
}

struct Task{
	int taskID;
	const char *taskFileSource;
	TaskState taskState;
	DxDecoderWrap *taskTcuvid;
	DxGPUFrame task_algorithm_data;      //针对新框架不做resize的处理,先暂时用backup的原图大小的图片送进算法参与计算
	float* taskDataToRT;
	bool taskHasBackup;
	//VideoHeightWidth taskHeightWidthRatio;
	VideoHeightWidth taskHeightWidth;
	MyAtomic<int> taskFrameCount;
	int taskTotalFrameCount;
	SNAPSHOT_CALLBACK taskObjCallbackFunc;
	REALTIME_CALLBACK taskRealTimeCallbackFunc;
	cv::Mat frameImage;
	char* folderNameLittle;
	char* folderName;
	sy_rect task_min_boxsize[DETECTTYPE];
};

enum TaskOperator
{
	ADDTASK,
	PAUSETASK,
	RESTARTTASK,
	FINISHTASK
};
	
struct Operator{
	int changeTaskID;
	const char* videoFileName;
	const char* resultFolderLittleName;
	const char* resultFolderName;
	TaskOperator changeTaskOperator;
	VIDEO_OBJECT_SNAPSHOT_CALLBACK taskObjCallbackFunc;
	VIDEO_REALTIME_CALLBACK taskRealTimeCallbackFunc;
	sy_rect minBoxsize[DETECTTYPE];
};
	
struct CUVID_USERDATA{
	int		id;
	void	*opaque;
};

struct CUVID_DATA{
	float*	pData;
	int		nWidth;
	int		nHeight;
	int		nDatasize;
};





static int TaskID = 0;



struct SNAPSHOT_PROCESS_UNIT{
	vector<DxGPUFrame> imgBig;
	vector<DxGPUFrame> imgSmall;
	vector<VPT_Result> imgVPTResult;
};

class CMutliSourceVideoProcess
{
public:
	CMutliSourceVideoProcess();
	~CMutliSourceVideoProcess();

	int InitAlgorthim(mvpt_param vptParam, VIDEO_OBJECT_INFO_CALLBACK tObjInfoCallbackFunc, VIDEO_FINISH_CALLBACK tFinishCallbackFunc);
	void* GetVPT_Handle(){ return VPT_Handle; };
	int get_task_progress(int taskid, double & progress);
	void OperatorTask();
	bool HasNewTask() {
		return !TaskOperatorQ.empty();
	}
	void AddOperator(int taskID, int taskOper);
	int AddOperator(task_param tparam);
	void callTaskObjInfoCallbackFunc(int objCount, VPT_ObjInfo *obj, int taskFrameCount, int taskId);
	bool AddTask(const char* videoFileName, const char* resultFolderLittle, const char* resultFolder, sy_rect minBoxsize[DETECTTYPE], VIDEO_OBJECT_SNAPSHOT_CALLBACK objCallbackFunc = NULL, VIDEO_REALTIME_CALLBACK realTimeCallbackFunc = NULL);
	void PauseTask(const int taskID);
	void RestartTask(const int taskID);
	void FinishTask(const int taskID);
	void ViewTask(const int taskID);
	void FinishViewTask();
	int FinishProcessThread();
	int SaveResultInFile(const OBJ_KEY & obj_key, const OBJ_VALUE & obj_value);
	void FinishDecode(const int taskID);

private:
	//bool ChangeTask;
	//HANDLE handle_process;
	boost::thread ProcessThread;
	std::mutex _tx_add_task;
	

	//DWORD dwThreadID;
	deque<Operator> TaskOperatorQ;
	int capacity;
	
	//cv::Mat objSnapshot;

	double gpu_total_memory;
	boost::thread thrd;
	void* authority_handle;

public: /*按道理不应该是public的 但是在线程函数中会用到以下的数据 每个都写一个get函数太过复杂*/
	//fstream fout[THREAD_COUNT];	//用于输出结果
 	void * VPT_Handle;
	int section_batch_size;
	int licence_status;
	int thrd_status;
	int mgpuid;
	vector<Task> tasks;
	int AddTaskSucFlag;   //0:初始化状态 1:添加任务成功 -1:添加任务失败
	int TaskinPlay; 
	int TotalTask;
	set<int> TaskinPlayID;
//	float* pDataToVPT;
	vector<VPT_Result> VPTResult;
	std::atomic<bool> ProcessFlag;
	bool SourceFlag;
	//float* imgDataHost;
	//float* snapshotDataHost;
	unsigned char* imgDataDecive;
	void * FrameTemp;
	char* mModeSnapshotVideo;
	char* mModeSnapshotLittle;
	int viewTaskID;
	
	map<int, set<int>> objDelete;

	FINISH_CALLBACK taskFinishCallbackFunc;
	OBJECT_INFO_CALLBACK taskObjInfoCallbackFunc;

	queue<SNAPSHOT_PROCESS_UNIT> snapshotProcessQueue;
	
	//CUcontext cuCtx;

	

	//int PROCESSHEIGHT;
	//int PROCESSWIDTH;
	//int DATASIZE;
	
	bool beginSaveSnapshot;
	boost::thread_group saveSnapshotsThreadGroup;
	//boost::mutex process_thread_mutex;
	std::mutex taskMutex;
	std::condition_variable taskCondVar;
	bool AttributionAnalysis;  //用于控制,每帧分析只进行一个二次属性分析

	//算法配置参数
	sy_command m_hp_analysis_config;			       //是否启动车型识别
	sy_command m_hcp_analysis_config;	               //是否启动车牌检测识别
	sy_command m_vehicle_analysis_config;			   //是否启动车辆颜色识别
	sy_command m_vehicle_recg_config;		             //是否启动车辆属性识别
	sy_command m_vehicle_plate_det_recg_config;			   //是否启动车违规行为检测
	sy_command m_hf_recg_config;                     //是否开启行人特征识别
	sy_command m_hcf_recg_config;                    //是否开启人骑车特征识别
	sy_command m_vcf_recg_config;                    //是否开启车辆特征识别
	snapshot_helper m_snaphot_helper;
};

static  CMutliSourceVideoProcess mainProcess;
#endif