
#include "AVPlaySdkApi.h"
#include <map>
#include <string>
#include <stdio.h>

#if defined(_WIN32) || defined(_WIN64)
void usleep(int _iMicroSecond)
{
	if (_iMicroSecond < 1000 && _iMicroSecond != 0)
	{
		_iMicroSecond = 1000;
	}
	Sleep(_iMicroSecond/1000);
}
#endif

//定义demo操作命令值
#define CMD_Quit				-1
#define CMD_Create				1
#define CMD_Delete				2
#define CMD_PlayVideo			3
#define CMD_PauseVideo			4
#define CMD_StopVideo			5
#define CMD_PlayAudio			6
#define CMD_StopAudio			7
#define CMD_GoBegin				8
#define CMD_GoEnd				9
#define CMD_StepForward			10
#define CMD_StepBackward		11
#define CMD_FastForward			12
#define CMD_SlowForward			13
#define CMD_FastBackward		14
#define CMD_Seek				15
#define CMD_SetAudioVolume		16
#define CMD_GetAudioVolume		17
#define CMD_CapturePicture		18
#define CMD_StartCaptureFile	19
#define CMD_SetDecryptKey		20
#define CMD_GetInfo				21
#define CMD_SetAVMode			22
#define CMD_StopCaptureFile	    23
#define CMD_GetPlayTime			24

//存储操作指令
static map<string, int> s_mapCmd;
static void MakeCmd();
static void DoTest();

//demo功能函数
static void CreatePlayer();
static void DeletePlayer();
static void PlayVideo();
static void PauseVideo();
static void StopVideo();
static void PlayAudio();
static void StopAudio();
static void GoBegin();
static void GoEnd();
static void StepForward();
static void StepBackward();
static void FastForward();
static void SlowForward();
static void FastBackward();
static void Seek();			
static void SetAudioVolume();
static void GetAudioVolume();
static void CapturePicture();	
static void StartCaptureFile();	
static void StopCaptureFile();	
static void SetDecryptKey();
static void GetStreamInfo();	
static void SetAVMode();
static int CommonEventNotify(int _iPlayerID, int _iEventMessage, void* _pvUsrData);
static void DecodeYuvNofify(unsigned int _ulID,unsigned char *_cData, int _iLen, const FRAME_INFO *_pFrameInfo, void* _iUser);
static void PlayEndFun(int _iID);
static void	GetPlayTime();


static FILE* s_pfFile = NULL;
#define INVALID_ID		(-1)
static int s_iPlayerId = INVALID_ID;
PLAYHWND s_hWnd = 0;
const int CONST_iMaxReadSize = 1024 * 1024 * 2;
char s_cDataBuf[CONST_iMaxReadSize] = {0};
static char  s_cYuvFile[] = "./MyData.yuv";
static FILE* s_pfYuvFile = NULL;


static int	s_iRunThread = 0;


#if defined(_WIN32) || defined(_WIN64)
void WindowsPutStreamThread(void* _pvPara)
#else
void* LinuxPutStreamThread(void* _pvPara)
#endif
{
	int iSleepTime = 200000;	//200 ms
	while(s_iRunThread)
	{
		if (NULL == s_pfFile)
		{
			break;
		}
		unsigned int ulCurPos = ftell(s_pfFile);
		int iReadLen = (int)fread(s_cDataBuf, sizeof(char), CONST_iMaxReadSize, s_pfFile);
		if(0 == iReadLen)
		{
			cout << "[PutStreamThread]: file has reach end!" << endl;
			fclose(s_pfFile);
			s_pfFile = NULL;
			CLS_AVPlaySdkApi::Instance()->SetVoDPlayerOver(s_iPlayerId);
			break;
		}

		int iPutRet = CLS_AVPlaySdkApi::Instance()->PutStreamToPlayer(s_iPlayerId, (unsigned char*)s_cDataBuf, iReadLen);
		if(RET_BUFFER_WILL_BE_FULL == iPutRet)
		{
			//缓冲满了，减速且这次不送
			iSleepTime += 50;
		}
		else if (RET_BUFFER_WILL_BE_EMPTY == iPutRet)
		{
			//缓冲太少，加速
			iSleepTime -= 50;
		}
		else if (RET_BUFFER_FULL == iPutRet)
		{
			//缓冲区满，数据没有放入缓冲区
			fseek(s_pfFile, ulCurPos, SEEK_SET);
		}
		else if (RET_BUFFER_IS_OK != iPutRet)
		{
			//正常可以放数据
		}
		usleep(iSleepTime);
	}

	if (NULL != s_pfYuvFile)
	{
		fclose(s_pfYuvFile);
		s_pfYuvFile = NULL;
	}

	if (NULL != s_pfFile)
	{
		fclose(s_pfFile);
		s_pfFile = NULL;
	}

#if defined(_WIN32) || defined(_WIN64)
	return;
#else
	return NULL;
#endif
}


int main(int argc, char** argv)
{
	int iRet = RET_FAILED;
	iRet = CLS_AVPlaySdkApi::Instance()->LoadSdkLibrary();
	if (RET_SUCCESS != iRet)
	{
		printf("LoadSdkLibrary fail return!(%d)\n", iRet);
		goto END;
	}

	iRet = CLS_AVPlaySdkApi::Instance()->CreateSystem(s_hWnd);
	if (RET_SUCCESS != iRet)
	{
		printf("CreateSystem fail return!(%d)\n", iRet);
		goto END;
	}

	MakeCmd();
	DoTest();

END:
	if (NULL != s_pfYuvFile)
	{
		fclose(s_pfYuvFile);
		s_pfYuvFile = NULL;
	}

	if (NULL != s_pfFile)
	{
		fclose(s_pfFile);
		s_pfFile = NULL;
	}
	CLS_AVPlaySdkApi::Instance()->DeleteSystem();
	CLS_AVPlaySdkApi::Instance()->FreeSdkLibrary();
	CLS_AVPlaySdkApi::Instance()->Destroy();
	return iRet;
}

void MakeCmd()
{   
	s_mapCmd[string("Quit")] = CMD_Quit;
	s_mapCmd[string("q")] = CMD_Quit;

	s_mapCmd[string("CreatePlayer")] = CMD_Create;
	s_mapCmd[string("1")] = CMD_Create;

	s_mapCmd[string("DeletePlayer")] = CMD_Delete;
	s_mapCmd[string("2")] = CMD_Delete;

	s_mapCmd[string("PlayVideo")] = CMD_PlayVideo;
	s_mapCmd[string("3")] = CMD_PlayVideo;

	s_mapCmd[string("PauseVideo")] = CMD_PauseVideo;
	s_mapCmd[string("4")] = CMD_PauseVideo;

	s_mapCmd[string("StopVideo")] = CMD_StopVideo;
	s_mapCmd[string("5")] = CMD_StopVideo;

	s_mapCmd[string("PlayAudio")] = CMD_PlayAudio;
	s_mapCmd[string("6")] = CMD_PlayAudio;

	s_mapCmd[string("StopAudio")] = CMD_StopAudio;
	s_mapCmd[string("7")] = CMD_StopAudio;

	s_mapCmd[string("GoBegin")] = CMD_GoBegin;
	s_mapCmd[string("8")] = CMD_GoBegin;

	s_mapCmd[string("GoEnd")] = CMD_GoEnd;
	s_mapCmd[string("9")] = CMD_GoEnd;

	s_mapCmd[string("StepForward")] = CMD_StepForward;
	s_mapCmd[string("10")] = CMD_StepForward;

	s_mapCmd[string("StepBackward")] = CMD_StepBackward;
	s_mapCmd[string("11")] = CMD_StepBackward;

	s_mapCmd[string("FastForward")] = CMD_FastForward;
	s_mapCmd[string("12")] = CMD_FastForward;

	s_mapCmd[string("SlowForward")] = CMD_SlowForward;
	s_mapCmd[string("13")] = CMD_SlowForward;

	s_mapCmd[string("FastBackward")] = CMD_FastBackward;
	s_mapCmd[string("14")] = CMD_FastBackward;

	s_mapCmd[string("Seek")] = CMD_Seek;
	s_mapCmd[string("15")] = CMD_Seek;

	s_mapCmd[string("SetAudioVolume")] = CMD_SetAudioVolume;
	s_mapCmd[string("16")] = CMD_SetAudioVolume;

	s_mapCmd[string("GetAudioVolume")] = CMD_GetAudioVolume;
	s_mapCmd[string("17")] = CMD_GetAudioVolume;

	s_mapCmd[string("CapturePicture")] = CMD_CapturePicture;
	s_mapCmd[string("18")] = CMD_CapturePicture;

	s_mapCmd[string("StartCaptureFile")] = CMD_StartCaptureFile;
	s_mapCmd[string("19")] = CMD_StartCaptureFile;

	s_mapCmd[string("SetDecryptKey")] = CMD_SetDecryptKey;
	s_mapCmd[string("20")] = CMD_SetDecryptKey;

	s_mapCmd[string("GetInfo")] = CMD_GetInfo;
	s_mapCmd[string("21")] = CMD_GetInfo;

	s_mapCmd[string("SetAVMode")] = CMD_SetAVMode;
	s_mapCmd[string("22")] = CMD_SetAVMode;

	s_mapCmd[string("StopCaptureFile")] = CMD_StopCaptureFile;
	s_mapCmd[string("23")] = CMD_StopCaptureFile;

	s_mapCmd[string("GetPlayTime")] = CMD_GetPlayTime;
	s_mapCmd[string("24")] = CMD_GetPlayTime;
}

int get_cmd_int()
{
	char cTemp[1024] = {0};
	cin>>cTemp;
	int iTemp = atoi(cTemp);
	return iTemp;
}

void DoTest()
{
	int iCmd = -1;
	string strCmd;
	bool blQuit = false;
	while(!blQuit)
	{
		cout<<"*********************************************************************************************"<<endl;
		fprintf(stderr,
			"[q]Quit			[1]CreatePlayer		[2]DeletePlayer		[3]PlayVideo		\n"
#ifdef	WIN32
			"[4]PauseVideo		[5]StopVideo		[6]PlayAudio		[7]StopAudio		\n"
#else	//linux下暂不支持播放声音
			"[4]PauseVideo		[5]StopVideo		\n"	
#endif
			
			"[8]GoBegin		[9]GoEnd		[10]StepForward		[11]StepBackward			\n"
			"[12]FastForward		[13]SlowForward		[14]FastBackward	[15]Seek		\n"
			"[16]SetAudioVolume	[17]GetAudioVolume	[18]CapturePicture	[19]StartCaptureFile\n"
			"[20]SetDecryptKey	[21]GetInfo		[22]SetAVMode		[23]StopCaptureFile		\n"
			"[24]GetPlayTime\n");
		cout<<"*********************************************************************************************"<<endl;

		cout<<endl<<"Please input your correct command: "<<endl;
		cout<<">";
		cin>>strCmd;
		iCmd = s_mapCmd[strCmd];
		switch(iCmd)  
		{
		case CMD_Quit:   //q
			cout<<"Goodbye, my friend!"<<endl;
			blQuit = true;
			break;
		case CMD_Create:
			CreatePlayer();
			break;
		case CMD_Delete:
			DeletePlayer();
			break;
		case CMD_PlayVideo:
			PlayVideo();
			break;
		case CMD_PauseVideo:
			PauseVideo();
			break;
		case CMD_StopVideo:
			StopVideo();
			break;
		case CMD_PlayAudio:
			PlayAudio();
			break;
		case CMD_StopAudio:
			StopAudio();
			break;
		case CMD_GoBegin:
			GoBegin();
			break;
		case CMD_GoEnd:
			GoEnd();
			break;
		case CMD_StepForward:
			StepForward();
			break;
		case CMD_StepBackward:
			StepBackward();
			break;
		case CMD_FastForward:
			FastForward();
			break;
		case CMD_SlowForward:
			SlowForward();
			break;
		case CMD_FastBackward:
			FastBackward();
			break;
		case CMD_Seek:
			Seek();
			break;
		case CMD_SetAudioVolume:
			SetAudioVolume();
			break;
		case CMD_GetAudioVolume:
			GetAudioVolume();
			break;
		case CMD_CapturePicture:
			CapturePicture();
			break;
		case CMD_StartCaptureFile:
			StartCaptureFile();
			break;
		case CMD_StopCaptureFile:
			StopCaptureFile();
			break;
		case CMD_SetDecryptKey:
			SetDecryptKey();
			break;
		case CMD_GetInfo:
			GetStreamInfo();
			break;
		case CMD_SetAVMode:
			SetAVMode();
			break;
		case CMD_GetPlayTime:
			GetPlayTime();
			break;
		default:
			cout<<"Command \""<<strCmd<<"\" not found!"<<endl;
			break;
		}
	}
}

void CreatePlayer()
{
	DeletePlayer();

	int iDataMode = 0;	//数据模式，如果是流模式，需要demo模拟实时流传送到SDK，而文件模式只需要传递本地有效的文件路径到SDK
	int iDecodeMode = 0;
	int iHwMode = 0;
	char cLocalFilePath[MAX_FILENAME_LEN] = {0};
	unsigned char ucFileHeader[PLAY_VIDEO_HEADER_LEN] = {0};
	cout<<"Please input player mode(0:file mode, 1:stream mode, other:file mode): "<<endl;
	iDataMode = get_cmd_int();
#ifdef WIN32
	cout<<"Please input decode mode(0:soft mode, 1:hard mode, other:soft mode): "<<endl;
	iDecodeMode = get_cmd_int();
#else
	iDecodeMode = 0;
#endif

	if (1 == iDecodeMode)
	{
		cout<<"Please input hard decode mode(0:cuda, 1:dxva, other:cuda): "<<endl;
		iHwMode = get_cmd_int();
	}

	cout<<"Please input local avfile path: "<<endl;
	cin>>cLocalFilePath;

	s_pfFile = fopen(cLocalFilePath, "rb+");
	if (NULL == s_pfFile)
	{
		cout<<"failure, Open local avfile, cLocalFilePath="<<cLocalFilePath<<endl;
		return;
	}

	int iReadLen = (int)fread(ucFileHeader, sizeof(unsigned char), PLAY_VIDEO_HEADER_LEN, s_pfFile);
	if (iReadLen < PLAY_VIDEO_HEADER_LEN)
	{
		cout<<"failure, Read local avfile, iReadLen="<<iReadLen<<endl;
		return;
	}

	int iPlayerType = E_NORMAL_FILEPLAYER;
	void* pvPlayerPara = NULL;
	int iBufSize = 0;
	FilePlayer tFilePlayer = {0};
	StreamPlayer tStreamPlayer = {0};
	CudaPlayer tCudaStreamPlayer = {0};
	CudaFilePlayer tCudaFilePlayer = {0};
	//提前设置硬解
	if (1 == iDecodeMode && 1 == iHwMode)
	{
		//硬解->dxva    设置硬解模式
		HwDecodeParam tHwDecInfo = {0};
		tHwDecInfo.iSize = sizeof(HwDecodeParam);
		tHwDecInfo.iLimitType = HWDEC_LIMIT_LOCAL;
		tHwDecInfo.iMaxCount = 100;
		tHwDecInfo.iEnableFlag = HWDEC_ENABLE_STREAM | HWDEC_ENABLE_VOD | HWDEC_ENABLE_FILE;
		CLS_AVPlaySdkApi::Instance()->SetAVMode(CMD_AV_DEC_HWDECODE_PARAM, &tHwDecInfo, tHwDecInfo.iSize);
	}

	if (1 == iDataMode && ((0 == iDecodeMode) || (1 == iDecodeMode && 1 == iHwMode)))
	{
		//流模式 -> (软解  或者   硬解+dxva)
		iPlayerType = E_NORMAL_STREAMPLAYER;
		tStreamPlayer.iSize = (int)sizeof(StreamPlayer);
		tStreamPlayer.hWnd = s_hWnd;
		memcpy(tStreamPlayer.ucVideoHeadBuf, ucFileHeader, sizeof(ucFileHeader));
		pvPlayerPara = &tStreamPlayer;
		iBufSize = sizeof(StreamPlayer);
	}
	else if (1 == iDataMode && 1 == iDecodeMode && 0 == iHwMode)
	{
		//流模式+硬解+cuda，对应的PlayerType
		iPlayerType = E_CUDA_STREAMPLAYER;
		tCudaStreamPlayer.iSize = sizeof(CudaPlayer);
		tCudaStreamPlayer.hWnd = s_hWnd;
		memcpy(tStreamPlayer.ucVideoHeadBuf, ucFileHeader, sizeof(ucFileHeader));
		pvPlayerPara = &tCudaStreamPlayer;
		iBufSize = sizeof(CudaPlayer);
	}
	else if (0 == iDataMode && 1 == iDecodeMode && 0 == iHwMode)
	{
		//文件模式+硬解+cuda，对应的PlayerType
		iPlayerType = E_CUDA_FILEPLAYER;
		tCudaFilePlayer.iSize = sizeof(CudaFilePlayer);
		tCudaFilePlayer.hWnd = s_hWnd;
		memcpy(tCudaFilePlayer.cFileName, cLocalFilePath, sizeof(cLocalFilePath));
		pvPlayerPara = &tCudaFilePlayer;
		iBufSize = sizeof(CudaFilePlayer);
	}
	else
	{
		iPlayerType = E_NORMAL_FILEPLAYER;
		tFilePlayer.iSize = sizeof(FilePlayer);
		tFilePlayer.hWnd = s_hWnd;
		memcpy(tFilePlayer.cFileName, cLocalFilePath, sizeof(cLocalFilePath));
		pvPlayerPara = &tFilePlayer;
		iBufSize = sizeof(FilePlayer);
	}

	s_iPlayerId = CLS_AVPlaySdkApi::Instance()->CreatePlayer(iPlayerType, pvPlayerPara, iBufSize, NULL);
	if (s_iPlayerId < 0)
	{
		cout<<"failure, CreatePlayer, s_iPlayerId="<<s_iPlayerId<<", cLocalFilePath="<<cLocalFilePath<<endl;
		return;
	}
	//流模式，模拟实时流传送到SDK
	if (1 == iDataMode)
	{
		CLS_AVPlaySdkApi::Instance()->SetStreamBufferSize(s_iPlayerId, 4*1024*1024);
		CLS_AVPlaySdkApi::Instance()->SetFrameListBufferSize(s_iPlayerId, 10*1024*1024);
		CLS_AVPlaySdkApi::Instance()->SetModeRule(s_iPlayerId, MODERULE_AUTO_ADJUST_STREAM_PLAY_SPEED_NO);
		CLS_AVPlaySdkApi::Instance()->SetModeRule(s_iPlayerId, MODERULE_AUTO_ADJUST_DRAW_YES);
		s_iRunThread = 1;
#if defined(_WIN32) || defined(_WIN64)
		_beginthread(WindowsPutStreamThread, 0, NULL);
#else
		pthread_t t;
		pthread_create(&t, NULL, LinuxPutStreamThread, NULL);
#endif
	}

	CLS_AVPlaySdkApi::Instance()->RegisterCommonEventCallBack_V4(s_iPlayerId, CommonEventNotify, NULL);
	CLS_AVPlaySdkApi::Instance()->RegisterNotifyPlayToEnd((void*)PlayEndFun);
	//注册YUV回调
	CLS_AVPlaySdkApi::Instance()->SetDecCallBack(s_iPlayerId, DecodeYuvNofify, NULL);

	cout<<"success, CreatePlayer, s_iPlayerId="<<s_iPlayerId<<endl;
}

void DeletePlayer()
{
	s_iRunThread = 0;
	usleep(100*1000);

	if(INVALID_ID != s_iPlayerId)
	{
		CLS_AVPlaySdkApi::Instance()->DeletePlayerEx(s_iPlayerId, 0);
		cout<<"success, DeletePlayer, s_iPlayerId="<<s_iPlayerId<<endl;
	}
	else 
	{
		cout<<"failure, DeletePlayer, s_iPlayerId="<<s_iPlayerId<<endl;
	}
	s_iPlayerId = INVALID_ID;
	
	if (NULL != s_pfYuvFile)
	{
		fclose(s_pfYuvFile);
		s_pfYuvFile = NULL;
	}

	if (NULL != s_pfFile)
	{
		fclose(s_pfFile);
		s_pfFile = NULL;
	}
}

void PlayVideo()
{
	int iRet = RET_FAILED;
	if(INVALID_ID != s_iPlayerId)
	{
		iRet = CLS_AVPlaySdkApi::Instance()->Play(s_iPlayerId);	
	}

	if (RET_SUCCESS == iRet)
	{
		cout<<"success, PlayVideo, s_iPlayerId="<<s_iPlayerId<<endl;
		//if (NULL == s_pfYuvFile)
		//{
		//	s_pfYuvFile = fopen(s_cYuvFile, "wb+");
		//}
	}
	else
	{
		cout<<"failure, PlayVideo, s_iPlayerId="<<s_iPlayerId<<endl;
	}
}

void PauseVideo()
{
	int iRet = RET_FAILED;
	if(INVALID_ID != s_iPlayerId)
	{
		iRet = CLS_AVPlaySdkApi::Instance()->Pause(s_iPlayerId);		
	}

	if (RET_SUCCESS == iRet)
	{
		cout<<"success, PauseVideo, s_iPlayerId="<<s_iPlayerId<<endl;
	}
	else
	{
		cout<<"failure, PauseVideo, s_iPlayerId="<<s_iPlayerId<<endl;
	}
}

void StopVideo()
{
	int iRet = RET_FAILED;
	if(INVALID_ID != s_iPlayerId)
	{
		iRet = CLS_AVPlaySdkApi::Instance()->Stop(s_iPlayerId);
	}

	if (RET_SUCCESS == iRet)
	{
		cout<<"success, StopVideo, s_iPlayerId="<<s_iPlayerId<<endl;
	}
	else
	{
		cout<<"failure, StopVideo, s_iPlayerId="<<s_iPlayerId<<endl;
	}

	if (NULL != s_pfYuvFile)
	{
		fclose(s_pfYuvFile);
		s_pfYuvFile = NULL;
	}
}

void PlayAudio()
{
	int iRet = RET_FAILED;
	if(INVALID_ID != s_iPlayerId)
	{
		iRet = CLS_AVPlaySdkApi::Instance()->PlayAudio(s_iPlayerId);
	}

	if (RET_SUCCESS == iRet)
	{
		cout<<"success, PlayAudio, s_iPlayerId="<<s_iPlayerId<<endl;
	}
	else
	{
		cout<<"failure, PlayAudio, s_iPlayerId="<<s_iPlayerId<<endl;
	}
}

void StopAudio()
{
	int iRet = RET_FAILED;
	if(INVALID_ID != s_iPlayerId)
	{
		iRet = CLS_AVPlaySdkApi::Instance()->StopAudio(s_iPlayerId);
	}

	if (RET_SUCCESS == iRet)
	{
		cout<<"success, StopAudio, s_iPlayerId="<<s_iPlayerId<<endl;
	}
	else
	{
		cout<<"failure, StopAudio, s_iPlayerId="<<s_iPlayerId<<endl;
	}
}

void GoBegin()
{
	int iRet = RET_FAILED;
	if(INVALID_ID != s_iPlayerId)
	{
		iRet = CLS_AVPlaySdkApi::Instance()->GoBegin(s_iPlayerId);
	}

	if (RET_SUCCESS == iRet)
	{
		cout<<"success, GoBegin, s_iPlayerId="<<s_iPlayerId<<endl;
	}
	else
	{
		cout<<"failure, GoBegin, s_iPlayerId="<<s_iPlayerId<<endl;
	}
}

void GoEnd()
{
	int iRet = RET_FAILED;
	if(INVALID_ID != s_iPlayerId)
	{
		iRet = CLS_AVPlaySdkApi::Instance()->GoEnd(s_iPlayerId);
	}

	if (RET_SUCCESS == iRet)
	{
		cout<<"success, GoEnd, s_iPlayerId="<<s_iPlayerId<<endl;
	}
	else
	{
		cout<<"failure, GoEnd, s_iPlayerId="<<s_iPlayerId<<endl;
	}
}

void StepForward()
{
	int iRet = RET_FAILED;
	if(INVALID_ID != s_iPlayerId)
	{
		iRet = CLS_AVPlaySdkApi::Instance()->StepForward(s_iPlayerId);
	}	

	if (RET_SUCCESS == iRet)
	{
		cout<<"success, StepForward, s_iPlayerId="<<s_iPlayerId<<endl;
	}
	else
	{
		cout<<"failure, StepForward, s_iPlayerId="<<s_iPlayerId<<endl;
	}
}

void StepBackward()
{
	int iRet = RET_FAILED;
	if(INVALID_ID != s_iPlayerId)
	{
		iRet = CLS_AVPlaySdkApi::Instance()->StepBackward(s_iPlayerId);
	}

	if (RET_SUCCESS == iRet)
	{
		cout<<"success, StepBackward, s_iPlayerId="<<s_iPlayerId<<endl;
	}
	else
	{
		cout<<"failure, StepBackward, s_iPlayerId="<<s_iPlayerId<<endl;
	}
}

void FastForward()
{
	int iRet = RET_FAILED;
	int iSpeed = 0;
	if(INVALID_ID != s_iPlayerId)
	{
		cout<<"Please input iSpeed(0-4): "<<endl;
		iSpeed = get_cmd_int();
		if (iSpeed > 4)
		{
			iSpeed = 4;
		}
		iRet = CLS_AVPlaySdkApi::Instance()->FastForward(s_iPlayerId, iSpeed);
	}

	if (RET_SUCCESS == iRet)
	{
		cout<<"success, FastForward, s_iPlayerId="<<s_iPlayerId<<", iSpeed="<<iSpeed<<endl;
	}
	else
	{
		cout<<"failure, FastForward, s_iPlayerId="<<s_iPlayerId<<", iSpeed="<<iSpeed<<endl;
	}
}

void SlowForward()
{
	int iRet = RET_FAILED;
	int iSpeed = 0;
	if(INVALID_ID != s_iPlayerId)
	{
		cout<<"Please input iSpeed(0-4): "<<endl;
		iSpeed = get_cmd_int();
		if (iSpeed > 4)
		{
			iSpeed = 4;
		}
		iRet = CLS_AVPlaySdkApi::Instance()->SlowForward(s_iPlayerId, iSpeed);
	}

	if (RET_SUCCESS == iRet)
	{
		cout<<"success, SlowForward, s_iPlayerId="<<s_iPlayerId<<", iSpeed="<<iSpeed<<endl;
	}
	else
	{
		cout<<"failure, SlowForward, s_iPlayerId="<<s_iPlayerId<<", iSpeed="<<iSpeed<<endl;
	}
}

void FastBackward()
{
	int iRet = RET_FAILED;
	if(INVALID_ID != s_iPlayerId)
	{
		iRet = CLS_AVPlaySdkApi::Instance()->FastBackward(s_iPlayerId);
	}

	if (RET_SUCCESS == iRet)
	{
		cout<<"success, FastBackward, s_iPlayerId="<<s_iPlayerId<<endl;
	}
	else
	{
		cout<<"failure, FastBackward, s_iPlayerId="<<s_iPlayerId<<endl;
	}
}

void Seek()
{
	int iRet = RET_FAILED;
	int iFrameNo = 0;
	if(INVALID_ID != s_iPlayerId)
	{
		cout<<"Please input Seek FrameNo: "<<endl;
		iFrameNo = get_cmd_int();
		iRet = CLS_AVPlaySdkApi::Instance()->Seek(s_iPlayerId, iFrameNo);
	}

	if (RET_SUCCESS == iRet)
	{
		cout<<"success, Seek, s_iPlayerId="<<s_iPlayerId<<", iSeekNo="<<iFrameNo<<endl;
	}
	else
	{
		cout<<"failure, Seek, s_iPlayerId="<<s_iPlayerId<<", iSeekNo="<<iFrameNo<<endl;
	}
}

void SetAudioVolume()
{
	int iRet = RET_FAILED;
	int iVolume = 0;
	if(INVALID_ID != s_iPlayerId)
	{
		cout<<"Please input Audio Volume(0-65535): "<<endl;
		iVolume = get_cmd_int();
		iRet = CLS_AVPlaySdkApi::Instance()->SetAudioVolumeEx(s_iPlayerId, iVolume);
	}

	if (RET_SUCCESS == iRet)
	{
		cout<<"success, SetAudioVolume, s_iPlayerId="<<s_iPlayerId<<", iVolume="<<iVolume<<endl;
	}
	else
	{
		cout<<"failure, SetAudioVolume, s_iPlayerId="<<s_iPlayerId<<", iVolume="<<iVolume<<endl;
	}
}

void GetAudioVolume()
{
	int iRet = RET_FAILED;
	unsigned short iVolume = 0;
	if(INVALID_ID != s_iPlayerId)
	{
		iRet = CLS_AVPlaySdkApi::Instance()->GetAudioVolumeEx(s_iPlayerId, iVolume);
	}

	if (RET_SUCCESS == iRet)
	{
		cout<<"success, GetAudioVolume, s_iPlayerId="<<s_iPlayerId<<", iVolume="<<iVolume<<endl;
	}
	else
	{
		cout<<"failure, GetAudioVolume, s_iPlayerId="<<s_iPlayerId<<", iVolume="<<iVolume<<endl;
	}
}

void CapturePicture()
{
	int iRet = RET_FAILED;
	int iCapType =  0;
	char cCapName[LEN_32] = "./CapPic."; 
	if(INVALID_ID != s_iPlayerId)
	{
		cout<<"Please input Capture Picture Type[1:bmp, 2:jpg]: "<<endl;
		iCapType = get_cmd_int();
		if(1 == iCapType)
		{
			strcat(cCapName, "bmp");
		}
		else
		{
			strcat(cCapName, "jpg");
		}
		iRet = CLS_AVPlaySdkApi::Instance()->CapturePicture(s_iPlayerId, iCapType, cCapName);
	}

	if (iRet >= RET_SUCCESS)
	{
		cout<<"success, CapturePicture, s_iPlayerId="<<s_iPlayerId<<", iCapType="<<iCapType<<endl;
	}
	else
	{
		cout<<"failure, CapturePicture, s_iPlayerId="<<s_iPlayerId<<", iCapType="<<iCapType<<endl;
	}
}

void StartCaptureFile()
{
	int iRet = RET_FAILED;
	char cFileName[LEN_32] = "./CaptureFile.sdv"; 
	if(INVALID_ID != s_iPlayerId)
	{
		iRet = CLS_AVPlaySdkApi::Instance()->StartCaptureFile(s_iPlayerId, cFileName, REC_FILE_TYPE_NORMAL);
	}

	if (RET_SUCCESS == iRet)
	{
		cout<<"success, StartCaptureFile, s_iPlayerId="<<s_iPlayerId<< ", FileName = " << cFileName << endl;
	}
	else
	{
		cout<<"failure, StartCaptureFile, s_iPlayerId="<<s_iPlayerId<< ", FileName = " << cFileName << endl;
	}
}

void StopCaptureFile()
{
	int iRet = RET_FAILED;
	if(INVALID_ID != s_iPlayerId)
	{
		iRet = CLS_AVPlaySdkApi::Instance()->StopCaptureFile(s_iPlayerId);
	}

	if (RET_SUCCESS == iRet)
	{
		cout<<"success, StopCaptureFile, s_iPlayerId="<<s_iPlayerId<< endl;
	}
	else
	{
		cout<<"failure, StopCaptureFile, s_iPlayerId="<<s_iPlayerId<< endl;
	}
}

void SetDecryptKey()
{
	int iRet = RET_FAILED;
	if(INVALID_ID != s_iPlayerId)
	{
		char cDecryptKey[LEN_1024] = {0};
		cout<<"Please inputDecrypt Key: "<<endl;
		cin >> cDecryptKey;
		iRet = CLS_AVPlaySdkApi::Instance()->SetVideoDecryptKey(s_iPlayerId, cDecryptKey, strlen(cDecryptKey));
	}

	if (RET_SUCCESS == iRet)
	{
		cout<<"success, SetDecryptKey, s_iPlayerId="<<s_iPlayerId<<endl;
	}
	else
	{
		cout<<"failure, SetDecryptKey, s_iPlayerId="<<s_iPlayerId<<endl;
	}
}

void GetStreamInfo()
{
	if(INVALID_ID != s_iPlayerId)
	{
		int iRet = -1;
		int iBegin = -1;
		int iEnd = -1;
		int iWidth = -1;
		int iHeight = -1;
		int iFrameRate = -1;
		char cFileName[LEN_1024] = {0};
		iRet = CLS_AVPlaySdkApi::Instance()->GetFrameRate(s_iPlayerId);						
		printf("[TC_GetFrameRate]:FrameRate = %d\n", iRet);
		iRet = CLS_AVPlaySdkApi::Instance()->GetPlayingFrameNum(s_iPlayerId);				
		printf("[TC_GetPlayingFrameNum]:FrameNum = %d\n", iRet);
		iRet = CLS_AVPlaySdkApi::Instance()->GetFrameCount(s_iPlayerId);						
		printf("[TC_GetFrameCount]:FrameCount = %d\n", iRet);
		iRet = CLS_AVPlaySdkApi::Instance()->GetCurFrameNo(s_iPlayerId);					
		printf("[TC_GetCurFrameNo]:CurFrameNo = %d\n", iRet);
		CLS_AVPlaySdkApi::Instance()->GetBeginEnd(s_iPlayerId, &iBegin, &iEnd);
		printf("[TC_GetBeginEnd]:iBegin = %d, iEnd = %d\n", iBegin, iEnd);
		CLS_AVPlaySdkApi::Instance()->GetFileName(s_iPlayerId, cFileName);
		printf("[TC_GetFileName]:cFileName = %s\n", cFileName);
		CLS_AVPlaySdkApi::Instance()->GetVideoParam(s_iPlayerId, &iWidth, &iHeight, &iFrameRate);
		printf("[TC_GetVideoParam]:iWidth = %d, iHeight = %d, iFrameRate = %d\n", iWidth, iHeight, iFrameRate);
		iRet = CLS_AVPlaySdkApi::Instance()->GetPlayTime(s_iPlayerId);
		printf("[TC_GetPlayTime]:PlayTime = %d\n", iRet);
		iRet = CLS_AVPlaySdkApi::Instance()->GetFrameListCount(s_iPlayerId);
		printf("[TC_GetFrameListCount]:FrameListCount = %d\n", iRet);
	}
}

void SetAVMode()
{
	int iRet = RET_FAILED;
	if(INVALID_ID != s_iPlayerId)
	{
		int iVideoShowMode = -1;
		int iShowMode = -1;
		cout <<"Please Input Video Show Mode:" << endl;
		iVideoShowMode = get_cmd_int();

		cout <<"Please Input Show Mode:" << endl;
		iShowMode = get_cmd_int();
		iRet = CLS_AVPlaySdkApi::Instance()->SetAVMode(iVideoShowMode, &iShowMode, sizeof(int));
	}

	if (RET_SUCCESS == iRet)
	{
		cout<<"success, SetAVMode, s_iPlayerId="<<s_iPlayerId<<endl;
	}
	else
	{
		cout<<"failure, SetAVMode, s_iPlayerId="<<s_iPlayerId<<endl;
	}
}

int CommonEventNotify(int _iPlayerID, int _iEventMessage, void* _pvUsrData)
{
	if (_iPlayerID != s_iPlayerId)
	{
		return -1;
	}

	switch(_iEventMessage)
	{
	case LPARAM_NEED_DECRYPT_KEY:
		cout<<"CommonEventNotify, _iPlayerID="<<_iPlayerID<<", RecvMsg:LPARAM_NEED_DECRYPT_KEY"<<endl;
		break;
	case LPARAM_DECRYPT_KEY_FAILED:
		cout<<"CommonEventNotify, _iPlayerID="<<_iPlayerID<<", RecvMsg:LPARAM_DECRYPT_KEY_FAILED"<<endl;
		break;
	case LPARAM_DECRYPT_SUCCESS:
		cout<<"CommonEventNotify, _iPlayerID="<<_iPlayerID<<", RecvMsg:LPARAM_DECRYPT_SUCCESS"<<endl;
		break;
	case LPARAM_FILE_SEARCH_END:
		//cout<<"CommonEventNotify, _iPlayerID="<<_iPlayerID<<", RecvMsg:LPARAM_FILE_SEARCH_END"<<endl;
		break;
	case LPARAM_STREAM_SEARCH_END:
		//cout<<"CommonEventNotify, _iPlayerID="<<_iPlayerID<<", RecvMsg:LPARAM_STREAM_SEARCH_END"<<endl;
		break;

	default:
		break;
	}

	return 0;
}

void DecodeYuvNofify(unsigned int _uiID, unsigned char* _pucData, int _iLen, const FRAME_INFO* _ptFrmInfo, void* _pvUser)
{
	//if (NULL != s_pfYuvFile)
	//{
	//	int iWriteLen = (int)fwrite(_pucData, sizeof(unsigned char), _iLen, s_pfYuvFile);
	//	if (iWriteLen < _iLen)
	//	{
	//		cout <<"DecodeYuvNofify write data fai!iWriLen=" <<iWriteLen<<endl;
	//	}
	//}
}

void PlayEndFun(int _iPlayerID)
{
	if (_iPlayerID != s_iPlayerId)
	{
		return;
	}

	//cout<<"_iPlayerID="<<_iPlayerID<<", Recv:PlayEndFun"<<endl;
}

void GetPlayTime()
{
	int iRet = RET_FAILED;
	if(INVALID_ID != s_iPlayerId)
	{
		iRet = CLS_AVPlaySdkApi::Instance()->GetPlayTime(s_iPlayerId);
	}

	if (iRet >= 0)
	{
		unsigned int iBeg = 0, iEnd = 0;
		CLS_AVPlaySdkApi::Instance()->GetBeginEndTimeStamp(s_iPlayerId, &iBeg, &iEnd);
		char cPlayTime[32] = {0};
		int iPlayTime = iRet/1000;
		int iTotalTime = (iEnd - iBeg)/1000;
		sprintf(cPlayTime, "%02d:%02d:%02d / %02d:%02d:%02d", iPlayTime/3600, iPlayTime/60, iPlayTime%60, iTotalTime/3600, iTotalTime/60, iTotalTime%60);
		cout<<"success, GetPlayTime, s_iPlayerId="<<s_iPlayerId<<", playTime="<<cPlayTime<<"\r\n" << endl;
	}
	else
	{
		cout<<"failure, StopCaptureFile, s_iPlayerId="<<s_iPlayerId<< endl;
	}
}


