Explorar el Código

Merge branch '0_0_3_st1' into release

gifur hace 4 años
padre
commit
8239909964
Se han modificado 62 ficheros con 2036 adiciones y 1341 borrados
  1. 62 52
      DevAdapter/include/CardAssist.cpp
  2. 2 2
      DevAdapter/include/CardAssist.h
  3. 1 1
      Module/CMakeLists.txt
  4. 8 1
      Module/mod_CameraConfigManage/mod_CameraConfigManage.h
  5. 19 14
      Module/mod_ContactlessCard/ContactlessFSM.cpp
  6. 5 0
      Module/mod_ContactlessCard/ContactlessFSM.h
  7. 1 0
      Module/mod_assistantchannel/chan_protocol.h
  8. 54 22
      Module/mod_cardissuer/CardIssuerFSM.cpp
  9. 5 0
      Module/mod_cardissuer/CardIssuerFSM.h
  10. 69 6
      Module/mod_cardswiper/CardSwiperFSM.cpp
  11. 5 0
      Module/mod_cardswiper/CardSwiperFSM.h
  12. 16 0
      Module/mod_interactivecontrol/InteractiveControl.xml
  13. 125 0
      Module/mod_interactivecontrol/InteractiveControl_client_g.h
  14. 103 0
      Module/mod_interactivecontrol/InteractiveControl_def_g.h
  15. 18 0
      Module/mod_interactivecontrol/InteractiveControl_msg_g.h
  16. 125 0
      Module/mod_interactivecontrol/InteractiveControl_server_g.h
  17. 225 2
      Module/mod_interactivecontrol/mod_interactivecontrol.cpp
  18. 0 6
      Module/mod_mediacontroller/CMakeLists.txt
  19. 0 79
      Module/mod_mediacontroller/audiocapobj.cpp
  20. 0 27
      Module/mod_mediacontroller/audiocapobj.h
  21. 21 19
      Module/mod_mediacontroller/capture.cpp
  22. 6 7
      Module/mod_mediacontroller/capture.h
  23. 15 5
      Module/mod_mediacontroller/mod_mediacontroller.cpp
  24. 0 89
      Module/mod_mediacontroller/videocapobj.cpp
  25. 0 28
      Module/mod_mediacontroller/videocapobj.h
  26. 4 4
      Module/mod_recorder/mod_recorder.cpp
  27. 0 4
      Module/mod_sipphone/CMakeLists.txt
  28. 115 0
      Module/mod_sipphone/SIPPhone_client_g.h
  29. 86 0
      Module/mod_sipphone/SIPPhone_def_g.h
  30. 100 0
      Module/mod_sipphone/SIPPhone_server_g.h
  31. 28 0
      Module/mod_sipphone/SipService.xml
  32. 0 91
      Module/mod_sipphone/audio_manager.cpp
  33. 0 28
      Module/mod_sipphone/audio_manager.h
  34. 10 2
      Module/mod_sipphone/audio_session.cpp
  35. 149 2
      Module/mod_sipphone/mod_sipphone.cpp
  36. 7 2
      Module/mod_sipphone/mod_sipphone.h
  37. 32 14
      Module/mod_sipphone/video_session.cpp
  38. 0 75
      Module/mod_sipphone/videorenderobj.cpp
  39. 0 23
      Module/mod_sipphone/videorenderobj.h
  40. 1 3
      Other/libaudiomgr/iaudiomgrinterface.cpp
  41. 8 7
      Other/libaudiomgr/iaudiomgrinterface.h
  42. 63 258
      Other/libaudiomgr/linux/libaudiomgr_linux.cpp
  43. 6 6
      Other/libaudiomgr/linux/libaudiomgr_linux.h
  44. 8 10
      Other/libaudions/CMakeLists.txt
  45. 2 2
      Other/libaudions/iaudionsinterface.cpp
  46. 13 3
      Other/libaudions/iaudionsinterface.h
  47. 27 17
      Other/libaudions/libaudions.cpp
  48. 3 1
      Other/libaudions/libaudions.h
  49. 1 1
      Other/libvideocapture/ivideocaptureinterface.cpp
  50. 9 8
      Other/libvideocapture/ivideocaptureinterface.h
  51. 134 204
      Other/libvideocapture/linux/videocapture_linux.cpp
  52. 14 7
      Other/libvideocapture/linux/videocapture_linux.h
  53. 2 2
      Other/libvideorender/CMakeLists.txt
  54. 2 2
      Other/libvideorender/ivideorenderinterface.cpp
  55. 19 7
      Other/libvideorender/ivideorenderinterface.h
  56. 171 58
      Other/libvideorender/libvideorender.cpp
  57. 9 6
      Other/libvideorender/libvideorender.h
  58. 48 77
      Other/libwmvrecord/FFmpegWriter.cpp
  59. 7 7
      Other/libwmvrecord/FFmpegWriter.h
  60. 1 1
      Other/libwmvrecord/WmvWriter.h
  61. 63 47
      Other/libwmvrecord/libwmvrecord.cpp
  62. 9 2
      Plugins/MediaDevDetectBasePulse/mainform.cpp

+ 62 - 52
DevAdapter/include/CardAssist.cpp

@@ -2249,7 +2249,7 @@ int CCardProcess::SplitOnlineReplyData(const char *pData,int size)
 	}
 	return 0;
 }
-int CCardProcess::DetectAndReadICData(CardReadType eType, DeviceBaseClass *pCardX, const char *pAID, int &cardType)
+int CCardProcess::DetectAndReadICData(CardReadType eType, DeviceBaseClass* pCardX, CAutoArray<CSimpleStringA>pAIDs, int& cardType)
 {
 	LOG_FUNCTION();
 	bool bIC = DetectIfICCard(eType,pCardX,cardType);
@@ -2258,7 +2258,8 @@ int CCardProcess::DetectAndReadICData(CardReadType eType, DeviceBaseClass *pCard
 		Dbg("not ic card.");
 		return -1;
 	}
-	bool bGetICData = GetICDataFromCard(eType,pCardX,pAID);
+	bool bGetICData = false;
+	bGetICData = GetICDataFromCard(eType, pCardX, pAIDs);
 	if (!bGetICData)
 	{
 		Dbg("GetICDataFromCard failed.");
@@ -2268,64 +2269,73 @@ int CCardProcess::DetectAndReadICData(CardReadType eType, DeviceBaseClass *pCard
 
 	return 0;
 }
-bool CCardProcess::GetICDataFromCard(CardReadType eType,DeviceBaseClass *pCardX,const char *pAID)
+bool CCardProcess::GetICDataFromCard(CardReadType eType, DeviceBaseClass* pCardX, CAutoArray<CSimpleStringA> pAIDs)
 {
 	LOG_FUNCTION();
-	//暂时只有一个,需要改成通用处理么。。。oiltmp
-	//aidflag ? oiltmp
 	AIDData aidData;
 	aidData.aid = new BYTE[32];//oiltmp
-	memset(aidData.aid,0,32);
-	int aidLen = StrBuf2HexBuf(pAID,&aidData.aid);
-	Dbg("str2hex len[%d]",aidLen);
-	aidData.len = aidLen;
-	char* aidTest = new char[128];
-	//char* aidTest2 = new char[128];
-	//memset(aidTest2,0,128);
-	//memcpy(aidTest2,aidData.aid,10);
-	int aidStrLen = HexBuf2StrBuf(aidData.aid,&aidTest,5);
-	Dbg("hex2str len[%d]",aidStrLen);
-	Dbg("aid[%s][%s]",pAID,aidTest);
-	vector<AIDData> vAIDs;
-	vAIDs.push_back(aidData);
-	//ErrorCodeEnum eErr = BuildSupportedAppList(vAIDs);
-
-	ErrorCodeEnum eErr = Error_Unexpect;
-	if (eType == CARD_MACHINE_ISSUER)
-	{
-		pCardI = dynamic_cast<CardIssuerClass*>(pCardX);
-	}
-	else if (eType == CARD_MACHINE_SWIPER || eType == CARD_MACHINE_SWIPER_RF)
-	{
-		pCardS = dynamic_cast<CardSwiperClass*>(pCardX);
-	}
-	else if (eType == CARD_MACHINE_RFIC)
-	{
-		pCardR = dynamic_cast<RFICClass*>(pCardX);
-	}
-	eErr = BuildSupportedAppList(eType,pCardX,vAIDs);
-	if (eErr != Error_Succeed)
+	memset(aidData.aid, 0, 32);
+	for (int index = 0; index < pAIDs.GetCount(); ++index)
 	{
-		DevErrorInfo devErr;
-		ZeroMemory(devErr.szErrMsg, sizeof(devErr.szErrMsg));
+		int aidLen = StrBuf2HexBuf(pAIDs[index].GetData(), &aidData.aid);
+
+		Dbg("str2hex len[%d]", aidLen);
+		aidData.len = aidLen;
+		char* aidTest = new char[128];
+		int aidStrLen = HexBuf2StrBuf(aidData.aid, &aidTest, 5);
+		Dbg("hex2str len[%d]", aidStrLen);
+		Dbg("aid[%s][%s]", pAIDs[index].GetData(), aidTest);
+		vector<AIDData> vAIDs;
+		vAIDs.push_back(aidData);
+
+		ErrorCodeEnum eErr = Error_Unexpect;
 		if (eType == CARD_MACHINE_ISSUER)
-			pCardI->GetLastErr(devErr);
-		else if (eType == CARD_MACHINE_SWIPER)
-			pCardS->GetLastErr(devErr);
+		{
+			pCardI = dynamic_cast<CardIssuerClass*>(pCardX);
+		}
+		else if (eType == CARD_MACHINE_SWIPER || eType == CARD_MACHINE_SWIPER_RF)
+		{
+			pCardS = dynamic_cast<CardSwiperClass*>(pCardX);
+		}
 		else if (eType == CARD_MACHINE_RFIC)
-			pCardR->GetLastErr(devErr);
-		Dbg("BuildSupportedAppList failed %d, %s.",eErr,devErr.szErrMsg);
-		return false;
-	}
-	//Dbg("[%s]",testIC);
-	eErr = AppSelected(eType,pCardX,vAIDs.at(0).aid,vAIDs.at(0).len);
-	if (eErr == Error_Succeed)
-		return true;
-	else
-	{
-		Dbg("AppSelected failed(%d).",eErr);
-		return false;
+		{
+			pCardR = dynamic_cast<RFICClass*>(pCardX);
+		}
+		eErr = BuildSupportedAppList(eType, pCardX, vAIDs);
+
+		Dbg("size = %d", vAIDs.size());
+		for (size_t i = 0; i < vAIDs.size(); ++i)
+		{
+			char* aidTest1 = new char[128];
+			int aidlen = HexBuf2StrBuf(vAIDs[i].aid, &aidTest1, vAIDs[i].len);
+			Dbg("aidTest = %s", aidTest1);
+			delete[] aidTest1;
+		}
+
+		if (eErr != Error_Succeed)
+		{
+			DevErrorInfo devErr;
+			ZeroMemory(devErr.szErrMsg, sizeof(devErr.szErrMsg));
+			if (eType == CARD_MACHINE_ISSUER)
+				pCardI->GetLastErr(devErr);
+			else if (eType == CARD_MACHINE_SWIPER)
+				pCardS->GetLastErr(devErr);
+			else if (eType == CARD_MACHINE_RFIC)
+				pCardR->GetLastErr(devErr);
+			Dbg("BuildSupportedAppList failed %d, %s.", eErr, devErr.szErrMsg);
+			continue;
+		}
+		//Dbg("[%s]",testIC);
+		eErr = AppSelected(eType, pCardX, vAIDs.at(0).aid, vAIDs.at(0).len);
+		if (eErr == Error_Succeed)
+			return true;
+		else
+		{
+			Dbg("AppSelected failed(%d).", eErr);
+			continue;
+		}
 	}
+	return false;
 }
 int CCardProcess::ConstructARQCData(const char *pATC, char *&pDataToARQC, char *&pSomeICData)
 {

+ 2 - 2
DevAdapter/include/CardAssist.h

@@ -52,7 +52,7 @@ public:
 	~CCardProcess();
 	void DataInit();
 	bool DetectIfICCard(CardReadType eType,DeviceBaseClass *pCardX,int &cardType);//cardType:0x41'A',type A; 0x42'B',type B; 0x4d'M',type M
-	bool GetICDataFromCard(CardReadType eType,DeviceBaseClass *pCardX,const char *pAID);
+	bool GetICDataFromCard(CardReadType eType, DeviceBaseClass* pCardX, CAutoArray<CSimpleStringA> pAIDs);
 	//int  SplitICData(vector<ICData>& vResult,LPBYTE* origData,int start,int dataLen,int level);
 	ErrorCodeEnum BuildSupportedAppList(CardReadType eType,DeviceBaseClass *pCardX,vector<AIDData>& vAIDFromTerm);
 	ErrorCodeEnum BuildAppListByAIDs(CardReadType eType,DeviceBaseClass *pCardX,vector<AIDData>& vAIDFromTerm);
@@ -69,7 +69,7 @@ public:
 	void SplitBusinessData(const char *pData,int size);
 	int SplitOnlineReplyData(const char *pData,int size);
 	void GetBaseInfoNotInRecord(CardReadType eType,DeviceBaseClass *pCardX);
-	int DetectAndReadICData(CardReadType eType,DeviceBaseClass *pCardX,const char *pAID,int &cardType);
+	int DetectAndReadICData(CardReadType eType, DeviceBaseClass* pCardX, CAutoArray<CSimpleStringA>pAIDs, int& cardType);
 	int ConstructARQCData(const char *pATC,char *&pDataToARQC,char *&pSomeICData);
 	int FindTagValue(TagVectorType eType,ICData& data,bool bLevel,int start=0,int end=0);
 	int ToFindTagValue(vector<ICData>& vData,ICData& data,bool bLevel,int start,int end);

+ 1 - 1
Module/CMakeLists.txt

@@ -148,7 +148,7 @@ if(MSVC)
     BASIC_SETUP CMAKE_TARGETS)
     set(MODULE_CONAN_DEP_LIBS ${CONAN_BIN_DIRS_MISC})
 else()
-    conan_cmake_run(REQUIRES Misc/2020.1211.1@LR04.02_ModuleDep/UOS
+    conan_cmake_run(REQUIRES Misc/2021.1105.1@LR04.02_ModuleDep/UOS
     BASIC_SETUP CMAKE_TARGETS)
     set(MODULE_CONAN_DEP_LIBS ${CONAN_BIN_DIRS_MISC} ${CONAN_LIB_DIRS_MISC} )
 endif(MSVC)

+ 8 - 1
Module/mod_CameraConfigManage/mod_CameraConfigManage.h

@@ -25,6 +25,11 @@
 
 using namespace MediaController;
 
+static void __audiomgrlog(void* user_data, const char* fmt, va_list arg)
+{
+	vDbg(fmt, arg);
+}
+
 namespace CameraConfigManage {
 
 	typedef struct
@@ -113,7 +118,9 @@ namespace CameraConfigManage {
 			, m_bStartCamera(FALSE), 
 			m_bEchoVideo(FALSE), m_lCaptureCount(0),mlibAudioMgr(NULL)
 		{
-			mlibAudioMgr = CreateAudioMgrObj(NULL);
+			audiomgr_callback_t t_callback = { 0 };
+			t_callback.debug = &__audiomgrlog;
+			mlibAudioMgr = CreateAudioMgrObj(&t_callback);
 		}
 
 		virtual ~CCameraConfigManageEntity() { 

+ 19 - 14
Module/mod_ContactlessCard/ContactlessFSM.cpp

@@ -799,14 +799,12 @@ int CContactlessCardFSM::AcceptCard(SpReqAnsContext<ContactlessCardService_Inser
             int retDetectAndRead = -1;
             if (!ctx->Req.aid.IsNullOrEmpty()) {
                 Dbg("aid:[%s]", (const char*)ctx->Req.aid);
-                retDetectAndRead = m_pCardProcess->DetectAndReadICData(CARD_MACHINE_RFIC, m_hDevHelper, ctx->Req.aid, activeCardType);
+				CAutoArray<CSimpleStringA> aidReq;
+				aidReq.Init(1);
+				aidReq[0] = ctx->Req.aid;
+                retDetectAndRead = m_pCardProcess->DetectAndReadICData(CARD_MACHINE_RFIC, m_hDevHelper, aidReq, activeCardType);
             } else {
-                retDetectAndRead = m_pCardProcess->DetectAndReadICData(CARD_MACHINE_RFIC, m_hDevHelper, "A000000333", activeCardType);
-                if (retDetectAndRead < -1)//-1:DetectIfICCard failed; -2:select app failed
-                {
-                    Dbg("Can't read pboc record, to try emv...");
-                    retDetectAndRead = m_pCardProcess->DetectAndReadICData(CARD_MACHINE_RFIC, m_hDevHelper, "A0000000108888", activeCardType);
-                }
+				retDetectAndRead = m_pCardProcess->DetectAndReadICData(CARD_MACHINE_RFIC, m_hDevHelper, m_aidList, activeCardType);
             }
 
             if (retDetectAndRead < 0) {
@@ -828,6 +826,7 @@ int CContactlessCardFSM::AcceptCard(SpReqAnsContext<ContactlessCardService_Inser
                 ZeroMemory(pICTrack2, 128);
                 HexBuf2StrBuf(track2.value, &pICTrack2, track2.lenth);
                 pICTrack2[37] = '\0';
+				Dbg("pICTrack2 = %s", pICTrack2);
 
                 char* ddd = new char[128];
                 memset(ddd, 0, 128);
@@ -836,6 +835,7 @@ int CContactlessCardFSM::AcceptCard(SpReqAnsContext<ContactlessCardService_Inser
                 t2ICTrack2 = pICTrack2;
                 t2ICAccount = (char*)ddd;//oiltest
                 Dbg("contactless card countcount:%s,%s", t2ICAccount.substr(0, 6).c_str(), t2ICAccount.substr(t2ICAccount.length() - 4, 4).c_str());
+				Dbg("account = %s", t2ICAccount.c_str());
                 ctx->Ans.ICData = ctx->Ans.t2Account = t2ICAccount.c_str();
                 ctx->Ans.ICType = 4;
                 ctx->Ans.status = 0;
@@ -895,6 +895,13 @@ int CContactlessCardFSM::SplitTrack2(CSimpleStringA pTrack2, Track2Data& decodeD
         decodeData.t2Region = pTrack2.SubString(23, 4);
         decodeData.t2ExpireDate = pTrack2.SubString(27, 4);
         break;
+	case 25://AE Card
+		decodeData.t2Account = CSimpleString(pTrack2, 15);
+		decodeData.t2CardSerial = pTrack2.SubString(15, 1);
+		decodeData.t2CVC = pTrack2.SubString(16, 5);
+		decodeData.t2ExpireDate = pTrack2.SubString(21, 4);
+		decodeData.t2Region = "";
+		break;
     case 38:
         break;
     default:
@@ -919,18 +926,16 @@ int CContactlessCardFSM::PreOnline(SpReqAnsContext<ContactlessCardService_PreOnl
     ICData aidFromBus(false, 0x4f, 0x00);
     if (m_pCardProcess->FindTagValue(TAG_VECTOR_BUS, aidFromBus, false, 0) == -1) {
         Dbg("the front BusinessData han't provide aid data.");
-        retDetectAndRead = m_pCardProcess->DetectAndReadICData(CARD_MACHINE_RFIC, m_hDevHelper, "A000000333", activeCardType);
-        if (retDetectAndRead < -1)//-1:DetectIfICCard failed; -2:select app failed
-        {
-            Dbg("Can't read pboc record,to try emv...");
-            retDetectAndRead = m_pCardProcess->DetectAndReadICData(CARD_MACHINE_RFIC, m_hDevHelper, "A0000000108888", activeCardType);
-        }
+		retDetectAndRead = m_pCardProcess->DetectAndReadICData(CARD_MACHINE_RFIC, m_hDevHelper, m_aidList, activeCardType);
     } else {
         char* pAIDTmp = new char[64];
         memset(pAIDTmp, 0, 64);
         HexBuf2StrBuf(aidFromBus.value, &pAIDTmp, aidFromBus.lenth);
         Dbg("the aid is[%s],len:%d .", pAIDTmp, strlen(pAIDTmp));
-        retDetectAndRead = m_pCardProcess->DetectAndReadICData(CARD_MACHINE_RFIC, m_hDevHelper, pAIDTmp, activeCardType);
+		CAutoArray<CSimpleString> preAIDs;
+		preAIDs.Init(1);
+		preAIDs[0] = (CSimpleStringA)pAIDTmp;
+		retDetectAndRead = m_pCardProcess->DetectAndReadICData(CARD_MACHINE_RFIC, m_hDevHelper, preAIDs, activeCardType);
         if (pAIDTmp != NULL)
             delete[]pAIDTmp;
     }

+ 5 - 0
Module/mod_ContactlessCard/ContactlessFSM.h

@@ -220,6 +220,10 @@ public:
         //,m_pTACReject(NULL),m_pIACOnline(NULL),m_pTACOnline(NULL),m_pIACDefault(NULL),m_pTACDefault(NULL)
         , m_bCDA(false), m_pDataToARQC(NULL), m_bSM(false), m_bOnlineOnly(false)
     {
+		m_aidList.Init(3);
+		m_aidList[0] = "A000000333";
+		m_aidList[1] = "A0000000108888";
+		m_aidList[2] = "A000000790";
     }
     ~CContactlessCardFSM() {}
     virtual ErrorCodeEnum OnInit();
@@ -296,6 +300,7 @@ private:
     CCardProcess* m_pCardProcess;
     char* m_pDataToARQC;
     long xxTest;
+	CAutoArray<CSimpleStringA> m_aidList;
 
     char m_AuthCode[2];
     bool m_bOnlineOnly, m_bCDA;

+ 1 - 0
Module/mod_assistantchannel/chan_protocol.h

@@ -22,6 +22,7 @@
 #define ACM_TYPE_CALLTRANS	0x000d	//呼叫转移
 #define ACM_TYPE_VIDEOFREQ	0x000e	//视频帧频
 #define ACM_TYPE_AGENTVIDEOTYPE  0x000f	//坐席视频类型,单/双向
+#define ACM_TYPE_H5_SYNC  0x0010	//H5窗体同步
 
 #define ACM_ERROR_NONE		0x01
 #define ACM_ERROR_CORRUPT	0x02

+ 54 - 22
Module/mod_cardissuer/CardIssuerFSM.cpp

@@ -3060,6 +3060,7 @@ int CCardIssuerFSM::SplitTrack2(CSimpleStringA pTrack2,Track2Data &decodeData)
 	if (pTrack2.GetLength() == 0)
 		return -1;
 	int dataLen = strlen(pTrack2);
+	Dbg("pTrack2 = %s", pTrack2.GetData());
 	Dbg("pT2.len:%d",dataLen);
 	switch(dataLen)
 	{
@@ -3077,6 +3078,13 @@ int CCardIssuerFSM::SplitTrack2(CSimpleStringA pTrack2,Track2Data &decodeData)
 		decodeData.t2Region = pTrack2.SubString(23,4);
 		decodeData.t2ExpireDate = pTrack2.SubString(27,4);
 		break;
+	case 25://AE Card
+		decodeData.t2Account = CSimpleString(pTrack2, 15);
+		decodeData.t2CardSerial = pTrack2.SubString(15, 1);
+		decodeData.t2CVC = pTrack2.SubString(16, 5);
+		decodeData.t2ExpireDate = pTrack2.SubString(21, 4);
+		decodeData.t2Region = "";
+		break;
 	case 38:
 		break;
 	default:
@@ -3185,12 +3193,15 @@ int CCardIssuerFSM::ReadCard(SpReqAnsContext<CardIssuerService_Read_Req,CardIssu
 	int readTries = 0;
 	memset(magTracks.track[0].data, 0, sizeof(magTracks.track[0].data));
 	memset(magTracks.track[1].data, 0, sizeof(magTracks.track[1].data));
-	memset(magTracks.track[2].data, 0, sizeof(magTracks.track[3].data));
+	memset(magTracks.track[2].data, 0, sizeof(magTracks.track[2].data));
 	{
 		magTracks.eRange = CI_TRACK_RANGE_2_3;
 		do {
 			eErr = m_pCardIssuer->MagRead(magTracks);
 			Dbg("MAGread(%d)...",eErr);
+			Dbg("track1 = %s", (const char*)magTracks.track[0].data);
+			Dbg("track2 = %s", (const char*)magTracks.track[1].data);
+			Dbg("track3 = %s", (const char*)magTracks.track[2].data);
 			ctx->Ans.t2Account = ctx->Ans.ICData = "";
 			//DevErrorInfo devErrInfo;
 			//m_pCardIssuer->GetLastErr(devErrInfo);
@@ -3251,8 +3262,11 @@ int CCardIssuerFSM::ReadCard(SpReqAnsContext<CardIssuerService_Read_Req,CardIssu
 				int pos = 0;
 				for (int i = 0; i < magTracks.track[1].dwSize; ++i,++pos)
 				{
-					if (magTracks.track[1].data[i] == 0x3d || magTracks.track[1].data[i] == 0x3e)
-						break;
+					// fixpoint (3d是=,3e是 >), 运通卡要考虑分隔符为D的情况
+					if (magTracks.track[1].data[i] == 0x3d 
+						|| magTracks.track[1].data[i] == 0x3e 
+						|| magTracks.track[1].data[i] == 0x44)
+					break;
 				}
 				Dbg("pos:%d,%d",pos,magTracks.track[1].dwSize);
 				if (pos <= 0 || pos == magTracks.track[1].dwSize)
@@ -3307,6 +3321,7 @@ int CCardIssuerFSM::ReadCard(SpReqAnsContext<CardIssuerService_Read_Req,CardIssu
 					tmpMag2 = NULL;
 				}
 				Dbg("%s,%s", (LPCTSTR)ctx->Ans.t2Account.SubString(0, 6), (LPCTSTR)ctx->Ans.t2Account.SubString(ctx->Ans.t2Account.GetLength() - 4, 4));
+				Dbg("account = %s", ctx->Ans.t2Account.GetData());
 				break;
 			}
 			else
@@ -3574,19 +3589,17 @@ int CCardIssuerFSM::PreOnline(SpReqAnsContext<CardIssuerService_PreOnline_Req,Ca
 	{
 		Dbg("the front BusinessData han't provide aid data.");
 
-		retDetectAndRead = m_pCardProcess->DetectAndReadICData(CARD_MACHINE_ISSUER, m_pCardIssuer, "A000000333", activeCardType);
-		if (retDetectAndRead < -1)//-1:DetectIfICCard failed; -2:select app failed
-		{
-			Dbg("Can't read pboc record,to try emv...");
-			retDetectAndRead = m_pCardProcess->DetectAndReadICData(CARD_MACHINE_ISSUER, m_pCardIssuer, "A0000000108888", activeCardType);
-		}
+		retDetectAndRead = m_pCardProcess->DetectAndReadICData(CARD_MACHINE_ISSUER, m_pCardIssuer, m_aidList, activeCardType);
 	}
 	else {
 		char* pAIDTmp = new char[64];
 		memset(pAIDTmp, 0, 64);
 		HexBuf2StrBuf(aidFromBus.value, &pAIDTmp, aidFromBus.lenth);
 		Dbg("the aid is[%s],len:%d .", pAIDTmp,strlen(pAIDTmp));
-		retDetectAndRead = m_pCardProcess->DetectAndReadICData(CARD_MACHINE_ISSUER, m_pCardIssuer, pAIDTmp, activeCardType);
+		CAutoArray<CSimpleString> preAIDs;
+		preAIDs.Init(1);
+		preAIDs[0] = (CSimpleStringA)pAIDTmp;
+		retDetectAndRead = m_pCardProcess->DetectAndReadICData(CARD_MACHINE_ISSUER, m_pCardIssuer, preAIDs, activeCardType);
 		if (pAIDTmp != NULL)
 			delete[]pAIDTmp;
 	}
@@ -3688,6 +3701,7 @@ int CCardIssuerFSM::PreOnline(SpReqAnsContext<CardIssuerService_PreOnline_Req,Ca
 		ZeroMemory(pICTrack2,128);
 		HexBuf2StrBuf(track2.value,&pICTrack2,track2.lenth);
 		pICTrack2[37] = '\0';
+		Dbg("zjw pICTrack2 = %s", pICTrack2);
 		Dbg("ic.track2,pos:%d",pos);
 		Dbg("pos:%d",pos);
 
@@ -3709,9 +3723,11 @@ int CCardIssuerFSM::PreOnline(SpReqAnsContext<CardIssuerService_PreOnline_Req,Ca
 		track2Data.status = 0;
 		track2Data.t2Account = "";
 		cmdDecodeMag2(pICTrack2,icTrack2Data);
+		Dbg("zjw icTrack2Data = %s", icTrack2Data);
 		if (SplitTrack2(icTrack2Data,track2Data) == 0)
 		{
 			t2ICAccount = track2Data.t2Account;
+			Dbg("zjw t2ICAccount = %s", t2ICAccount.c_str());
 			//t2ICCardSerial = track2Data.t2CardSerial;
 			t2ICCVC = track2Data.t2CVC;
 			t2ICTrack2 = pICTrack2;
@@ -4805,11 +4821,7 @@ bool CCardIssuerFSM::JustReadCardNo()
 	{
 		//oilyang@20201014 add emv support
 		bool bGetICData = false;
-		bGetICData = m_pCardProcess->GetICDataFromCard(CARD_MACHINE_ISSUER, m_pCardIssuer, "A000000333");
-		if (!bGetICData)
-		{
-			bGetICData = m_pCardProcess->GetICDataFromCard(CARD_MACHINE_ISSUER, m_pCardIssuer, "A0000000108888");
-		}
+		bGetICData = m_pCardProcess->GetICDataFromCard(CARD_MACHINE_ISSUER, m_pCardIssuer, m_aidList);
 		ICData track2(false, 0x57, 0x00);
 		string t2ICAccount(""), t2ICCardSerial(""), t2ICCVC(""), t2ICTrack2(""), cardType;
 		if (m_pCardProcess->FindTagValue(TAG_VECTOR_IC, track2, false, 0) == -1)
@@ -4847,7 +4859,10 @@ bool CCardIssuerFSM::JustReadCardNo()
 				int pos = 0;
 				for (int i = 0; i < magTracks.track[1].dwSize; ++i, ++pos)
 				{
-					if (magTracks.track[1].data[i] == 0x3d || magTracks.track[1].data[i] == 0x3e)
+					//运通卡考虑 = 和 D 
+					if (magTracks.track[1].data[i] == 0x3d ||
+						magTracks.track[1].data[i] == 0x3e ||
+						magTracks.track[1].data[i] == 0x44) 
 						break;
 				}
 				Dbg("pos:%d", pos);
@@ -6256,6 +6271,12 @@ int CCardIssuerFSM::IssueCardFromStore(SpReqAnsContext<CardIssuerService_IssueEx
 		ctx->Ans.reserved1.Init(3);
 		ctx->Ans.reserved2.Init(2);
 		eErr = m_pCardIssuer->ReadAccount(card);
+		Dbg("card.account = %s", card.account);
+		Dbg("card.dwsize = %d", card.dwSize);
+		Dbg("card.dwTrack2Size = %d", card.dwTrack2Size);
+		Dbg("card.track2 = %s", card.track2);
+		Dbg("card.dwTrack3Size = %d", card.dwTrack3Size);
+		Dbg("card.track3 = %s", card.track3);
 		if (eErr == Error_Succeed && ctx->Req.reserved2[0].GetLength() == card.dwSize && strncmp(card.account, ctx->Req.reserved2[0], card.dwSize) == 0)
 		{
 			Dbg("ReadAccount ok.");
@@ -6407,6 +6428,12 @@ int CCardIssuerFSM::AddCardToStoreStepFirst(SpReqAnsContext<CardIssuerService_Is
 		CardNo card;
 		ctx->Ans.reserved2[0] = "";
 		eErr = m_pCardIssuer->ReadAccount(card);
+		Dbg("card.account = %s", card.account);
+		Dbg("card.dwsize = %d", card.dwSize);
+		Dbg("card.dwTrack2Size = %d", card.dwTrack2Size);
+		Dbg("card.track2 = %s", card.track2);
+		Dbg("card.dwTrack3Size = %d", card.dwTrack3Size);
+		Dbg("card.track3 = %s", card.track3);
 		bool bDataOK = true;//oilyang@20171213 是否读卡失败,是否解析出卡序号,否则吞卡 @宋锐
 		if (eErr == Error_Succeed && card.dwSize > 0 && card.dwSize < 64)
 		{
@@ -6612,6 +6639,12 @@ bool CCardIssuerFSM::OperateCardStore(CSmartPointer<IConfigInfo> &spConfigRun, i
 		CardNo card;
 		ZeroMemory(card.account, sizeof(card.account));
 		eErr = m_pCardIssuer->ReadAccount(card);
+		Dbg("card.account = %s", card.account);
+		Dbg("card.dwsize = %d", card.dwSize);
+		Dbg("card.dwTrack2Size = %d", card.dwTrack2Size);
+		Dbg("card.track2 = %s", card.track2);
+		Dbg("card.dwTrack3Size = %d", card.dwTrack3Size);
+		Dbg("card.track3 = %s", card.track3);
 		bool bDataOK = true;
 		//读卡成功并解析出卡序号,才算成功,卡序号也要返回
 		if(eErr == Error_Succeed && card.dwSize > 0 && card.dwSize < 64)
@@ -7037,7 +7070,7 @@ void CCardIssuerFSM::DecodeTracksData(const char *track2, DWORD dwT2size, const
 		Dbg("track2 isn't ok.");
 		return;
 	}
-	if (dwT2size <= 0 || strlen(track2) < 16)
+	if (dwT2size <= 0 || strlen(track2) < 15)//运通卡号为15位
 	{
 		Dbg("t2.size %d,strlen(t2):%d",dwT2size,strlen(track2));
 		return;
@@ -7054,6 +7087,9 @@ void CCardIssuerFSM::DecodeTracksData(const char *track2, DWORD dwT2size, const
 		memcpy(tmpMag2_3 + dwT2size + 1, track3, dwT3size);
 		cmdDecodeEx(tmpMag2_3, cardType, magData);
 	}
+	Dbg("tmpMage2_3 = %s", tmpMag2_3);
+	Dbg("magData = %s", magData);
+	Dbg("cardType = %s", cardType);
 	if (!bT3OK || strlen(cardType) < 4)
 	{
 		Dbg("no(%d) or wrong track 3(size:%d,strlen(%d)),%s",bT3OK,dwT3size,strlen(track3),cardType);
@@ -7336,11 +7372,7 @@ void CCardIssuerFSM::oiltestSCI(bool bSCI)
 			m_pCardProcess->DetectIfICCard(CARD_MACHINE_ISSUER, m_pCardIssuer, activeCardType);
 			//oilyang@20201014 add emv support
 			int retGetICData = -1;
-			retGetICData = m_pCardProcess->GetICDataFromCard(CARD_MACHINE_ISSUER, m_pCardIssuer, "A000000333");
-			if (retGetICData < -1)//-1:DetectIfICCard failed; -2:select app failed
-			{
-				retGetICData = m_pCardProcess->GetICDataFromCard(CARD_MACHINE_ISSUER, m_pCardIssuer, "A0000000108888");
-			}
+			retGetICData = m_pCardProcess->GetICDataFromCard(CARD_MACHINE_ISSUER, m_pCardIssuer, m_aidList);
 			ICData track2(false, 0x57, 0x00);
 			string t2ICAccount(""), t2ICCardSerial(""), t2ICCVC(""), t2ICTrack2(""), cardType;
 			if (m_pCardProcess->FindTagValue(TAG_VECTOR_IC, track2, false, 0) == -1)

+ 5 - 0
Module/mod_cardissuer/CardIssuerFSM.h

@@ -761,6 +761,10 @@ public:
 			HARDWARE_ENTITY_RESET_ENTITYID(m_entCode, 0x203);
 			cmdDecodeMag2 = NULL;
 			cmdDecodeEx = NULL;
+			m_aidList.Init(3);
+			m_aidList[0] = "A000000333";
+			m_aidList[1] = "A0000000108888";
+			m_aidList[2] = "A000000790";
 		}
 
 	~CCardIssuerFSM(){}
@@ -1046,6 +1050,7 @@ private:
 	CardIssuerClass* m_pCardIssuer;
 	DevStateEnum m_eDevState;
 	CCardProcess *m_pCardProcess;
+	CAutoArray<CSimpleStringA> m_aidList;
 	pfEncryptDukptHSM EncypteDukptHSM;
 	pfGetEncrypedData GetEncrypedData;
 	char *m_pDataToARQC;

+ 69 - 6
Module/mod_cardswiper/CardSwiperFSM.cpp

@@ -1694,6 +1694,13 @@ int CCardSwiperFSM::SplitTrack2(CSimpleStringA pTrack2,Track2Data &decodeData)
 		decodeData.t2Region = pTrack2.SubString(23,4);
 		decodeData.t2ExpireDate = pTrack2.SubString(27,4);
 		break;
+	case 25://AE Card
+		decodeData.t2Account = CSimpleString(pTrack2, 15);
+		decodeData.t2CardSerial = pTrack2.SubString(15, 1);
+		decodeData.t2CVC = pTrack2.SubString(16, 5);
+		decodeData.t2ExpireDate = pTrack2.SubString(21, 4);
+		decodeData.t2Region = "";
+		break;
 	case 38:
 		break;
 	default:
@@ -1758,6 +1765,7 @@ int CCardSwiperFSM::ReadCard(SpReqAnsContext<CardSwiperService_Read_Req,CardSwip
 	DWORD dwStart = GetTickCount();
 	//HRESULT hr = -1;
 	MagTracks magTracks;
+	memset(&magTracks, 0, sizeof(MagTracks));
 //	int readTries = 0;
 	bool bReadCardInfo = false;
 	Dbg("mag card");
@@ -1864,8 +1872,10 @@ DoRead:		magTracks.eRange = CI_TRACK_RANGE_2_3;
 				}
 				for (int i = 0; i < 20; ++i)
 				{
+					//运通卡分隔符还要考虑为D的情况
 					if (magTracks.track[1].data[i] < 0x30
-						|| (magTracks.track[1].data[i] > 0x39 && (magTracks.track[1].data[i] != 0x3d && magTracks.track[1].data[i] != 0x3e)))
+						|| (magTracks.track[1].data[i] > 0x39 && 
+							(magTracks.track[1].data[i] != 0x3d && magTracks.track[1].data[i] != 0x3e && magTracks.track[1].data[i] != 0x44)))
 					{
 						//oilyang 20160523
 						//not '0'-'9' or '=' or '>'
@@ -1917,7 +1927,10 @@ DoRead:		magTracks.eRange = CI_TRACK_RANGE_2_3;
 					int pos = 0;
 					for (int i = 0; i < magTracks.track[1].dwSize; ++i,++pos)
 					{
-						if (magTracks.track[1].data[i] == 0x3d || magTracks.track[1].data[i] == 0x3e)
+						//运通卡考虑分隔符为D的情况
+						if (magTracks.track[1].data[i] == 0x3d
+							|| magTracks.track[1].data[i] == 0x3e
+							|| magTracks.track[1].data[i] == 0x44)
 							break;
 					}
 					Dbg("pos:%d,%d",pos,magTracks.track[1].dwSize);
@@ -1958,6 +1971,7 @@ DoRead:		magTracks.eRange = CI_TRACK_RANGE_2_3;
 						
 					}
 					Dbg("%s,%s", (LPCTSTR)ctx->Ans.t2Account.SubString(0, 6), (LPCTSTR)ctx->Ans.t2Account.SubString(pos - 4, 4));
+					Dbg("account = %s", ctx->Ans.t2Account.GetData());
 					break;
 				}
 				else
@@ -1981,7 +1995,19 @@ DoRead:		magTracks.eRange = CI_TRACK_RANGE_2_3;
 					Dbg("contact ic %d",eErr);
 					eErr = m_pCardSwiper->ActiveICCard();
 					Dbg("active ic %d",eErr);
-					m_pCardProcess->GetICDataFromCard(m_eReadType,m_pCardSwiper,"A000000333");
+					bool bGetICData = false;
+					if (ctx->Req.aid.IsNullOrEmpty())
+					{
+						Dbg("the front han't provide aid data.");
+						bGetICData = m_pCardProcess->GetICDataFromCard(m_eReadType, m_pCardSwiper, m_aidList);
+					}
+					else {
+						Dbg("the aid is[%s],len:%d .", (const char*)ctx->Req.aid, ctx->Req.aid.GetLength());
+						CAutoArray<CSimpleStringA> preAIDs;
+						preAIDs.Init(1);
+						preAIDs[0] = ctx->Req.aid;
+						bGetICData = m_pCardProcess->GetICDataFromCard(m_eReadType, m_pCardSwiper, preAIDs);
+					}
 					ICData track2(false,0x57,0x00);
 					eErr = Error_Unexpect;
 					string t2ICAccount(""),t2ICCardSerial(""),t2ICCVC(""),t2ICTrack2(""),cardType;
@@ -2044,7 +2070,19 @@ DoRead:		magTracks.eRange = CI_TRACK_RANGE_2_3;
 					}
 					ctx->Ans.reserved3 = chType;
 					Dbg("active type %d",chType);
-					m_pCardProcess->GetICDataFromCard(m_eReadType,m_pCardSwiper,"A000000333");
+					bool bGetICData = false;
+					if (ctx->Req.aid.IsNullOrEmpty())
+					{
+						Dbg("the front han't provide aid data.");
+						bGetICData = m_pCardProcess->GetICDataFromCard(m_eReadType, m_pCardSwiper, m_aidList);
+					}
+					else {
+						Dbg("the aid is[%s],len:%d .", (const char*)ctx->Req.aid, ctx->Req.aid.GetLength());
+						CAutoArray<CSimpleStringA> preAIDs;
+						preAIDs.Init(1);
+						preAIDs[0] = ctx->Req.aid;
+						bGetICData = m_pCardProcess->GetICDataFromCard(m_eReadType, m_pCardSwiper, preAIDs);
+					}
 					ICData track2(false,0x57,0x00);
 					eErr = Error_Unexpect;
 					string t2ICAccount(""),t2ICCardSerial(""),t2ICCVC(""),t2ICTrack2(""),cardType;
@@ -2066,6 +2104,7 @@ DoRead:		magTracks.eRange = CI_TRACK_RANGE_2_3;
 						ZeroMemory(pICTrack2,128);
 						HexBuf2StrBuf(track2.value,&pICTrack2,track2.lenth);
 						pICTrack2[37] = '\0';
+						Dbg("pICTrack2 = %s", pICTrack2);
 
 						{
 							char *ddd = new char[128];
@@ -2075,6 +2114,7 @@ DoRead:		magTracks.eRange = CI_TRACK_RANGE_2_3;
 							t2ICTrack2 = pICTrack2;
 							t2ICAccount = (char*)ddd;//oiltest
 							Dbg("count : %s,%s", t2ICAccount.substr(0, 6).c_str(), t2ICAccount.substr(t2ICAccount.length() - 4, 4).c_str());
+							Dbg("account = %s", t2ICAccount.c_str());
 							ctx->Ans.ICData = ctx->Ans.t2Account = t2ICAccount.c_str();
 							delete []ddd;
 						}
@@ -2253,9 +2293,32 @@ int CCardSwiperFSM::PreOnline(SpReqAnsContext<CardSwiperService_PreOnline_Req,Ca
 		m_pCardProcess->SplitBusinessData("DF690101",strlen("DF690101"));
 	}
 	int activeCardType;
-	if (!m_pCardProcess->DetectAndReadICData(m_eReadType, m_pCardSwiper, "A000000333", activeCardType))//oiltest 20140915
+	int retDetectAndRead = -1;
+	ICData aidFromBus(false, 0x4f, 0x00);
+	if (m_pCardProcess->FindTagValue(TAG_VECTOR_BUS, aidFromBus, false, 0) == -1)
+	{
+		Dbg("the front BusinessData han't provide aid data.");
+		retDetectAndRead = m_pCardProcess->DetectAndReadICData(m_eReadType, m_pCardSwiper, m_aidList, activeCardType);
+	}
+	else {
+		char* pAIDTmp = new char[64];
+		memset(pAIDTmp, 0, 64);
+		HexBuf2StrBuf(aidFromBus.value, &pAIDTmp, aidFromBus.lenth);
+		Dbg("the aid is[%s],len:%d .", pAIDTmp, strlen(pAIDTmp));
+		CAutoArray<CSimpleString> preAIDs;
+		preAIDs.Init(1);
+		preAIDs[0] = (CSimpleStringA)pAIDTmp;
+		retDetectAndRead = m_pCardProcess->DetectAndReadICData(m_eReadType, m_pCardSwiper, preAIDs, activeCardType);
+		if (pAIDTmp != NULL)
+			delete[]pAIDTmp;
+	}
+
+	if (retDetectAndRead < 0)
 	{
-		ctx->Answer(Error_Unexpect, AlarmDECToBusiness(MEC_DEVAPI_CARDSWIPER_ICCommand));
+		if (retDetectAndRead == -1)
+			ctx->Answer(Error_Unexpect, AlarmDECToBusiness("PreOnline(-1):", Error_Unexpect, MEC_DEVAPI_CARDSWIPER_ActiveICCard));
+		else if (retDetectAndRead == -2)
+			ctx->Answer(Error_Unexpect, AlarmDECToBusiness("PreOnline(-2):", Error_Unexpect, MEC_DEVAPI_CARDSWIPER_ICCommand));
 		return 0;
 	}
 	//if (m_cardType == CI_CARDTYPE_IC)

+ 5 - 0
Module/mod_cardswiper/CardSwiperFSM.h

@@ -364,6 +364,10 @@ public:
 	, m_bInMainPage(false), m_batteryLeft(999), m_bFWBOpenSucEver(false)
 	{
 		HARDWARE_ENTITY_RESET_ENTITYID(m_entCode, 0x202);
+		m_aidList.Init(3);
+		m_aidList[0] = "A000000333";
+		m_aidList[1] = "A0000000108888";
+		m_aidList[2] = "A000000790";
 	}
 	~CCardSwiperFSM(){}
 	virtual ErrorCodeEnum OnInit();
@@ -651,6 +655,7 @@ private:
 		, m_bDoingBindFWB, m_bDevOpenEx, m_bBTScan, m_bInMainPage,m_bFWBOpenSucEver;
 	
 	ErrorCodeEnum m_testResult;
+	CAutoArray<CSimpleStringA> m_aidList;
 
 	SelfChekerClient*m_pSelfcheckClient;
 	bool m_bCancelQueryConn;

+ 16 - 0
Module/mod_interactivecontrol/InteractiveControl.xml

@@ -364,6 +364,22 @@
 			</res>
 		</twoway>
 		
+		<!--设置话筒模式下声音大小-->
+		<twoway name="GetPickupOutVolume" overlap="true">
+			<req>
+			</req>
+			<res>
+				<param name="Volume" type="int"/>
+			</res>
+		</twoway>
+		<twoway name="SetPickupOutVolume" overlap="true">
+			<req>
+				<param name="Volume" type="int"/>
+			</req>
+			<res>
+			</res>
+		</twoway>
+		
 	</class>
 	
 

+ 125 - 0
Module/mod_interactivecontrol/InteractiveControl_client_g.h

@@ -1048,6 +1048,131 @@ public:
 		}
 		return Error;
 	}
+
+	ErrorCodeEnum SendH5SyncData(UIService_SendH5SyncData_Info &Info)
+	{
+		CSmartPointer<IClientSessionFunction> pFunc = GetFunction();
+		CAutoBuffer Buf = SpObject2Buffer(Info);
+		return pFunc->OnewayCall(UIService_Method_SendH5SyncData, UIService_MethodSignature_SendH5SyncData, Buf);
+	}
+
+	ErrorCodeEnum GetHandfreeOutVolume(UIService_GetHandfreeOutVolume_Req &Req, CSmartPointer<IAsynWaitSp> &spAsyncWait, DWORD dwTimeout)
+	{
+		CSmartPointer<IClientSessionFunction> pFunc = GetFunction();
+		CAutoBuffer Buf = SpObject2Buffer(Req);
+		return pFunc->AsyncRequest(UIService_Method_GetHandfreeOutVolume, UIService_MethodSignature_GetHandfreeOutVolume, Buf, spAsyncWait, dwTimeout);
+	}
+	ErrorCodeEnum GetHandfreeOutVolume(UIService_GetHandfreeOutVolume_Req &Req, UIService_GetHandfreeOutVolume_Ans &Ans, DWORD dwTimeout)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = GetHandfreeOutVolume(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+	ErrorCodeEnum GetHandfreeOutVolume(UIService_GetHandfreeOutVolume_Req &Req, UIService_GetHandfreeOutVolume_Ans &Ans, DWORD dwTimeout, DWORD &dwUserError)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = GetHandfreeOutVolume(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwUserError, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+
+	ErrorCodeEnum SetHandfreeOutVolume(UIService_SetHandfreeOutVolume_Req &Req, CSmartPointer<IAsynWaitSp> &spAsyncWait, DWORD dwTimeout)
+	{
+		CSmartPointer<IClientSessionFunction> pFunc = GetFunction();
+		CAutoBuffer Buf = SpObject2Buffer(Req);
+		return pFunc->AsyncRequest(UIService_Method_SetHandfreeOutVolume, UIService_MethodSignature_SetHandfreeOutVolume, Buf, spAsyncWait, dwTimeout);
+	}
+	ErrorCodeEnum SetHandfreeOutVolume(UIService_SetHandfreeOutVolume_Req &Req, UIService_SetHandfreeOutVolume_Ans &Ans, DWORD dwTimeout)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = SetHandfreeOutVolume(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+	ErrorCodeEnum SetHandfreeOutVolume(UIService_SetHandfreeOutVolume_Req &Req, UIService_SetHandfreeOutVolume_Ans &Ans, DWORD dwTimeout, DWORD &dwUserError)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = SetHandfreeOutVolume(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwUserError, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+
+	ErrorCodeEnum GetPickupOutVolume(UIService_GetPickupOutVolume_Req &Req, CSmartPointer<IAsynWaitSp> &spAsyncWait, DWORD dwTimeout)
+	{
+		CSmartPointer<IClientSessionFunction> pFunc = GetFunction();
+		CAutoBuffer Buf = SpObject2Buffer(Req);
+		return pFunc->AsyncRequest(UIService_Method_GetPickupOutVolume, UIService_MethodSignature_GetPickupOutVolume, Buf, spAsyncWait, dwTimeout);
+	}
+	ErrorCodeEnum GetPickupOutVolume(UIService_GetPickupOutVolume_Req &Req, UIService_GetPickupOutVolume_Ans &Ans, DWORD dwTimeout)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = GetPickupOutVolume(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+	ErrorCodeEnum GetPickupOutVolume(UIService_GetPickupOutVolume_Req &Req, UIService_GetPickupOutVolume_Ans &Ans, DWORD dwTimeout, DWORD &dwUserError)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = GetPickupOutVolume(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwUserError, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+
+	ErrorCodeEnum SetPickupOutVolume(UIService_SetPickupOutVolume_Req &Req, CSmartPointer<IAsynWaitSp> &spAsyncWait, DWORD dwTimeout)
+	{
+		CSmartPointer<IClientSessionFunction> pFunc = GetFunction();
+		CAutoBuffer Buf = SpObject2Buffer(Req);
+		return pFunc->AsyncRequest(UIService_Method_SetPickupOutVolume, UIService_MethodSignature_SetPickupOutVolume, Buf, spAsyncWait, dwTimeout);
+	}
+	ErrorCodeEnum SetPickupOutVolume(UIService_SetPickupOutVolume_Req &Req, UIService_SetPickupOutVolume_Ans &Ans, DWORD dwTimeout)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = SetPickupOutVolume(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+	ErrorCodeEnum SetPickupOutVolume(UIService_SetPickupOutVolume_Req &Req, UIService_SetPickupOutVolume_Ans &Ans, DWORD dwTimeout, DWORD &dwUserError)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = SetPickupOutVolume(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwUserError, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+
+
 	bool SafeDelete()
 	{
 		if (!m_bSysManaged) {

+ 103 - 0
Module/mod_interactivecontrol/InteractiveControl_def_g.h

@@ -64,6 +64,11 @@ namespace InteractiveControl {
 #define UIService_Method_AjustVideoPreviewSize 42
 #define UIService_Method_StopShowVideo 43
 #define UIService_Method_StartPlaySalesRecord 44
+#define UIService_Method_SendH5SyncData 45
+#define UIService_Method_GetHandfreeOutVolume 46
+#define UIService_Method_SetHandfreeOutVolume 47
+#define UIService_Method_GetPickupOutVolume 48
+#define UIService_Method_SetPickupOutVolume 49
 
 #define UIService_MethodSignature_SetUIState -649355360
 #define UIService_MethodSignature_SendAgentText -389826246
@@ -110,6 +115,11 @@ namespace InteractiveControl {
 #define UIService_MethodSignature_AjustVideoPreviewSize 1033541107
 #define UIService_MethodSignature_StopShowVideo 195996145
 #define UIService_MethodSignature_StartPlaySalesRecord -995863402
+#define UIService_MethodSignature_SendH5SyncData -546371570
+#define UIService_MethodSignature_GetHandfreeOutVolume 1306483555
+#define UIService_MethodSignature_SetHandfreeOutVolume 2042464727
+#define UIService_MethodSignature_GetPickupOutVolume 1201465844
+#define UIService_MethodSignature_SetPickupOutVolume -1088342808
 
 struct UIService_SetUIState_Info
 {
@@ -927,6 +937,99 @@ struct UIService_StartPlaySalesRecord_Ans
 	}
 
 };
+
+struct UIService_SendH5SyncData_Info
+{
+	CSimpleStringW content;
+
+	void Serialize(SpBuffer &Buf)
+	{
+		auto & buf = Buf & content;
+	}
+
+};
+
+struct UIService_GetHandfreeOutVolume_Req
+{
+
+	void Serialize(SpBuffer &Buf)
+	{
+	}
+
+};
+
+struct UIService_GetHandfreeOutVolume_Ans
+{
+	int Volume;
+
+	void Serialize(SpBuffer &Buf)
+	{
+		auto & buf = Buf & Volume;
+	}
+
+};
+
+struct UIService_SetHandfreeOutVolume_Req
+{
+	int Volume;
+
+	void Serialize(SpBuffer &Buf)
+	{
+		auto & buf = Buf & Volume;
+	}
+
+};
+
+struct UIService_SetHandfreeOutVolume_Ans
+{
+
+	void Serialize(SpBuffer &Buf)
+	{
+	}
+
+};
+
+struct UIService_GetPickupOutVolume_Req
+{
+
+	void Serialize(SpBuffer &Buf)
+	{
+	}
+
+};
+
+struct UIService_GetPickupOutVolume_Ans
+{
+	int Volume;
+
+	void Serialize(SpBuffer &Buf)
+	{
+		auto & buf = Buf & Volume;
+	}
+
+};
+
+struct UIService_SetPickupOutVolume_Req
+{
+	int Volume;
+
+	void Serialize(SpBuffer &Buf)
+	{
+		auto & buf = Buf & Volume;
+	}
+
+};
+
+struct UIService_SetPickupOutVolume_Ans
+{
+
+	void Serialize(SpBuffer &Buf)
+	{
+	}
+
+};
+
+
 ///////////////////////////
 
 } // namespace InteractiveControl

+ 18 - 0
Module/mod_interactivecontrol/InteractiveControl_msg_g.h

@@ -28,6 +28,7 @@ namespace InteractiveControl {
 #define eMsg_EnterBFlowFromUT 16
 #define eMsg_AudioEndRet 17
 #define eMsg_CommonWebMsg 18
+#define eMsg_H5BackSyncData 19
 
 #define eMsgSig_CustomerState 175614460
 #define eMsgSig_Stop -150723185
@@ -48,6 +49,7 @@ namespace InteractiveControl {
 #define eMsgSig_EnterBFlowFromUT 48398790
 #define eMsgSig_AudioEndRet -1055633973
 #define eMsgSig_CommonWebMsg -1026578513
+#define eMsgSig_H5BackSyncData -1217690931
 
 struct CustomerState
 {
@@ -286,6 +288,8 @@ struct AudioEndRet
 
 };
 
+///////////////////////////
+
 struct CommonWebMsg
 {
 	int type;
@@ -298,6 +302,20 @@ struct CommonWebMsg
 
 };
 
+///////////////////////////
+
+struct H5BackSyncData
+{
+	CSimpleStringW content;
+
+	void Serialize(SpBuffer &Buf)
+	{
+		auto & buf = Buf & content;
+	}
+
+};
+
+///////////////////////////
 
 } // namespace InteractiveControl
 #endif // __INTERACTIVECONTROL_MSG_G_H

+ 125 - 0
Module/mod_interactivecontrol/InteractiveControl_server_g.h

@@ -345,6 +345,41 @@ public:
 				Error = Error_MethodSignatureFailed;
 			}
 			break;
+		case UIService_Method_SendH5SyncData:
+			if (dwSignature == UIService_MethodSignature_SendH5SyncData) {
+				bOverlap = true;
+			} else {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
+		case UIService_Method_GetHandfreeOutVolume:
+			if (dwSignature == UIService_MethodSignature_GetHandfreeOutVolume) {
+				bOverlap = true;
+			} else {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
+		case UIService_Method_SetHandfreeOutVolume:
+			if (dwSignature == UIService_MethodSignature_SetHandfreeOutVolume) {
+				bOverlap = true;
+			} else {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
+		case UIService_Method_GetPickupOutVolume:
+			if (dwSignature == UIService_MethodSignature_GetPickupOutVolume) {
+				bOverlap = true;
+			} else {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
+		case UIService_Method_SetPickupOutVolume:
+			if (dwSignature == UIService_MethodSignature_SetPickupOutVolume) {
+				bOverlap = true;
+			} else {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
 		default:
 			Error = Error_MethodNotFound;
 			break;
@@ -581,6 +616,31 @@ public:
 				Error = Error_MethodSignatureFailed;
 			}
 			break;
+		case UIService_Method_SendH5SyncData:
+			if (dwSignature != UIService_MethodSignature_SendH5SyncData) {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
+		case UIService_Method_GetHandfreeOutVolume:
+			if (dwSignature != UIService_MethodSignature_GetHandfreeOutVolume) {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
+		case UIService_Method_SetHandfreeOutVolume:
+			if (dwSignature != UIService_MethodSignature_SetHandfreeOutVolume) {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
+		case UIService_Method_GetPickupOutVolume:
+			if (dwSignature != UIService_MethodSignature_GetPickupOutVolume) {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
+		case UIService_Method_SetPickupOutVolume:
+			if (dwSignature != UIService_MethodSignature_SetPickupOutVolume) {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
 		default:
 			Error = Error_MethodNotFound;
 			break;
@@ -813,6 +873,31 @@ public:
 	/// override by user
 	}
 
+	virtual void Handle_SendH5SyncData(SpOnewayCallContext<UIService_SendH5SyncData_Info>::Pointer ctx)
+	{
+	/// override by user
+	}
+
+	virtual void Handle_GetHandfreeOutVolume(SpReqAnsContext<UIService_GetHandfreeOutVolume_Req, UIService_GetHandfreeOutVolume_Ans>::Pointer ctx)
+	{
+	/// override by user
+	}
+
+	virtual void Handle_SetHandfreeOutVolume(SpReqAnsContext<UIService_SetHandfreeOutVolume_Req, UIService_SetHandfreeOutVolume_Ans>::Pointer ctx)
+	{
+	/// override by user
+	}
+
+	virtual void Handle_GetPickupOutVolume(SpReqAnsContext<UIService_GetPickupOutVolume_Req, UIService_GetPickupOutVolume_Ans>::Pointer ctx)
+	{
+	/// override by user
+	}
+
+	virtual void Handle_SetPickupOutVolume(SpReqAnsContext<UIService_SetPickupOutVolume_Req, UIService_SetPickupOutVolume_Ans>::Pointer ctx)
+	{
+	/// override by user
+	}
+
 	virtual void OnRequest(CSmartPointer<ITransactionContext> pTransactionContext)
 	{
 		CAutoBuffer Buf;
@@ -1189,6 +1274,46 @@ public:
 						Handle_StartPlaySalesRecord(ctx);
 					}
 					break;
+				case UIService_Method_SendH5SyncData:
+					{
+						SpOnewayCallContext<UIService_SendH5SyncData_Info>::Pointer ctx;
+						ctx.Attach(new SpOnewayCallContext<UIService_SendH5SyncData_Info>());
+						SpBuffer2Object(Buf, ctx->Info);
+						Handle_SendH5SyncData(ctx);
+					}
+					break;
+				case UIService_Method_GetHandfreeOutVolume:
+					{
+						SpReqAnsContext<UIService_GetHandfreeOutVolume_Req,UIService_GetHandfreeOutVolume_Ans>::Pointer ctx;
+						ctx.Attach(new SpReqAnsContext<UIService_GetHandfreeOutVolume_Req,UIService_GetHandfreeOutVolume_Ans>(pTransactionContext));
+						SpBuffer2Object(Buf, ctx->Req);
+						Handle_GetHandfreeOutVolume(ctx);
+					}
+					break;
+				case UIService_Method_SetHandfreeOutVolume:
+					{
+						SpReqAnsContext<UIService_SetHandfreeOutVolume_Req,UIService_SetHandfreeOutVolume_Ans>::Pointer ctx;
+						ctx.Attach(new SpReqAnsContext<UIService_SetHandfreeOutVolume_Req,UIService_SetHandfreeOutVolume_Ans>(pTransactionContext));
+						SpBuffer2Object(Buf, ctx->Req);
+						Handle_SetHandfreeOutVolume(ctx);
+					}
+					break;
+				case UIService_Method_GetPickupOutVolume:
+					{
+						SpReqAnsContext<UIService_GetPickupOutVolume_Req,UIService_GetPickupOutVolume_Ans>::Pointer ctx;
+						ctx.Attach(new SpReqAnsContext<UIService_GetPickupOutVolume_Req,UIService_GetPickupOutVolume_Ans>(pTransactionContext));
+						SpBuffer2Object(Buf, ctx->Req);
+						Handle_GetPickupOutVolume(ctx);
+					}
+					break;
+				case UIService_Method_SetPickupOutVolume:
+					{
+						SpReqAnsContext<UIService_SetPickupOutVolume_Req,UIService_SetPickupOutVolume_Ans>::Pointer ctx;
+						ctx.Attach(new SpReqAnsContext<UIService_SetPickupOutVolume_Req,UIService_SetPickupOutVolume_Ans>(pTransactionContext));
+						SpBuffer2Object(Buf, ctx->Req);
+						Handle_SetPickupOutVolume(ctx);
+					}
+					break;
 				default:
 					assert(0);
 					break;

+ 225 - 2
Module/mod_interactivecontrol/mod_interactivecontrol.cpp

@@ -102,6 +102,8 @@ public:
 
 	virtual void Handle_SendFrontSyncData(SpOnewayCallContext<UIService_SendFrontSyncData_Info>::Pointer ctx);
 
+	virtual void Handle_SendH5SyncData(SpOnewayCallContext<UIService_SendH5SyncData_Info>::Pointer ctx);
+
 	virtual void Handle_StartRecordVideo(SpReqAnsContext<UIService_StartRecordVideo_Req, UIService_StartRecordVideo_Ans>::Pointer ctx);
 
 	virtual void Handle_StopRecordVideo(SpReqAnsContext<UIService_StopRecordVideo_Req, UIService_StopRecordVideo_Ans>::Pointer ctx);
@@ -179,7 +181,10 @@ public:
 	virtual void Handle_StartSalesVideoRecord(SpReqAnsContext<UIService_StartSalesVideoRecord_Req, UIService_StartSalesVideoRecord_Ans>::Pointer ctx);
 	virtual void Handle_StopShowVideo(SpReqAnsContext<UIService_StopShowVideo_Req, UIService_StopShowVideo_Ans>::Pointer ctx);
 	virtual void Handle_StartPlaySalesRecord(SpReqAnsContext<UIService_StartPlaySalesRecord_Req, UIService_StartPlaySalesRecord_Ans>::Pointer ctx);
-
+	virtual void Handle_GetHandfreeOutVolume(SpReqAnsContext<UIService_GetHandfreeOutVolume_Req, UIService_GetHandfreeOutVolume_Ans>::Pointer ctx);
+	virtual void Handle_SetHandfreeOutVolume(SpReqAnsContext<UIService_SetHandfreeOutVolume_Req, UIService_SetHandfreeOutVolume_Ans>::Pointer ctx);
+	virtual void Handle_GetPickupOutVolume(SpReqAnsContext<UIService_GetPickupOutVolume_Req, UIService_GetPickupOutVolume_Ans>::Pointer ctx);
+	virtual void Handle_SetPickupOutVolume(SpReqAnsContext<UIService_SetPickupOutVolume_Req, UIService_SetPickupOutVolume_Ans>::Pointer ctx);
 
 private:
 	CITCtrlEntity *m_pEntity;
@@ -362,6 +367,14 @@ public:
 			m_pChannelClient->GetFunction()->CloseSession();
 			m_pChannelClient = NULL;
 		}
+
+		Sub.type = ACM_TYPE_H5_SYNC;
+		Error = m_pChannelClient->BeginRecv(Sub);
+		if (Error != Error_Succeed)
+		{
+			m_pChannelClient->GetFunction()->CloseSession();
+			m_pChannelClient = NULL;
+		}
 		ChannelService_BeginState_Sub Sub1;
 		Error = m_pChannelClient->BeginState(Sub1);
 		if (Error != Error_Succeed) {
@@ -875,10 +888,14 @@ public:
 		{
 			SpBuffer buf;
 			buf.OpenWrite(32 + strContent.GetLength()*2);
-			buf& id;
+#if defined(RVC_OS_WIN)
+			buf& id& strContent;
+#else
+            buf& id;
             CSimpleString16Bit convertedData = CSimpleStringW216Bit(strContent);
             buf& convertedData;
             Dbg("%s After convert: %s", __FUNCTION__, CSimpleString16Bit2A(convertedData).GetData());
+#endif //RVC_OS_WIN
 			ChannelService_Send_Info Info;
 			Info.sub_type = ACM_IM_FRONTSYNC;
 			Info.type = ACM_TYPE_IM;
@@ -894,6 +911,35 @@ public:
 		}
 	}
 
+	ErrorCodeEnum SendH5SyncData(CSimpleStringW strContent)
+	{
+		if (m_nSysCallType == 0)
+		{
+			SpBuffer buf;
+			buf.OpenWrite(32 + strContent.GetLength() * 2);
+#if defined(RVC_OS_WIN)
+			buf& strContent;
+#else
+            CSimpleString16Bit convertedData = CSimpleStringW216Bit(strContent);
+            buf& convertedData;
+            Dbg("%s After convert: %s", __FUNCTION__, CSimpleString16Bit2A(convertedData).GetData());
+#endif //RVC_OS_WIN
+			
+			ChannelService_Send_Info Info;
+			Info.sub_type = 0;
+			Info.type = ACM_TYPE_H5_SYNC;
+			Info.data = buf.ToBlob();
+			Info.compress = true;
+			Info.encrypt = true;
+			return m_pChannelClient->Send(Info);
+		}
+		else
+		{
+			Dbg("cur call type cannot send pkt");
+			return Error_Succeed;
+		}
+	}
+
 	void SetConnected(BOOL bConnected)
 	{
 		m_bConnected = bConnected;
@@ -974,6 +1020,14 @@ public:
 				LOG_TRACE("unknown type %d sub_type %d from agent!", type,sub_type);
 			}
 		}
+		else if (type == ACM_TYPE_H5_SYNC) {
+			SpBuffer buf;
+			buf.OpenRead(data, size);
+			H5BackSyncData evt;
+			evt.Serialize(buf);
+			SpSendBroadcast(GetFunction(), SP_MSG_OF(H5BackSyncData), SP_MSG_SIG_OF(H5BackSyncData), evt);
+			//LOG_TRACE("Recv ACM_TYPE_H5_SYNC,content=%s", CSimpleStringW2A(evt.content));
+		}
 		else if (type == ACM_TYPE_FLW)
 		{
 			LOG_TRACE("Recv P2P Caller data,buf=%s", data);
@@ -1264,6 +1318,143 @@ public:
 		return Error_Succeed;
 	}
 
+	ErrorCodeEnum GetHandfreeCallOutVolume(int& nVolume, DWORD dwTimeout)
+	{
+		auto rc = Error_Succeed;
+		auto pSipPhoneClient = new PhoneService_ClientBase(this);
+
+		if(pSipPhoneClient->Connect() != Error_Succeed)
+		{
+			pSipPhoneClient->SafeDelete();
+			pSipPhoneClient = NULL;
+			rc = Error_DevConnFailed;
+		}
+		else
+		{
+			Dbg("pSipPhoneClient connected success!");
+			PhoneService_GetHandfreeOutVolume_Req req;
+			PhoneService_GetHandfreeOutVolume_Ans ans;
+			rc = pSipPhoneClient->GetHandfreeOutVolume(req, ans, 1000);
+			nVolume = ans.Volume;
+			if(Error_Succeed == rc)
+			{
+				Dbg("get hand free out volume success.");
+			}
+			else
+			{
+				Dbg("get hand free out volume failed for 0x%08x", rc);
+			}
+
+			pSipPhoneClient->GetFunction()->CloseSession();
+			//pSipPhoneClient->SafeDelete();
+			pSipPhoneClient = NULL;
+		}
+
+		return rc;
+	}
+
+	ErrorCodeEnum SetHandfreeCallOutVolume(int nVolume, DWORD dwTimeout)
+	{
+		auto rc = Error_Succeed;
+		auto pSipPhoneClient = new PhoneService_ClientBase(this);
+
+		if(pSipPhoneClient->Connect() != Error_Succeed)
+		{
+			pSipPhoneClient->SafeDelete();
+			pSipPhoneClient = NULL;
+			rc = Error_DevConnFailed;
+		}
+		else
+		{
+			Dbg("pSipPhoneClient connected success!");
+			PhoneService_SetHandfreeOutVolume_Req req;
+			req.Volume = nVolume;
+			PhoneService_SetHandfreeOutVolume_Ans ans;
+			rc = pSipPhoneClient->SetHandfreeOutVolume(req, ans, 1000);
+			if(Error_Succeed == rc)
+			{
+				Dbg("set hand free out volume success.");
+			}
+			else
+			{
+				Dbg("set hand free out volume failed for 0x%08x", rc);
+			}
+
+			pSipPhoneClient->GetFunction()->CloseSession();
+			//pSipPhoneClient->SafeDelete();
+			pSipPhoneClient = NULL;
+		}
+
+		return rc;
+	}
+
+	ErrorCodeEnum GetPickupCallOutVolume(int& nVolume, DWORD dwTimeout)
+	{
+		auto rc = Error_Succeed;
+		auto pSipPhoneClient = new PhoneService_ClientBase(this);
+
+		if(pSipPhoneClient->Connect() != Error_Succeed)
+		{
+			pSipPhoneClient->SafeDelete();
+			pSipPhoneClient = NULL;
+			rc = Error_DevConnFailed;
+		}
+		else
+		{
+			Dbg("pSipPhoneClient connected success!");
+			PhoneService_GetPickupOutVolume_Req req;
+			PhoneService_GetPickupOutVolume_Ans ans;
+			rc = pSipPhoneClient->GetPickupOutVolume(req, ans, 1000);
+			nVolume = ans.Volume;
+			if(Error_Succeed == rc)
+			{
+				Dbg("get pickup out volume success.");
+			}
+			else
+			{
+				Dbg("get pickup out volume failed for 0x%08x", rc);
+			}
+
+			pSipPhoneClient->GetFunction()->CloseSession();
+			pSipPhoneClient = NULL;
+		}
+
+		return rc;
+	}
+
+	ErrorCodeEnum SetPickupCallOutVolume(int nVolume, DWORD dwTimeout)
+	{
+		auto rc = Error_Succeed;
+		auto pSipPhoneClient = new PhoneService_ClientBase(this);
+
+		if(pSipPhoneClient->Connect() != Error_Succeed)
+		{
+			pSipPhoneClient->SafeDelete();
+			pSipPhoneClient = NULL;
+			rc = Error_DevConnFailed;
+		}
+		else
+		{
+			Dbg("pSipPhoneClient connected success!");
+			PhoneService_SetPickupOutVolume_Req req;
+			req.Volume = nVolume;
+			PhoneService_SetPickupOutVolume_Ans ans;
+			rc = pSipPhoneClient->SetPickupOutVolume(req, ans, 1000);
+			if(Error_Succeed == rc)
+			{
+				Dbg("set pickup out volume success.");
+			}
+			else
+			{
+				Dbg("set pickup out volume failed for 0x%08x", rc);
+			}
+
+			pSipPhoneClient->GetFunction()->CloseSession();
+			pSipPhoneClient = NULL;
+		}
+
+		return rc;
+	}
 	virtual void OnLog(const CAutoArray<CUUID> &SubIDs, const CUUID nLogID,const LogTypeEnum eLogType, const SeverityLevelEnum eLevel,
 		const DWORD dwSysError,const DWORD dwUserCode,const DWORD dwEntityInstanceID, const WORD wEntityDevelID, 
 		const CAutoArray<DWORD> &Param, const char *pszEntityName, const char *pszModuleName,const char *pszMessage)
@@ -1727,6 +1918,11 @@ void UIServiceSession::Handle_SendFrontSyncData(SpOnewayCallContext<UIService_Se
 	m_pEntity->SendFrontSyncData(ctx->Info.id, ctx->Info.content);
 }
 
+void UIServiceSession::Handle_SendH5SyncData(SpOnewayCallContext<UIService_SendH5SyncData_Info>::Pointer ctx)
+{
+	m_pEntity->SendH5SyncData(ctx->Info.content);
+}
+
 void UIServiceSession::Handle_StartRecordVideo(SpReqAnsContext<UIService_StartRecordVideo_Req, UIService_StartRecordVideo_Ans>::Pointer ctx)
 {
 
@@ -2536,6 +2732,33 @@ void UIServiceSession::Handle_StartPlaySalesRecord(SpReqAnsContext<UIService_Sta
 	ctx->Answer(Error);
 }
 
+void UIServiceSession::Handle_GetHandfreeOutVolume(SpReqAnsContext<UIService_GetHandfreeOutVolume_Req, UIService_GetHandfreeOutVolume_Ans>::Pointer ctx)
+{
+	ErrorCodeEnum Error = m_pEntity->GetHandfreeCallOutVolume(ctx->Ans.Volume, 2000);
+	ctx->Answer(Error);
+}
+
+
+void UIServiceSession::Handle_SetHandfreeOutVolume(SpReqAnsContext<UIService_SetHandfreeOutVolume_Req, UIService_SetHandfreeOutVolume_Ans>::Pointer ctx)
+{
+	ErrorCodeEnum Error = m_pEntity->SetHandfreeCallOutVolume(ctx->Req.Volume, 2000);
+	ctx->Answer(Error);
+}
+
+
+void UIServiceSession::Handle_GetPickupOutVolume(SpReqAnsContext<UIService_GetPickupOutVolume_Req, UIService_GetPickupOutVolume_Ans>::Pointer ctx)
+{
+	ErrorCodeEnum Error = m_pEntity->GetPickupCallOutVolume(ctx->Ans.Volume, 2000);
+	ctx->Answer(Error);
+}
+
+
+void UIServiceSession::Handle_SetPickupOutVolume(SpReqAnsContext<UIService_SetPickupOutVolume_Req, UIService_SetPickupOutVolume_Ans>::Pointer ctx)
+{
+	ErrorCodeEnum Error = m_pEntity->SetPickupCallOutVolume(ctx->Req.Volume, 2000);
+	ctx->Answer(Error);
+}
+
 
 ChannelClient::ChannelClient( CITCtrlEntity *pEntity ) : ChannelService_ClientBase(pEntity)
 {

+ 0 - 6
Module/mod_mediacontroller/CMakeLists.txt

@@ -8,12 +8,8 @@ endif(RVC_DEBUG_MODE)
 
 if(MSVC)
     set(STDAFXCPP stdafx.cpp)
-	 set(VIDEOCAPTURECPP )
-	 set(AUDIOCAPTURECPP )
 else()
 	 set(STDAFXCPP )
-	 set(VIDEOCAPTURECPP videocapobj.h videocapobj.cpp)
-	 set(AUDIOCAPTURECPP audiocapobj.h audiocapobj.cpp)
 endif(MSVC)
 
 set(${MODULE_PREFIX}_SRCS
@@ -26,8 +22,6 @@ set(${MODULE_PREFIX}_SRCS
     MediaController_server_g.h
 
 	${STDAFXCPP}
-	${VIDEOCAPTURECPP}
-	${AUDIOCAPTURECPP}
 
     capture.cpp
     mod_mediacontroller.cpp

+ 0 - 79
Module/mod_mediacontroller/audiocapobj.cpp

@@ -1,79 +0,0 @@
-#include"audiocapobj.h"
-#include<stdlib.h>
-#include<string.h>
-#include<stdarg.h>
-#include <time.h>
-#include <stdio.h>
-#include "SpBase.h"
-
-AudioCapObj::AudioCapObj()
-{
-	m_pAudioMgr = CreateAudioMgrObj(this);
-}
-
-AudioCapObj::~AudioCapObj()
-{
-	if (NULL != m_pAudioMgr){
-		DestroyIAudioMgrObj(m_pAudioMgr);
-	}
-}
-
-int AudioCapObj::AudioMgrInitialize()
-{
-	return m_pAudioMgr->audio_mgr_initialize();
-}
-
-int AudioCapObj::AudioMgrTerminate()
-{
-	return m_pAudioMgr->audio_mgr_terminate();
-}
-
-int AudioCapObj::audio_get_device_count(bool binput)
-{
-	return m_pAudioMgr->audio_get_device_count(binput);
-}
-
-int AudioCapObj::audio_get_device_name(char* strbuf, size_t ulen, bool binput, int index)
-{
-	return m_pAudioMgr->audio_get_device_name(strbuf, ulen, binput, index);
-}
-
-int AudioCapObj::audio_get_device_id(const char* pstrname, bool binput)
-{
-	return m_pAudioMgr->audio_get_device_id(pstrname, binput);
-}
-
-int AudioCapObj::set_audio_capture_params(audiocap_param_t* param)
-{
-	return m_pAudioMgr->set_audio_capture_params(param);
-}
-
-int AudioCapObj::start_audio_capture()
-{
-	return m_pAudioMgr->start_audio_capture();
-}
-
-int AudioCapObj::stop_audio_capture()
-{
-	return m_pAudioMgr->stop_audio_capture();
-}
-
-
-void AudioCapObj::debug(const char* fmt, ...)
-{
-	va_list arg;
-	va_start(arg, fmt);
-	vDbg(fmt, arg);
-	va_end(arg);
-}
-
-
-void AudioCapObj::on_audio_mgr_failed()
-{
-
-}
-
-void AudioCapObj::on_audio_mgr_excption()
-{
-
-}

+ 0 - 27
Module/mod_mediacontroller/audiocapobj.h

@@ -1,27 +0,0 @@
-#pragma once
-
-#include "../../Other/libaudiomgr/iaudiomgrinterface.h"
-
-
-class AudioCapObj : public IAudioMgrCallback
-{
-public:
-	AudioCapObj();
-	virtual ~AudioCapObj();
-
-	void debug(const char* fmt, ...);
-	void on_audio_mgr_failed();
-	void on_audio_mgr_excption();
-
-	int AudioMgrInitialize();
-	int AudioMgrTerminate();
-	int audio_get_device_count(bool binput);
-	int audio_get_device_name(char* strbuf, size_t ulen, bool binput, int index);
-	int audio_get_device_id(const char* pstrname, bool binput);
-	int set_audio_capture_params(audiocap_param_t* param);
-	int start_audio_capture();
-	int stop_audio_capture();
-
-private:
-	IAudioMgr* m_pAudioMgr;
-};

+ 21 - 19
Module/mod_mediacontroller/capture.cpp

@@ -1230,6 +1230,12 @@ static int video_capture_start_win(video_capture_t* video_cap)
 }
 
 #else
+
+static void __videocaplog(void* user_data, const char* fmt, va_list arg)
+{
+	vDbg(fmt, arg);
+}
+
 static int video_capture_start_linux(video_capture_t* video_cap)
 {
 	LOG_FUNCTION();
@@ -1273,33 +1279,29 @@ static int video_capture_start_linux(video_capture_t* video_cap)
 	//t_param.on_frame_i420 = (video_cap->camera_type == CAMERA_TYPE_ENV ? &env_cap_on_frame_i420 : &opt_cap_on_frame_i420);
 	t_param.user_data = video_cap;
 	t_param.option = 0;
-	
-	video_cap->pVideoCap = new VideoCapObj();
+
+	videocap_callback_t t_callback = { 0 };
+	t_callback.debug = &__videocaplog;
+	video_cap->pVideoCap = CreateVideoCaptureObj(&t_callback);
 	if (NULL != video_cap->pVideoCap){
-		if (0 == video_cap->pVideoCap->Init()) {
-			if (0 == video_cap->pVideoCap->VideoCaptureSetParam(&t_param)) {
-				Dbg("VideoCap SetVideoCaptureParam success!");
-				if (0 == video_cap->pVideoCap->StartVideoCapture()) {
-					Dbg("VideoCap StartVideoCapture success!");
-					iret = 0;
-				}
-				else {
-					Dbg("VideoCap StartVideoCapture failed!");
-					delete video_cap->pVideoCap;
-				}
+		if (0 == video_cap->pVideoCap->VideoCaptureSetParam(&t_param)) {
+			Dbg("VideoCap SetVideoCaptureParam success!");
+			if (0 == video_cap->pVideoCap->StartVideoCapture()) {
+				Dbg("VideoCap StartVideoCapture success!");
+				iret = 0;
 			}
 			else {
-				Dbg("VideoCap SetVideoCaptureParam failed!");
-				delete video_cap->pVideoCap;
+				Dbg("VideoCap StartVideoCapture failed!");
+				DestroyVideoCaptureObj(video_cap->pVideoCap);
 			}
 		}
 		else {
-			Dbg("VideoCap init failed!");
-			delete video_cap->pVideoCap;
+			Dbg("VideoCap SetVideoCaptureParam failed!");
+			DestroyVideoCaptureObj(video_cap->pVideoCap);
 		}
 	}
 	else{
-		Dbg(" new VideoCapObj failed!");
+		Dbg(" CreateVideoCaptureObj failed!");
 	}
 
 	return iret;
@@ -1327,7 +1329,7 @@ static void video_capture_stop(video_capture_t *video_cap)
 #else
 	if (video_cap->pVideoCap) {
 		video_cap->pVideoCap->StopVideoCapture();
-		delete video_cap->pVideoCap;
+		DestroyVideoCaptureObj(video_cap->pVideoCap);
 		video_cap->pVideoCap = NULL;
 	}
 #endif // RVC_OS_WIN

+ 6 - 7
Module/mod_mediacontroller/capture.h

@@ -12,13 +12,11 @@
 #include "../../Other/libvideoframework/videoframework.h"
 #else
 #include "../../Other/libmediadeviceinfo/imediadeviceinfo.h"
-#include "videocapobj.h"
-#include "audiocapobj.h"
+#include "../../Other/libaudiomgr/iaudiomgrinterface.h"
+#include "../../Other/libvideocapture/ivideocaptureinterface.h"
 #endif // RVC_OS_WIN
 
 
-
-
 #ifndef INT64_C
 #define INT64_C(c) (c##LL) 
 #define UINT64_C(c) (c##UL) 
@@ -90,7 +88,8 @@ namespace MediaController {
 #ifdef RVC_OS_WIN
 		PaStream* stream;
 #else
-		AudioCapObj* paudiocap;
+		IAudioMgr* paudiocap;
+
 		char* paudio_buffer;
 		size_t uaudiolen;
 #endif
@@ -105,7 +104,7 @@ namespace MediaController {
 #ifdef RVC_OS_WIN
 		PaStream* stream;
 #else
-		AudioCapObj* paudiocap;
+		IAudioMgr* paudiocap;
 #endif
 		Clibaudioqueue *audio_shm_queue;					// 音频包存储队列
 		rvc_sales_audio_capture_t *parent;
@@ -122,7 +121,7 @@ namespace MediaController {
 #ifdef RVC_OS_WIN
 		videocap_t cap;
 #else
-		VideoCapObj* pVideoCap;
+		IVideoCapture* pVideoCap;
 #endif
 		//Clibvideoqueue* render_shm_queue;
 		//Clibvideoqueue* opt_render_shm_queue;

+ 15 - 5
Module/mod_mediacontroller/mod_mediacontroller.cpp

@@ -82,6 +82,12 @@ private:
 };
 
 
+static void __audiomgrlog(void* user_data, const char* fmt, va_list arg)
+{
+	vDbg(fmt, arg);
+}
+
+
 class CMediaControllerEntity : public CEntityBase, public ILogListener, public ITimerListener,public ISysVarListener
 {
 public:
@@ -201,8 +207,12 @@ public:
 		}
 #ifdef RVC_OS_LINUX
 		{
-			m_pAudioCap = new AudioCapObj();
-			if (0 == m_pAudioCap->AudioMgrInitialize()) {
+			audiomgr_callback_t t_callback = { 0 };
+			t_callback.debug = &__audiomgrlog;
+			Dbg("sizeof audiomgr_callback_t == %d.", sizeof(audiomgr_callback_t)); 
+			Dbg("sizeof calss IAudioMgr == %d.", sizeof(IAudioMgr));
+			m_pAudioCap = CreateAudioMgrObj(&t_callback);
+			if (0 == m_pAudioCap->audio_mgr_initialize()) {
 				Dbg("Audio Manager Initialize success!");
 			}
 			else {
@@ -716,8 +726,8 @@ public:
 		}
 #else
 		if (NULL != m_pAudioCap){
-			m_pAudioCap->AudioMgrTerminate();
-			delete m_pAudioCap;
+			m_pAudioCap->audio_mgr_terminate();
+			DestroyIAudioMgrObj(m_pAudioCap);
 			m_pAudioCap = NULL;
 		}
 
@@ -2343,7 +2353,7 @@ private:
 	pthread_mutex_t m_env_mutex;
 	pthread_mutex_t m_opt_mutex;
 	pthread_mutex_t m_envopt_mutex;
-	AudioCapObj* m_pAudioCap;
+	IAudioMgr* m_pAudioCap;
 #endif
 };
 

+ 0 - 89
Module/mod_mediacontroller/videocapobj.cpp

@@ -1,89 +0,0 @@
-#include"videocapobj.h"
-#include<stdlib.h>
-#include<string.h>
-#include<stdarg.h>
-#include <time.h>
-#include <stdio.h>
-#include "SpBase.h"
-
-VideoCapObj::VideoCapObj()
-{
-	m_pVideoCap = NULL;
-}
-
-VideoCapObj::~VideoCapObj()
-{
-	if (NULL != m_pVideoCap){
-		DestroyVideoCaptureObj(m_pVideoCap);
-	}
-}
-
-int VideoCapObj::Init()
-{
-	int iRet = -1;
-	m_pVideoCap = CreateVideoCaptureObj(this);
-	if (NULL != m_pVideoCap){
-		iRet = 0;
-	}
-
-	return iRet;
-}
-
-
-int VideoCapObj::VideoCaptureSetParam(videocap_param_t* param)
-{
-	return m_pVideoCap->VideoCaptureSetParam(param);
-}
-
-
-int VideoCapObj::StartVideoCapture()
-{
-	return m_pVideoCap->StartVideoCapture();
-}
-
-
-int VideoCapObj::StopVideoCapture()
-{
-	return m_pVideoCap->StopVideoCapture();
-}
-
-
-void VideoCapObj::VideoCaptureDestroy()
-{
-	return m_pVideoCap->VideoCaptureDestroy();
-}
-
-
-int VideoCapObj::GetCamBrightness(int* ibright)
-{
-	return m_pVideoCap->GetCamBrightness(ibright);
-}
-
-int VideoCapObj::SetCamBrightness(int ibright)
-{
-	return m_pVideoCap->SetCamBrightness(ibright);
-}
-
-int VideoCapObj::SetCamAutoBrightness()
-{
-	return m_pVideoCap->SetCamAutoBrightness();
-}
-
-
-void VideoCapObj::Debug(const char* fmt, ...)
-{
-	va_list arg;
-	va_start(arg, fmt);
-	vDbg(fmt, arg);
-	va_end(arg);
-}
-
-void VideoCapObj::OnCaptureFailed()
-{
-
-}
-
-void VideoCapObj::OnVideoCaptureExcption()
-{
-
-}

+ 0 - 28
Module/mod_mediacontroller/videocapobj.h

@@ -1,28 +0,0 @@
-#pragma once
-
-#include "../../Other/libvideocapture/ivideocaptureinterface.h"
-
-
-class VideoCapObj : public ICaptureCallback, public IVideoCapture
-{
-public:
-	VideoCapObj();
-	virtual ~VideoCapObj();
-
-	void Debug(const char* fmt, ...);
-	void OnCaptureFailed();
-	void OnVideoCaptureExcption();
-
-	int Init();
-	int VideoCaptureSetParam(videocap_param_t* param);
-	int StartVideoCapture();
-	int StopVideoCapture();
-	void VideoCaptureDestroy();
-
-	int GetCamBrightness(int* ibright);
-	int SetCamBrightness(int ibright);
-	int SetCamAutoBrightness();
-	
-private:
-	IVideoCapture* m_pVideoCap;
-};

+ 4 - 4
Module/mod_recorder/mod_recorder.cpp

@@ -180,8 +180,8 @@ public:
 			m_RecordSaveDir += SPLIT_SLASH_STR;
 		}
 
-		av_log_set_level(AV_LOG_DEBUG);
-		av_log_set_callback(logCallbacks);
+		//av_log_set_level(AV_LOG_DEBUG);
+		//av_log_set_callback(logCallbacks);
 		return Error;
 	}
 
@@ -200,7 +200,7 @@ public:
 		GetFunction()->UnregistSysVarEvent(SYSVAR_CAMERASTATE);
 		StopRecord();
 
-		av_log_set_callback(NULL);
+		//av_log_set_callback(NULL);
 		return Error_Succeed;
 	}
 
@@ -350,7 +350,7 @@ private:
 		Rvc_RecordAudioParam_t tAudioParams;
 		tAudioParams.eRecordType = eSingleSide;
 		tAudioParams.eOutPutType = eLowDefinition;
-		tAudioParams.bIsNsOn = false;
+		tAudioParams.bIsNsOn = true;
 		tAudioParams.iNsPolicy = 2;
 		tAudioParams.iAudioOutBitRate = 8;
 		tAudioParams.bIsTransOn = false;

+ 0 - 4
Module/mod_sipphone/CMakeLists.txt

@@ -27,10 +27,6 @@ if(MSVC)
 	)
 else()
 	set(${SIPPHONE_PLATFORM}_SRCS 
-	videorenderobj.h
-	videorenderobj.cpp
-	audio_manager.h
-	audio_manager.cpp
 	)
 endif(MSVC)
 

+ 115 - 0
Module/mod_sipphone/SIPPhone_client_g.h

@@ -179,6 +179,121 @@ public:
 		return pFunc->OnewayCall(PhoneService_Method_SetCallingParam, PhoneService_MethodSignature_SetCallingParam, Buf);
 	}
 
+	ErrorCodeEnum GetHandfreeOutVolume(PhoneService_GetHandfreeOutVolume_Req &Req, CSmartPointer<IAsynWaitSp> &spAsyncWait, DWORD dwTimeout)
+	{
+		CSmartPointer<IClientSessionFunction> pFunc = GetFunction();
+		CAutoBuffer Buf = SpObject2Buffer(Req);
+		return pFunc->AsyncRequest(PhoneService_Method_GetHandfreeOutVolume, PhoneService_MethodSignature_GetHandfreeOutVolume, Buf, spAsyncWait, dwTimeout);
+	}
+	ErrorCodeEnum GetHandfreeOutVolume(PhoneService_GetHandfreeOutVolume_Req &Req, PhoneService_GetHandfreeOutVolume_Ans &Ans, DWORD dwTimeout)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = GetHandfreeOutVolume(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+	ErrorCodeEnum GetHandfreeOutVolume(PhoneService_GetHandfreeOutVolume_Req &Req, PhoneService_GetHandfreeOutVolume_Ans &Ans, DWORD dwTimeout, DWORD &dwUserError)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = GetHandfreeOutVolume(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwUserError, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+
+	ErrorCodeEnum SetHandfreeOutVolume(PhoneService_SetHandfreeOutVolume_Req &Req, CSmartPointer<IAsynWaitSp> &spAsyncWait, DWORD dwTimeout)
+	{
+		CSmartPointer<IClientSessionFunction> pFunc = GetFunction();
+		CAutoBuffer Buf = SpObject2Buffer(Req);
+		return pFunc->AsyncRequest(PhoneService_Method_SetHandfreeOutVolume, PhoneService_MethodSignature_SetHandfreeOutVolume, Buf, spAsyncWait, dwTimeout);
+	}
+	ErrorCodeEnum SetHandfreeOutVolume(PhoneService_SetHandfreeOutVolume_Req &Req, PhoneService_SetHandfreeOutVolume_Ans &Ans, DWORD dwTimeout)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = SetHandfreeOutVolume(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+	ErrorCodeEnum SetHandfreeOutVolume(PhoneService_SetHandfreeOutVolume_Req &Req, PhoneService_SetHandfreeOutVolume_Ans &Ans, DWORD dwTimeout, DWORD &dwUserError)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = SetHandfreeOutVolume(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwUserError, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+
+	ErrorCodeEnum SetPickupOutVolume(PhoneService_SetPickupOutVolume_Req &Req, CSmartPointer<IAsynWaitSp> &spAsyncWait, DWORD dwTimeout)
+	{
+		CSmartPointer<IClientSessionFunction> pFunc = GetFunction();
+		CAutoBuffer Buf = SpObject2Buffer(Req);
+		return pFunc->AsyncRequest(PhoneService_Method_SetPickupOutVolume, PhoneService_MethodSignature_SetPickupOutVolume, Buf, spAsyncWait, dwTimeout);
+	}
+	ErrorCodeEnum SetPickupOutVolume(PhoneService_SetPickupOutVolume_Req &Req, PhoneService_SetPickupOutVolume_Ans &Ans, DWORD dwTimeout)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = SetPickupOutVolume(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+	ErrorCodeEnum SetPickupOutVolume(PhoneService_SetPickupOutVolume_Req &Req, PhoneService_SetPickupOutVolume_Ans &Ans, DWORD dwTimeout, DWORD &dwUserError)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = SetPickupOutVolume(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwUserError, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+
+	ErrorCodeEnum GetPickupOutVolume(PhoneService_GetPickupOutVolume_Req &Req, CSmartPointer<IAsynWaitSp> &spAsyncWait, DWORD dwTimeout)
+	{
+		CSmartPointer<IClientSessionFunction> pFunc = GetFunction();
+		CAutoBuffer Buf = SpObject2Buffer(Req);
+		return pFunc->AsyncRequest(PhoneService_Method_GetPickupOutVolume, PhoneService_MethodSignature_GetPickupOutVolume, Buf, spAsyncWait, dwTimeout);
+	}
+	ErrorCodeEnum GetPickupOutVolume(PhoneService_GetPickupOutVolume_Req &Req, PhoneService_GetPickupOutVolume_Ans &Ans, DWORD dwTimeout)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = GetPickupOutVolume(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+	ErrorCodeEnum GetPickupOutVolume(PhoneService_GetPickupOutVolume_Req &Req, PhoneService_GetPickupOutVolume_Ans &Ans, DWORD dwTimeout, DWORD &dwUserError)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = GetPickupOutVolume(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwUserError, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
 
 	bool SafeDelete()
 	{

+ 86 - 0
Module/mod_sipphone/SIPPhone_def_g.h

@@ -29,6 +29,10 @@ namespace SIPPhone {
 #define PhoneService_Method_EndState 7
 #define PhoneService_Method_PhoneState 8
 #define PhoneService_Method_SetCallingParam 9
+#define PhoneService_Method_GetHandfreeOutVolume 10
+#define PhoneService_Method_SetHandfreeOutVolume 11
+#define PhoneService_Method_SetPickupOutVolume 12
+#define PhoneService_Method_GetPickupOutVolume 13
 
 #define PhoneService_MethodSignature_MakeCall -1045574280
 #define PhoneService_MethodSignature_HangupCall 507892508
@@ -40,6 +44,10 @@ namespace SIPPhone {
 #define PhoneService_MethodSignature_EndState -1780469139
 #define PhoneService_MethodSignature_PhoneState -731514138
 #define PhoneService_MethodSignature_SetCallingParam 36667377
+#define PhoneService_MethodSignature_GetHandfreeOutVolume 1306483555
+#define PhoneService_MethodSignature_SetHandfreeOutVolume 2042464727
+#define PhoneService_MethodSignature_SetPickupOutVolume -1088342808
+#define PhoneService_MethodSignature_GetPickupOutVolume 1201465844
 
 struct PhoneService_MakeCall_Req
 {
@@ -190,7 +198,85 @@ struct PhoneService_SetCallingParam_Info
 
 };
 
+struct PhoneService_GetHandfreeOutVolume_Req
+{
+
+	void Serialize(SpBuffer &Buf)
+	{
+	}
+
+};
+
+struct PhoneService_GetHandfreeOutVolume_Ans
+{
+	int Volume;
+
+	void Serialize(SpBuffer &Buf)
+	{
+		auto & buf = Buf & Volume;
+	}
+
+};
+
+struct PhoneService_SetHandfreeOutVolume_Req
+{
+	int Volume;
+
+	void Serialize(SpBuffer &Buf)
+	{
+		auto & buf = Buf & Volume;
+	}
+
+};
+
+struct PhoneService_SetHandfreeOutVolume_Ans
+{
+
+	void Serialize(SpBuffer &Buf)
+	{
+	}
+
+};
 
+struct PhoneService_SetPickupOutVolume_Req
+{
+	int Volume;
+
+	void Serialize(SpBuffer &Buf)
+	{
+		auto & buf = Buf & Volume;
+	}
+
+};
+
+struct PhoneService_SetPickupOutVolume_Ans
+{
+
+	void Serialize(SpBuffer &Buf)
+	{
+	}
+
+};
+
+struct PhoneService_GetPickupOutVolume_Req
+{
+
+	void Serialize(SpBuffer &Buf)
+	{
+	}
+
+};
+
+struct PhoneService_GetPickupOutVolume_Ans
+{
+	int Volume;
+
+	void Serialize(SpBuffer &Buf)
+	{
+		auto & buf = Buf & Volume;
+	}
+
+};
 ///////////////////////////
 
 } // namespace SIPPhone

+ 100 - 0
Module/mod_sipphone/SIPPhone_server_g.h

@@ -87,6 +87,34 @@ public:
 				Error = Error_MethodSignatureFailed;
 			}
 			break;
+		case PhoneService_Method_GetHandfreeOutVolume:
+			if (dwSignature == PhoneService_MethodSignature_GetHandfreeOutVolume) {
+				bOverlap = true;
+			} else {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
+		case PhoneService_Method_SetHandfreeOutVolume:
+			if (dwSignature == PhoneService_MethodSignature_SetHandfreeOutVolume) {
+				bOverlap = true;
+			} else {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
+		case PhoneService_Method_SetPickupOutVolume:
+			if (dwSignature == PhoneService_MethodSignature_SetPickupOutVolume) {
+				bOverlap = true;
+			} else {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
+		case PhoneService_Method_GetPickupOutVolume:
+			if (dwSignature == PhoneService_MethodSignature_GetPickupOutVolume) {
+				bOverlap = true;
+			} else {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
 		default:
 			Error = Error_MethodNotFound;
 			break;
@@ -143,6 +171,26 @@ public:
 				Error = Error_MethodSignatureFailed;
 			}
 			break;
+		case PhoneService_Method_GetHandfreeOutVolume:
+			if (dwSignature != PhoneService_MethodSignature_GetHandfreeOutVolume) {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
+		case PhoneService_Method_SetHandfreeOutVolume:
+			if (dwSignature != PhoneService_MethodSignature_SetHandfreeOutVolume) {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
+		case PhoneService_Method_SetPickupOutVolume:
+			if (dwSignature != PhoneService_MethodSignature_SetPickupOutVolume) {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
+		case PhoneService_Method_GetPickupOutVolume:
+			if (dwSignature != PhoneService_MethodSignature_GetPickupOutVolume) {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
 		default:
 			Error = Error_MethodNotFound;
 			break;
@@ -195,6 +243,26 @@ public:
 	/// override by user
 	}
 
+	virtual void Handle_GetHandfreeOutVolume(SpReqAnsContext<PhoneService_GetHandfreeOutVolume_Req, PhoneService_GetHandfreeOutVolume_Ans>::Pointer ctx)
+	{
+	/// override by user
+	}
+
+	virtual void Handle_SetHandfreeOutVolume(SpReqAnsContext<PhoneService_SetHandfreeOutVolume_Req, PhoneService_SetHandfreeOutVolume_Ans>::Pointer ctx)
+	{
+	/// override by user
+	}
+
+	virtual void Handle_SetPickupOutVolume(SpReqAnsContext<PhoneService_SetPickupOutVolume_Req, PhoneService_SetPickupOutVolume_Ans>::Pointer ctx)
+	{
+	/// override by user
+	}
+
+	virtual void Handle_GetPickupOutVolume(SpReqAnsContext<PhoneService_GetPickupOutVolume_Req, PhoneService_GetPickupOutVolume_Ans>::Pointer ctx)
+	{
+	/// override by user
+	}
+
 	virtual void OnRequest(CSmartPointer<ITransactionContext> pTransactionContext)
 	{
 		CAutoBuffer Buf;
@@ -283,6 +351,38 @@ public:
 						Handle_SetCallingParam(ctx);
 					}
 					break;
+				case PhoneService_Method_GetHandfreeOutVolume:
+					{
+						SpReqAnsContext<PhoneService_GetHandfreeOutVolume_Req,PhoneService_GetHandfreeOutVolume_Ans>::Pointer ctx;
+						ctx.Attach(new SpReqAnsContext<PhoneService_GetHandfreeOutVolume_Req,PhoneService_GetHandfreeOutVolume_Ans>(pTransactionContext));
+						SpBuffer2Object(Buf, ctx->Req);
+						Handle_GetHandfreeOutVolume(ctx);
+					}
+					break;
+				case PhoneService_Method_SetHandfreeOutVolume:
+					{
+						SpReqAnsContext<PhoneService_SetHandfreeOutVolume_Req,PhoneService_SetHandfreeOutVolume_Ans>::Pointer ctx;
+						ctx.Attach(new SpReqAnsContext<PhoneService_SetHandfreeOutVolume_Req,PhoneService_SetHandfreeOutVolume_Ans>(pTransactionContext));
+						SpBuffer2Object(Buf, ctx->Req);
+						Handle_SetHandfreeOutVolume(ctx);
+					}
+					break;
+				case PhoneService_Method_SetPickupOutVolume:
+					{
+						SpReqAnsContext<PhoneService_SetPickupOutVolume_Req,PhoneService_SetPickupOutVolume_Ans>::Pointer ctx;
+						ctx.Attach(new SpReqAnsContext<PhoneService_SetPickupOutVolume_Req,PhoneService_SetPickupOutVolume_Ans>(pTransactionContext));
+						SpBuffer2Object(Buf, ctx->Req);
+						Handle_SetPickupOutVolume(ctx);
+					}
+					break;
+				case PhoneService_Method_GetPickupOutVolume:
+					{
+						SpReqAnsContext<PhoneService_GetPickupOutVolume_Req,PhoneService_GetPickupOutVolume_Ans>::Pointer ctx;
+						ctx.Attach(new SpReqAnsContext<PhoneService_GetPickupOutVolume_Req,PhoneService_GetPickupOutVolume_Ans>(pTransactionContext));
+						SpBuffer2Object(Buf, ctx->Req);
+						Handle_GetPickupOutVolume(ctx);
+					}
+					break;
 				default:
 					assert(0);
 					break;

+ 28 - 0
Module/mod_sipphone/SipService.xml

@@ -60,6 +60,34 @@
 			<param name="connect_ip" type="string"/>
 			<param name="connect_port" type="int"/>
 		</oneway>
+		<twoway name="GetHandfreeOutVolume" overlap="true">
+			<req>
+			</req>
+			<res>
+				<param name="Volume" type="int"/>
+			</res>
+		</twoway>
+		<twoway name="SetHandfreeOutVolume" overlap="true">
+			<req>
+				<param name="Volume" type="int"/>
+			</req>
+			<res>
+			</res>
+		</twoway>
+		<twoway name="SetPickupOutVolume" overlap="true">
+			<req>
+				<param name="Volume" type="int"/>
+			</req>
+			<res>
+			</res>
+		</twoway>
+		<twoway name="GetPickupOutVolume" overlap="true">
+			<req>
+			</req>
+			<res>
+				<param name="Volume" type="int"/>
+			</res>
+		</twoway>
 	</class>
 	<!-- ÊÓÆµ¿ò¿ªÊ¼Òƶ¯ÏûÏ¢ -->
 	<message name="VideoBoxStartMove">

+ 0 - 91
Module/mod_sipphone/audio_manager.cpp

@@ -1,91 +0,0 @@
-#include"audio_manager.h"
-#include<stdlib.h>
-#include<string.h>
-#include<stdarg.h>
-#include <time.h>
-#include <stdio.h>
-#include "SpBase.h"
-
-
-#ifndef RVC_MAX_VOLUME
-#define RVC_MAX_VOLUME 65536
-#endif
-
-
-CAudioManager::CAudioManager()
-{
-	m_pAudioMgr = CreateAudioMgrObj(this);
-}
-
-CAudioManager::~CAudioManager()
-{
-	if (NULL != m_pAudioMgr){
-		DestroyIAudioMgrObj(m_pAudioMgr);
-	}
-}
-
-int CAudioManager::audio_get_device_count(bool binput)
-{
-	return m_pAudioMgr->audio_get_device_count(binput);
-}
-
-int CAudioManager::audio_get_device_name(char* strbuf, size_t ulen, bool binput, int index)
-{
-	return m_pAudioMgr->audio_get_device_name(strbuf, ulen, binput, index);
-}
-
-int CAudioManager::audio_get_device_id(const char* pstrname, bool binput)
-{
-	return m_pAudioMgr->audio_get_device_id(pstrname, binput);
-}
-
-int CAudioManager::audio_get_device_volume(int* ivolume, const char* pstrname, bool binput)
-{
-	int iret = m_pAudioMgr->audio_get_device_volume(ivolume, pstrname, binput);
-	float fvol = (*ivolume) * 1000 / RVC_MAX_VOLUME;
-	int ivol = fvol;
-	int ilast = ivol % 10;
-	int inum = ivol / 10;
-	if (ilast >= 5) {
-		inum++;
-	}
-
-	*ivolume = inum;
-
-	return iret;
-}
-
-int CAudioManager::audio_set_device_volume(int ivolume, const char* pstrname, bool binput)
-{
-	int ivol = ivolume * RVC_MAX_VOLUME / 100;
-	return m_pAudioMgr->audio_set_device_volume(ivol, pstrname, binput);
-}
-
-void CAudioManager::debug(const char* fmt, ...)
-{
-	va_list arg;
-	va_start(arg, fmt);
-	vDbg(fmt, arg);
-	va_end(arg);
-}
-
-void CAudioManager::on_audio_mgr_failed()
-{
-
-}
-
-void CAudioManager::on_audio_mgr_excption()
-{
-
-}
-
-int CAudioManager::audio_mgr_initialize()
-{
-	return m_pAudioMgr->audio_mgr_initialize();
-}
-
-int CAudioManager::audio_mgr_terminate()
-{
-	return m_pAudioMgr->audio_mgr_terminate();
-}
-

+ 0 - 28
Module/mod_sipphone/audio_manager.h

@@ -1,28 +0,0 @@
-#pragma once
-
-#include "../../Other/libaudiomgr/iaudiomgrinterface.h"
-
-
-class CAudioManager : public IAudioMgrCallback
-{
-public:
-	CAudioManager();
-	virtual ~CAudioManager();
-
-	void debug(const char* fmt, ...);
-	void on_audio_mgr_failed();
-	void on_audio_mgr_excption();
-
-	int audio_mgr_initialize();
-	int audio_mgr_terminate();
-
-	int audio_get_device_count(bool binput);
-	int audio_get_device_name(char* strbuf, size_t ulen, bool binput, int index);
-	int audio_get_device_id(const char* pstrname, bool binput);
-
-	int audio_get_device_volume(int* ivolume, const char* pstrname, bool binput);
-	int audio_set_device_volume(int ivolume, const char* pstrname, bool binput);
-
-private:
-	IAudioMgr* m_pAudioMgr;
-};

+ 10 - 2
Module/mod_sipphone/audio_session.cpp

@@ -976,17 +976,25 @@ static int phonemedia_start_remote_recording(audio_session_t *session, const aud
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //// audio session
 
+static void __audionslog(void* user_data, const char* fmt, va_list arg)
+{
+	vDbg(fmt, arg);
+}
+
+
 int audio_session_create(const audio_session_conf_t *conf, audio_session_t **p_session)
 {
 	audio_session_t *session = ZALLOC_T(audio_session_t);
 	session->remoteaudioqueue = new Clibaudioqueue(REC_COMMON_REMOTEAUDIO_SHM_QUEUE);
 	session->brtpinsertqueue = false;
 	session->baudiorecved = false;
-	session->audionsobj = CreateIAudioNsObj();
+	audions_callback_t t_callback = { 0 };
+	t_callback.debug = &__audionslog;
+	session->audionsobj = CreateIAudioNsObj(&t_callback);
 	if (NULL != session->audionsobj){
 		session->audionsobj->SetNsParams(8000, 10, 2);
 	}
-	session->audioplaynsobj = CreateIAudioNsObj();
+	session->audioplaynsobj = CreateIAudioNsObj(&t_callback);
 	if (NULL != session->audioplaynsobj) {
 		session->audioplaynsobj->SetNsParams(8000, 10, 2);
 	}

+ 149 - 2
Module/mod_sipphone/mod_sipphone.cpp

@@ -534,6 +534,11 @@ void CSIPEntity::OnStarted()
 	}
 }
 
+static void __audiomgrlog(void* user_data, const char* fmt, va_list arg)
+{
+	vDbg(fmt, arg);
+}
+
 ErrorCodeEnum CSIPEntity::__OnStart(ErrorCodeEnum preOperationError)
 {
 	ErrorCodeEnum Error;
@@ -605,7 +610,9 @@ ErrorCodeEnum CSIPEntity::__OnStart(ErrorCodeEnum preOperationError)
 
 #ifdef RVC_OS_LINUX
 	{
-		m_pAudioMgr = new CAudioManager();
+		audiomgr_callback_t t_callback = { 0 };
+		t_callback.debug = &__audiomgrlog;
+		m_pAudioMgr = CreateAudioMgrObj(&t_callback);
 		if (0 == m_pAudioMgr->audio_mgr_initialize()) {
 			Dbg("Audio Manager Initialize success!");
 		}
@@ -1361,6 +1368,90 @@ void CSIPEntity::SendAudioDeviceVolumn(int nDevice)
 }
 
 
+ErrorCodeEnum CSIPEntity::SetHandfreeOutVolume(int iVolume)
+{
+	ErrorCodeEnum Error = Error_Succeed;
+
+	Dbg("handle set hand free out volume = %d.", iVolume);
+
+#ifdef RVC_OS_WIN
+	if (m_pKeeperOut[DEV_HANDFREE])
+	{
+		volume_keeper_change(m_pKeeperOut[DEV_HANDFREE], num.nValue);
+		m_kept_volume_out[DEV_HANDFREE] = iVolume;
+		Dbg("set hand free out volume to %d.", iVolume);
+		SaveAudioRunConfig(m_kept_volume_out[DEV_HANDFREE], m_kept_volume_out[DEV_PICKUP], m_kept_volume_in[DEV_HANDFREE], m_kept_volume_in[DEV_PICKUP]);
+	}
+	else
+	{
+		Dbg("HANDFREE out volume keeper create failed!");
+	}
+#else
+	if (m_pAudioMgr)
+	{
+		m_pAudioMgr->audio_set_device_volume(iVolume, conf.audio_handfree_out_dev, false);
+		m_kept_volume_out[DEV_HANDFREE] = iVolume;
+		Dbg("set hand free out volume to %d.", iVolume);
+		SaveAudioRunConfig(m_kept_volume_out[DEV_HANDFREE], m_kept_volume_out[DEV_PICKUP], m_kept_volume_in[DEV_HANDFREE], m_kept_volume_in[DEV_PICKUP]);
+	}
+	else
+	{
+		Dbg("HANDFREE out volume keeper create failed!");
+	}
+#endif
+
+	return Error;
+}
+
+ErrorCodeEnum CSIPEntity::SetPickupOutVolume(int iVolume)
+{
+	ErrorCodeEnum Error = Error_Succeed;
+
+	Dbg("handle set pickup out volume = %d.", iVolume);
+
+#ifdef RVC_OS_WIN
+	if (m_pKeeperOut[DEV_PICKUP])
+	{
+		if (eStand2sType == m_eDeviceType)
+		{
+			volume_keeper_change(m_pKeeperOut[DEV_PICKUP], num.nValue);
+			m_kept_volume_out[DEV_PICKUP] = iVolume;
+			Dbg("set pick up out volume to %d.", iVolume);
+			SaveAudioRunConfig(m_kept_volume_out[DEV_HANDFREE], m_kept_volume_out[DEV_PICKUP], m_kept_volume_in[DEV_HANDFREE], m_kept_volume_in[DEV_PICKUP]);
+		}
+		else   //pad版屏蔽当前PICKUP音量设置
+		{
+			Dbg("PAD type, ignore pickupout volume adj");
+		}
+	}
+	else
+	{
+		Dbg("PICKUP out volume keeper create failed!");
+	}
+#else
+	if (m_pAudioMgr)
+	{
+		if (eStand2sType == m_eDeviceType)
+		{
+			m_pAudioMgr->audio_set_device_volume(iVolume, conf.audio_pickup_out_dev, false);
+			m_kept_volume_out[DEV_PICKUP] = iVolume;
+			SaveAudioRunConfig(m_kept_volume_out[DEV_HANDFREE], m_kept_volume_out[DEV_PICKUP], m_kept_volume_in[DEV_HANDFREE], m_kept_volume_in[DEV_PICKUP]);
+		}
+		else   //pad版屏蔽当前PICKUP音量设置
+		{
+			Dbg("PAD type, ignore pickupout volume adj");
+		}
+	}
+	else
+	{
+		Dbg("PICKUP out volume keeper create failed!");
+	}
+#endif
+
+	return Error;
+}
+
+
 void CSIPEntity::OnPreClose(EntityCloseCauseEnum eCloseCause,CSmartPointer<ITransactionContext> pTransactionContext) 
 { 
 	ErrorCodeEnum Error = __OnClose(Error_Succeed);
@@ -1413,7 +1504,7 @@ ErrorCodeEnum CSIPEntity::__OnClose(ErrorCodeEnum preOperationError)
 #else
 	if (NULL != m_pAudioMgr) {
 		m_pAudioMgr->audio_mgr_terminate();
-		delete m_pAudioMgr;
+		DestroyIAudioMgrObj(m_pAudioMgr);
 		m_pAudioMgr = NULL;
 	}
 #endif
@@ -2125,6 +2216,62 @@ void CSIPPhoneSession::Handle_EndState( SpOnewayCallContext<PhoneService_EndStat
 	m_spCallbackContext.Clear();
 }
 
+
+void CSIPPhoneSession::Handle_GetHandfreeOutVolume(SpReqAnsContext<PhoneService_GetHandfreeOutVolume_Req, PhoneService_GetHandfreeOutVolume_Ans>::Pointer ctx)
+{
+	LOG_FUNCTION();
+	ctx->Ans.Volume = m_pEntity->m_kept_volume_out[DEV_HANDFREE];
+	Dbg("get hand free out volume is %d.", ctx->Ans.Volume);
+	ctx->Answer(Error_Succeed);
+}
+
+
+void CSIPPhoneSession::Handle_SetHandfreeOutVolume(SpReqAnsContext<PhoneService_SetHandfreeOutVolume_Req, PhoneService_SetHandfreeOutVolume_Ans>::Pointer ctx)
+{
+	LOG_FUNCTION();
+	int iVolume = ctx->Req.Volume;
+	if (iVolume > 100){
+		iVolume = 100;
+	}
+	if (iVolume < 30){
+		iVolume = 30;
+	}
+
+	m_pEntity->SetHandfreeOutVolume(iVolume);
+	ctx->Answer(Error_Succeed);
+}
+
+
+void CSIPPhoneSession::Handle_GetPickupOutVolume(SpReqAnsContext<PhoneService_GetPickupOutVolume_Req, PhoneService_GetPickupOutVolume_Ans>::Pointer ctx)
+{
+	LOG_FUNCTION();
+	if (eStand2sType == m_pEntity->m_eDeviceType){
+		ctx->Ans.Volume = m_pEntity->m_kept_volume_out[DEV_PICKUP];
+	} 
+	else{
+		ctx->Ans.Volume = 0;
+	}
+	
+	Dbg("get pickup out volume is %d.", ctx->Ans.Volume);
+	ctx->Answer(Error_Succeed);
+}
+
+
+void CSIPPhoneSession::Handle_SetPickupOutVolume(SpReqAnsContext<PhoneService_SetPickupOutVolume_Req, PhoneService_SetPickupOutVolume_Ans>::Pointer ctx)
+{
+	LOG_FUNCTION();
+	if (eStand2sType == m_pEntity->m_eDeviceType) {
+		int iVolume = ctx->Req.Volume;
+		if (iVolume > 100) {
+			iVolume = 100;
+		}
+		if (iVolume < 30) {
+			iVolume = 30;
+		}
+		m_pEntity->SetPickupOutVolume(iVolume);
+	}
+	ctx->Answer(Error_Succeed);
+}
 void CSIPPhoneSession::hangup_call(/*CSIPPhoneSession::HangupCallCommand* cmd*/)
 {
 	if (m_pCall) {

+ 7 - 2
Module/mod_sipphone/mod_sipphone.h

@@ -16,7 +16,7 @@ using namespace SelfChecker;
 
 #include "../mod_assistantchannel/chan_protocol.h"
 #include "../mod_assistantchannel/AssistantChannel_client_g.h"
-#include "audio_manager.h"
+#include "../../Other/libaudiomgr/iaudiomgrinterface.h"
 
 using namespace AssistantChannel;
 
@@ -156,6 +156,10 @@ public:
 	virtual void Handle_RealErrorCheck(SpOnewayCallContext<PhoneService_RealErrorCheck_Info>::Pointer ctx);
 	virtual void Handle_SetCallingParam(SpOnewayCallContext<PhoneService_SetCallingParam_Info>::Pointer ctx);
 	virtual void OnClose(ErrorCodeEnum eErrorCode);
+	virtual void Handle_GetHandfreeOutVolume(SpReqAnsContext<PhoneService_GetHandfreeOutVolume_Req, PhoneService_GetHandfreeOutVolume_Ans>::Pointer ctx);
+	virtual void Handle_SetHandfreeOutVolume(SpReqAnsContext<PhoneService_SetHandfreeOutVolume_Req, PhoneService_SetHandfreeOutVolume_Ans>::Pointer ctx);
+	virtual void Handle_GetPickupOutVolume(SpReqAnsContext<PhoneService_GetPickupOutVolume_Req, PhoneService_GetPickupOutVolume_Ans>::Pointer ctx);
+	virtual void Handle_SetPickupOutVolume(SpReqAnsContext<PhoneService_SetPickupOutVolume_Req, PhoneService_SetPickupOutVolume_Ans>::Pointer ctx);
 
 public:
 	void on_call_state(int state, const char *state_desc, const char *phrase);
@@ -203,6 +207,7 @@ public:
 	//send audio device volume
 	void SendAudioDeviceVolumn(int nDevice);
 	ErrorCodeEnum SetHandfreeOutVolume(int iVolume);
+	ErrorCodeEnum SetPickupOutVolume(int iVolume);
 
 	virtual void OnPreClose(EntityCloseCauseEnum eCloseCause,CSmartPointer<ITransactionContext> pTransactionContext);
 	ErrorCodeEnum __OnClose(ErrorCodeEnum preOperationError);
@@ -246,7 +251,7 @@ public:
 	void* m_pKeeperIn[2];
 	void* m_pKeeperOut[2];
 #else
-	CAudioManager* m_pAudioMgr;
+	IAudioMgr* m_pAudioMgr;
 #endif
 	//int m_nDownDynamicFps;	//当前视频下行的帧频,由前端通知后端更改频率,只有移动版才使用
 	CSystemStaticInfo staticInfo;

+ 32 - 14
Module/mod_sipphone/video_session.cpp

@@ -23,7 +23,7 @@
 #include <DbgHelp.h>
 #pragma comment(lib, "dbghelp.lib")
 #else
-#include "videorenderobj.h"
+#include "../../Other/libvideorender/ivideorenderinterface.h"
 #include "../../Other/libvideocapture/ivideocaptureinterface.h"
 #include <signal.h>
 #include <semaphore.h>
@@ -122,8 +122,8 @@ struct video_session_t
 	HWND local_hwnd; // preview window
 	HWND remote_hwnd; // remote window
 #else
-	VideoRenderObj* plocal_render;
-	VideoRenderObj* premote_render;
+	IVideoRender* plocal_render;
+	IVideoRender* premote_render;
 	pthread_t ui_threadid;
 	sem_t ui_stop_sem;
 	bool bshow_remote;
@@ -475,13 +475,13 @@ static int on_rx_frame(video_frame *frame, void *user_data)
 		//Dbg("session plocal_render RenderVideoFrame");
 		video_frame* echoframe = NULL;
 		if (0 == translate_image_resolution(&echoframe,session->conf.remote_video_view_cx,session->conf.remote_video_view_cy, frame)) {
-			session->premote_render->RenderVideoFrame(echoframe);
+			session->premote_render->RenderVideoFrame(echoframe, RVC_FLIP_VERTICAL);
 			session->bshow_remote = true;
 			video_frame_delete(echoframe);
 			echoframe = NULL;
 		}
 		else {
-			session->premote_render->RenderVideoFrame(frame);
+			session->premote_render->RenderVideoFrame(frame, RVC_FLIP_VERTICAL);
 			session->bshow_remote = true;
 		}
 		used = 1;
@@ -1289,7 +1289,14 @@ static int start_video_rtpsession(video_session_t* session)
 	config.on_rx_udp = &on_rx_udp;
 	config.dbg = &__dbg;
 	config.logevent = &__logevent;
-	videortp_create(&config, &session->rtp);
+	if (0 == videortp_create(&config, &session->rtp)) {
+		Dbg("videortp create success!");
+	}
+	else {
+		Dbg("videortp create failed!");
+	}
+
+	session->premote_render->StartVideoRender();
 	rc = videortp_start(session->rtp);
 	if (rc != 0)
 	{
@@ -1782,13 +1789,14 @@ static void stop_video(video_session_t *session)
 		Dbg("remote video player destroy.");
 	}
 #else
+	session->premote_render->StopVideoRender();
 	if (session->plocal_render){
-		delete session->plocal_render;
+		DestroyVideoRenderObj(session->plocal_render);
 		session->plocal_render = NULL;
 	}
 
 	if (session->premote_render){
-		delete session->premote_render;
+		DestroyVideoRenderObj(session->premote_render);
 		session->premote_render = NULL;
 	}
 #endif
@@ -2194,6 +2202,11 @@ static unsigned int __stdcall ui_proc(void *arg)
 }
 #else
 
+static void __video_render_log(void* user_data, const char* fmt, va_list arg)
+{
+	vDbg(fmt, arg);
+}
+
 void* videorender_func(void* arg)
 {
 	LOG_FUNCTION();
@@ -2209,7 +2222,9 @@ void* videorender_func(void* arg)
 	Dbg("%s:%d local(%d,%d,%d,%d) remote(%d,%d,%d,%d).", __FUNCTION__, __LINE__, session->conf.local_video_view_x, session->conf.local_video_view_y, session->conf.local_video_view_cx, session->conf.local_video_view_cy,
 		session->conf.remote_video_view_x, session->conf.remote_video_view_y, session->conf.remote_video_view_cx, session->conf.remote_video_view_cy);
 
-	session->plocal_render = new VideoRenderObj();
+	videorender_callback_t t_callback = { 0 };
+	t_callback.debug = &__video_render_log;
+	session->plocal_render = CreateVideoRenderObj(&t_callback);
 	if (NULL != session->plocal_render){
 		videorender_param_t tparam = { 0 };
 		tparam.icx = session->conf.local_video_view_x;
@@ -2219,7 +2234,7 @@ void* videorender_func(void* arg)
 		//tparam.uvideowidth = REC_COMMON_VIDEO_PREVIEW_WIDTH;
 		//tparam.uvideoheight = REC_COMMON_VIDEO_PREVIEW_HEIGHT;
 		tparam.ivideoformat = VIDEO_FORMAT_RGB24;
-		if (0 == session->plocal_render->SetVideoRenderParam(&tparam)){
+		if (0 == session->plocal_render->VideoRenderSetParam(&tparam)){
 			session->plocal_render->HideVideoWindow();
 		}
 		else {
@@ -2230,7 +2245,7 @@ void* videorender_func(void* arg)
 
 	if (session->conf.remote_video_view_x || session->conf.remote_video_view_y || session->conf.remote_video_view_cx || session->conf.remote_video_view_cy){
 		Dbg("%s:%d create remote video hwnd x = %d, y = %d, width = %d, height = %d.", __FUNCTION__, __LINE__, session->conf.remote_video_view_x, session->conf.remote_video_view_y, session->conf.remote_video_view_cx, session->conf.remote_video_view_cy);
-		session->premote_render = new VideoRenderObj();
+		session->premote_render = CreateVideoRenderObj(&t_callback);
 		if (session->premote_render){
 			videorender_param_t tparam_remote = { 0 };
 			tparam_remote.icx = session->conf.remote_video_view_x;
@@ -2240,7 +2255,7 @@ void* videorender_func(void* arg)
 			//tparam_remote.uvideowidth = REC_COMMON_VIDEO_DSM_AGENT_WIDTH;
 			//tparam_remote.uvideoheight = REC_COMMON_VIDEO_DSM_AGENT_HEIGHT;
 			tparam_remote.ivideoformat = VIDEO_FORMAT_RGB24;
-			if (0 == session->premote_render->SetVideoRenderParam(&tparam_remote)) {
+			if (0 == session->premote_render->VideoRenderSetParam(&tparam_remote)) {
 				//session->premote_render->ShowVideoWindow();
 			}
 		}
@@ -2255,6 +2270,8 @@ void* videorender_func(void* arg)
 		bool bshow_local = false;
 		bool bset = true;
 		//session->premote_render->ShowVideoWindow();
+		
+		session->plocal_render->StartVideoRender();
 		for (; ; ) {
 			struct timespec ts;
 			clock_gettime(CLOCK_REALTIME, &ts);
@@ -2275,12 +2292,12 @@ void* videorender_func(void* arg)
 					//Dbg("%s:%d, video size is (%d,%d), showPersonArea flag is %d.", __FUNCTION__, __LINE__, local_video_frame->width, local_video_frame->height, *session->conf.ref_Is_showPersonArea);
 					video_frame* localframe = NULL;
 					if (0 == translate_image_resolution(&localframe, session->conf.local_video_view_cx, session->conf.local_video_view_cy, local_video_frame)) {
-						session->plocal_render->RenderVideoFrame(localframe);
+						session->plocal_render->RenderVideoFrame(localframe, RVC_FLIP_VERTICAL);
 						video_frame_delete(localframe);
 						localframe = NULL;
 					}
 					else {
-						session->plocal_render->RenderVideoFrame(local_video_frame);
+						session->plocal_render->RenderVideoFrame(local_video_frame, RVC_FLIP_VERTICAL);
 					}
 
 					if (false == session->blocalrender){
@@ -2310,6 +2327,7 @@ void* videorender_func(void* arg)
 				}
 			}
 		}
+		session->plocal_render->StopVideoRender();
 	}
 
 	return 0;

+ 0 - 75
Module/mod_sipphone/videorenderobj.cpp

@@ -1,75 +0,0 @@
-#include"videorenderobj.h"
-#include<stdlib.h>
-#include<string.h>
-#include<stdarg.h>
-#include <time.h>
-#include <stdio.h>
-#include "SpBase.h"
-
-VideoRenderObj::VideoRenderObj()
-{
-	m_pVideoRender = CreateVideoRenderObj(this);
-}
-
-VideoRenderObj::~VideoRenderObj()
-{
-	if (NULL != m_pVideoRender){
-		DestroyVideoRenderObj(m_pVideoRender);
-	}
-}
-
-
-void VideoRenderObj::Debug(const char* fmt, ...)
-{
-	va_list arg;
-	va_start(arg, fmt);
-	vDbg(fmt, arg);
-	va_end(arg);
-}
-
-void VideoRenderObj::OnRenderFailed()
-{
-
-}
-
-void VideoRenderObj::OnVideoRenderExcption()
-{
-
-}
-
-int VideoRenderObj::ShowVideoWindow()
-{
-	int iRet = -1;
-	if (NULL == m_pVideoRender) {
-		return iRet;
-	}
-	return m_pVideoRender->ShowVideoWindow();
-}
-
-int VideoRenderObj::HideVideoWindow()
-{
-	int iRet = -1;
-	if (NULL == m_pVideoRender) {
-		return iRet;
-	}
-	return m_pVideoRender->HideVideoWindow();
-}
-
-int VideoRenderObj::RenderVideoFrame(video_frame* pframe)
-{
-	int iRet = -1;
-	if (NULL == m_pVideoRender) {
-		return iRet;
-	}
-	return m_pVideoRender->RenderVideoFrame(pframe);
-}
-
-
-int VideoRenderObj::SetVideoRenderParam(videorender_param_t* param)
-{
-	int iRet = -1;
-	if (NULL == m_pVideoRender){
-		return iRet;
-	}
-	return m_pVideoRender->VideoRenderSetParam(param);
-}

+ 0 - 23
Module/mod_sipphone/videorenderobj.h

@@ -1,23 +0,0 @@
-#pragma once
-
-#include "../../Other/libvideorender/ivideorenderinterface.h"
-
-
-class VideoRenderObj : public IRenderCallback
-{
-public:
-	VideoRenderObj();
-	virtual ~VideoRenderObj();
-
-	void Debug(const char* fmt, ...);
-	void OnRenderFailed();
-	void OnVideoRenderExcption();
-	
-	int SetVideoRenderParam(videorender_param_t* param);
-	int ShowVideoWindow();
-	int HideVideoWindow();
-	int RenderVideoFrame(video_frame* pframe);
-
-private:
-	IVideoRender* m_pVideoRender;
-};

+ 1 - 3
Other/libaudiomgr/iaudiomgrinterface.cpp

@@ -2,10 +2,8 @@
 #include "./linux/libaudiomgr_linux.h"
 
 
-IAudioMgr* CreateAudioMgrObj(IAudioMgrCallback* pCallback)
+IAudioMgr* CreateAudioMgrObj(audiomgr_callback_t* pCallback)
 {
-	if(pCallback)
-		pCallback->debug("%s:%d", __FUNCTION__, __LINE__);
 	return new AudioMgrImpl(pCallback);
 }
 

+ 8 - 7
Other/libaudiomgr/iaudiomgrinterface.h

@@ -13,6 +13,7 @@
 #endif // RVC_OS_WIN
 
 #include <stddef.h>
+#include <stdarg.h>
 
 typedef struct audiocap_param_s
 {
@@ -29,12 +30,12 @@ typedef struct audiocap_param_s
 
 }audiocap_param_t;
 
-struct IAudioMgrCallback
-{
-	virtual void debug(const char* fmt, ...) = 0;
-	virtual void on_audio_mgr_failed() = 0;
-	virtual void on_audio_mgr_excption() = 0;
-};
+typedef struct audiomgr_callback_s{
+	void (*debug)(void* user_data, const char* fmt, va_list arg);
+	void (*on_audio_mgr_failed)();
+	void (*on_audio_mgr_excption)();
+	void* user_data;
+}audiomgr_callback_t;
 
 class IAudioMgr 
 {
@@ -56,6 +57,6 @@ public:
 };
 
 
-extern "C" LIBAUDIOMGR_API IAudioMgr* CreateAudioMgrObj(IAudioMgrCallback* pCallback);
+extern "C" LIBAUDIOMGR_API IAudioMgr* CreateAudioMgrObj(audiomgr_callback_t* pCallback);
 extern "C" LIBAUDIOMGR_API void DestroyIAudioMgrObj(IAudioMgr* pIAudioMgr);
 

+ 63 - 258
Other/libaudiomgr/linux/libaudiomgr_linux.cpp

@@ -8,6 +8,10 @@
 #define RVC_PA_ADJUST_LATENCY_PROTOCOL_VERSION 13
 #endif
 
+#ifndef RVC_MAX_VOLUME
+#define RVC_MAX_VOLUME 65536
+#endif
+
 static int sample_index = 0;
 
 // From pulsecore/macro.h
@@ -21,10 +25,10 @@ static int sink_index = 0;
 static int source_index = 0;
 
 
-AudioMgrImpl::AudioMgrImpl(IAudioMgrCallback* pCallback)
+AudioMgrImpl::AudioMgrImpl(audiomgr_callback_t* pCallback)
 {
 	m_audio_context = NULL;
-	m_callback = pCallback;
+	memcpy(&m_callback, pCallback, sizeof(audiomgr_callback_t));
 }
 
 AudioMgrImpl::~AudioMgrImpl()
@@ -48,7 +52,6 @@ AudioMgrImpl::~AudioMgrImpl()
 		free(m_audio_context);
 		m_audio_context = NULL;
 	}
-	m_callback = NULL;
 }
 
 int AudioMgrImpl::audio_mgr_destroy()
@@ -72,73 +75,15 @@ int AudioMgrImpl::audio_init_pulseaudio()
 	/*assertions*/
 	assert(NULL != m_audio_context);
 
-	//if (false == m_initialized) {
-	//	// Initialize PulseAudio
-	//	if (InitPulseAudio() < 0) {
-	//		m_callback->debug("failed to initialize PulseAudio");
-	//		if (audio_mgr_terminate() < 0) {
-	//			m_callback->debug("failed to terminate PulseAudio");
-	//		}
-	//		return -1;
-	//	}
-
-	//	m_initialized = true;
-	//}
-
 	if (pa_get_devicelist() < 0)
 	{
-		m_callback->debug( "pulse audio failed to get audio device list from pulse server\n");
+		audiolog( "pulse audio failed to get audio device list from pulse server\n");
 		return -1;
 	}
 
 	return 0;
 }
 
-
-//int32_t AudioMgrImpl::InitPulseAudio()
-//{
-	//int retVal = 0;
-	//// Create a mainloop API and connection to the default server
-	//// the mainloop is the internal asynchronous API event loop
-	//if (m_paMainloop) {
-	//	m_callback->debug("PA main loop has already existed");
-	//	return -1;
-	//}
-
-	//m_paMainloop = pa_mainloop_new();
-	//if (!m_paMainloop) {
-	//	m_callback->debug("could not create main loop");;
-	//	return -1;
-	//}
-
-	//m_paMainloopApi = pa_mainloop_get_api(m_paMainloop);
-	//if (!m_paMainloopApi) {
-	//	m_callback->debug("could not create main loop API");
-	//	return -1;
-	//}
-
-	//// Create a new PulseAudio context
-	//if (m_paContext) {
-	//	m_callback->debug("PA context has already existed");
-	//	return -1;
-	//}
-
-	//m_paContext = pa_context_new(m_paMainloopApi, "RVC VoiceEngine");
-
-	//if (!m_paContext) {
-	//	m_callback->debug("could not create context");
-	//	return -1;
-	//}
-
-	//if (pa_context_connect(m_paContext, NULL, PA_CONTEXT_NOFLAGS, NULL) < 0)
-	//{
-	//	m_callback->debug("AUDIO: PULSE - unable to connect to server: pa_context_connect failed");
-	//	return -1;
-	//}
-//
-//	return 0;
-//}
-
 /*
  * pa_mainloop will call this function when it's ready to tell us
  *  about a source (input).
@@ -178,33 +123,6 @@ static void pa_sourcelist_cb(pa_context* c, const pa_source_info* l, int eol, vo
 	double my_latency = 0.0;
 	int verbosity = 1;
 
-	//if (verbosity > 0)
-	//{
-	//	
-	//	printf("AUDIO: =======[ Input Device #%d ]=======\n", source_index);
-	//	printf("       Description: %s\n", l->description);
-	//	printf("       Name: %s\n", l->name);
-	//	printf("       Index: %d\n", l->index);
-	//	printf("       Channels: %d (default to: %d)\n", l->sample_spec.channels, channels);
-	//	printf("       SampleRate: %d\n", l->sample_spec.rate);
-	//	printf("       Latency: %llu (usec)\n", (long long unsigned) l->latency);
-	//	printf("       Configured Latency: %llu (usec)\n", (long long unsigned) l->configured_latency);
-	//	printf("       Card: %d\n", l->card);
-	//	printf("       monitor_of_sink_name: %s\n", l->monitor_of_sink_name);
-	//	printf("       driver: %s\n", l->driver);
-	//	if (l->active_port && l->active_port->name){
-	//		printf("       name: %s\n", l->active_port->name);
-	//	}
-	//	if (l->active_port && l->active_port->description){
-	//		printf("       description name: %s\n", l->active_port->description);
-	//	}
-	//	printf("	Volume channels: %d\n", l->volume.channels);
-	//	for(int i = 0; i < l->volume.channels; i++) {
-	//		printf("   Volume value: %d\n", l->volume.values[i]);
-	//	}
-	//	printf("\n");
-	//}
-
 	if (my_latency <= 0.0)
 		my_latency = (double)latency_ms / 1000;
 
@@ -215,7 +133,6 @@ static void pa_sourcelist_cb(pa_context* c, const pa_source_info* l, int eol, vo
 		audio_ctx->list_input_devices = (rvc_audio_device_t*)realloc(audio_ctx->list_input_devices, audio_ctx->num_input_dev * sizeof(rvc_audio_device_t));
 		if (audio_ctx->list_input_devices == NULL)
 		{
-			//printf("AUDIO: FATAL memory allocation failure (pa_sourcelist_cb): %s\n", strerror(errno));
 			exit(-1);
 		}
 		/*fill device data*/
@@ -302,31 +219,6 @@ static void pa_sourcevolume_cb(pa_context* c, const pa_source_info* l, int eol,
 	if (eol > 0)
 		return;
 
-	//{
-	//	printf("AUDIO: =======[ Input Device #%d ]=======\n", source_index);
-	//	printf("       Description: %s\n", l->description);
-	//	printf("       Name: %s\n", l->name);
-	//	printf("       Index: %d\n", l->index);
-	//	printf("       SampleRate: %d\n", l->sample_spec.rate);
-	//	printf("       Latency: %llu (usec)\n", (long long unsigned) l->latency);
-	//	printf("       Configured Latency: %llu (usec)\n", (long long unsigned) l->configured_latency);
-	//	printf("       Card: %d\n", l->card);
-	//	printf("       monitor_of_sink_name: %s\n", l->monitor_of_sink_name);
-	//	printf("       driver: %s\n", l->driver);
-	//	if (l->active_port && l->active_port->name) {
-	//		printf("       name: %s\n", l->active_port->name);
-	//	}
-	//	if (l->active_port && l->active_port->description) {
-	//		printf("       description name: %s\n", l->active_port->description);
-	//	}
-	//	printf("	Volume channels: %d\n", l->volume.channels);
-	//	for (int i = 0; i < l->volume.channels; i++) {
-	//		printf("   Volume value: %d\n", l->volume.values[i]);
-	//	}
-	//	printf("\n");
-	//}
-
-
 	if (l->monitor_of_sink == PA_INVALID_INDEX)
 	{
 		if (strstr(l->description, audio_volume->strdevicename)){
@@ -347,52 +239,10 @@ static void pa_sinkvolume_cb(pa_context* c, const pa_sink_info* l, int eol, void
 	if (eol > 0)
 		return;
 
-
-	//{
-	//	printf("AUDIO: =======[ Output Device #%d ]=======\n", sink_index);
-	//	printf("       Description: %s\n", l->description);
-	//	printf("       Name: %s\n", l->name);
-	//	printf("       Index: %d\n", l->index);
-	//	printf("       Channels: %d\n", l->channel_map.channels);
-	//	printf("       SampleRate: %d\n", l->sample_spec.rate);
-	//	printf("       Latency: %llu (usec)\n", (long long unsigned) l->latency);
-	//	printf("       Configured Latency: %llu (usec)\n", (long long unsigned) l->configured_latency);
-	//	printf("       Card: %d\n", l->card);
-	//	printf("       monitor_of_sink_name: %s\n", l->monitor_source_name);
-	//	printf("       driver: %s\n", l->driver);
-	//	printf("       n_ports: %d\n", l->n_ports);
-	//	printf("       name: %s\n", l->active_port->name);
-	//	printf("       description name: %s\n", l->active_port->description);
-	//	printf("	   Volume channels: %d\n", l->volume.channels);
-	//	for (int i = 0; i < l->volume.channels; i++) {
-	//		printf("	   Volume value: %d\n", l->volume.values[i]);
-	//	}
-	//	printf("\n");
-	//}
-
 	if (strstr(l->description, audio_volume->strdevicename)) {
 		audio_volume->cvolumes = l->volume;
 		audio_volume->volume_flag = 1;
 	}
-
-
-	//{
-	//	pa_cvolume cvolumes;
-	//	// Set the same volume for all channels
-	//	int ivolume = 65536;
-	//	pa_cvolume_set(&cvolumes, l->channel_map.channels, ivolume);
-	//	printf("%s:%d. audio_dev->id = %d, audio_dev->channels = %d, ivolume = %d.\n", __FUNCTION__, __LINE__, l->index, l->channel_map.channels, ivolume);
-	//	for (int i = 0; i < cvolumes.channels; i++) {
-	//		printf("%s:%d. cvolumes.values[%d] = %d.\n", __FUNCTION__, __LINE__, i, cvolumes.values[i]);
-	//	}
-	//	pa_operation* paOperation = NULL;
-	//	if (!(paOperation = pa_context_set_sink_volume_by_name(c, l->name, &cvolumes, PaSetVolumeCallback, NULL))) {
-	//		printf("pa_context_set_sink_volume_by_index() failed\n");
-	//		return;
-	//	}
-	//	pa_operation_unref(paOperation);
-	//}
-
 }
 
 /*
@@ -428,29 +278,6 @@ static void pa_sinklist_cb(pa_context* c, const pa_sink_info* l, int eol, void*
 	double my_latency = 0.0;
 	int verbosity = 1;
 
-	//if (verbosity > 0)
-	//{
-	//	printf("AUDIO: =======[ Output Device #%d ]=======\n", sink_index);
-	//	printf("       Description: %s\n", l->description);
-	//	printf("       Name: %s\n", l->name);
-	//	printf("       Index: %d\n", l->index);
-	//	printf("       Channels: %d\n", l->channel_map.channels);
-	//	printf("       SampleRate: %d\n", l->sample_spec.rate);
-	//	printf("       Latency: %llu (usec)\n", (long long unsigned) l->latency);
-	//	printf("       Configured Latency: %llu (usec)\n", (long long unsigned) l->configured_latency);
-	//	printf("       Card: %d\n", l->card);
-	//	printf("       monitor_of_sink_name: %s\n", l->monitor_source_name);
-	//	printf("       driver: %s\n", l->driver);
-	//	printf("       n_ports: %d\n", l->n_ports);
-	//	printf("       name: %s\n", l->active_port->name);
-	//	printf("       description name: %s\n", l->active_port->description);
-	//	printf("	   Volume channels: %d\n", l->volume.channels);
-	//	for (int i = 0; i < l->volume.channels; i++) {
-	//	printf("	   Volume value: %d\n", l->volume.values[i]);
-	//	}
-	//	printf("\n");
-	//}
-
 	if (my_latency <= 0.0)
 		my_latency = (double)latency_ms / 1000;
 
@@ -566,8 +393,7 @@ int AudioMgrImpl::pa_get_devicelist()
 	/* This function connects to the pulse server */
 	if (pa_context_connect(pa_ctx, NULL, PA_CONTEXT_NOFLAGS, NULL) < 0)
 	{
-		if(m_callback)
-			m_callback->debug("AUDIO: PULSE - unable to connect to server: pa_context_connect failed!");
+		audiolog("AUDIO: PULSE - unable to connect to server: pa_context_connect failed!");
 		finish(pa_ctx, pa_ml);
 		return -1;
 	}
@@ -663,8 +489,7 @@ int AudioMgrImpl::pa_get_devicelist()
 			break;
 		default:
 			/* We should never see this state */
-			if(m_callback)
-				m_callback->debug("AUDIO: Pulse audio in state %d", state);
+			audiolog("AUDIO: Pulse audio in state %d", state);
 			return -1;
 		}
 		/*
@@ -722,12 +547,10 @@ rvc_audio_device_t* AudioMgrImpl::audio_get_input_device(int index)
 	assert(m_audio_context != NULL);
 
 	if (index >= m_audio_context->num_input_dev){
-		//printf("AUDIO: (audio_get_input_device) bad index %i using %i\n",index, m_audio_context->num_input_dev - 1);
 		index = m_audio_context->num_input_dev - 1;
 	}
 
 	if (index < 0){
-		//printf("AUDIO: (audio_get_input_device) bad index %i using 0\n", index);
 		index = 0;
 	}
 
@@ -750,15 +573,11 @@ rvc_audio_device_t* AudioMgrImpl::audio_get_output_device( int index)
 	/*assertions*/
 	assert(m_audio_context != NULL);
 
-	if (index >= m_audio_context->num_output_dev)
-	{
-		//printf("AUDIO: (audio_get_output_device) bad index %i using %i\n",index, m_audio_context->num_output_dev - 1);
+	if (index >= m_audio_context->num_output_dev){
 		index = m_audio_context->num_output_dev - 1;
 	}
 
-	if (index < 0)
-	{
-		//printf("AUDIO: (audio_get_output_device) bad index %i using 0\n", index);
+	if (index < 0){
 		index = 0;
 	}
 
@@ -834,8 +653,23 @@ int AudioMgrImpl::audio_get_device_id(const char* pstrname, bool binput)
 	return iret;
 }
 
-
 int AudioMgrImpl::audio_get_device_volume(int* ivolume, const char* pstrname, bool binput)
+{
+	audiopulse_get_device_volume(ivolume, pstrname, binput);
+	float fvol = (*ivolume) * 1000 / RVC_MAX_VOLUME;
+	int ivol = fvol;
+	int ilast = ivol % 10;
+	int inum = ivol / 10;
+	if (ilast >= 5) {
+		inum++;
+	}
+
+	*ivolume = inum;
+
+	return 0;
+}
+
+int AudioMgrImpl::audiopulse_get_device_volume(int* ivolume, const char* pstrname, bool binput)
 {
 	int iret = -1;
 
@@ -859,8 +693,7 @@ int AudioMgrImpl::audio_get_device_volume(int* ivolume, const char* pstrname, bo
 	/* This function connects to the pulse server */
 	if (pa_context_connect(pa_ctx, NULL, PA_CONTEXT_NOFLAGS, NULL) < 0)
 	{
-		if(m_callback)
-			m_callback->debug("AUDIO: PULSE - unable to connect to server: pa_context_connect failed");
+		audiolog("AUDIO: PULSE - unable to connect to server: pa_context_connect failed");
 		finish(pa_ctx, pa_ml);
 		return -1;
 	}
@@ -945,8 +778,13 @@ int AudioMgrImpl::audio_get_device_volume(int* ivolume, const char* pstrname, bo
 }
 
 
-
 int AudioMgrImpl::audio_set_device_volume(int ivolume, const char* pstrname, bool binput)
+{
+	int ivol = ivolume * RVC_MAX_VOLUME / 100;
+	return audiopulse_set_device_volume(ivol, pstrname, binput);
+}
+
+int AudioMgrImpl::audiopulse_set_device_volume(int ivolume, const char* pstrname, bool binput)
 {
 	int iret = -1;
 
@@ -971,8 +809,7 @@ int AudioMgrImpl::audio_set_device_volume(int ivolume, const char* pstrname, boo
 	/* This function connects to the pulse server */
 	if (pa_context_connect(pa_ctx, NULL, PA_CONTEXT_NOFLAGS, NULL) < 0)
 	{
-		if (m_callback)
-			m_callback->debug("AUDIO: PULSE - unable to connect to server: pa_context_connect failed");
+		audiolog("AUDIO: PULSE - unable to connect to server: pa_context_connect failed");
 		finish(pa_ctx, pa_ml);
 		return -1;
 	}
@@ -1063,8 +900,7 @@ int AudioMgrImpl::audio_mgr_initialize()
 	m_audio_context = (rvc_audio_context_t*)calloc(1, sizeof(rvc_audio_context_t));
 
 	if (NULL == m_audio_context){
-        if (m_callback)
-            m_callback->debug("%s:%d couldn't allocate audio context.", __FUNCTION__, __LINE__);
+        audiolog("%s:%d couldn't allocate audio context.", __FUNCTION__, __LINE__);
 		return iret;
 	}
 
@@ -1133,18 +969,13 @@ int AudioMgrImpl::stop_audio_capture()
 {
 	/*assertions*/
 	assert(m_audio_context != NULL);
-
 	m_audio_context->stream_flag = AUDIO_STRM_OFF;
-
 	if (0 == __THREAD_JOIN(m_readthread)){
-        if (m_callback)
-            m_callback->debug("read thread join success!");
+        audiolog("read thread join success!");
 	}
 	else{
-        if (m_callback)
-            m_callback->debug("read thread join failed!");
+        audiolog("read thread join failed!");
 	}
-
 	return 0;
 }
 
@@ -1160,25 +991,6 @@ int AudioMgrImpl::audio_mgr_terminate()
 
 	iret = audio_close_pulseaudio();
 
-	//if (!m_paMainloop) {
-	//	return 0;
-	//}
-
-	//// Disconnect the context
-	//if (m_paContext) {
-	//	(pa_context_disconnect)(m_paContext);
-	//}
-
-	//// Unreference the context
-	//if (m_paContext) {
-	//	(pa_context_unref)(m_paContext);
-	//}
-
-	//m_paContext = NULL;
-	//
-	//pa_mainloop_free(m_paMainloop);
-	//m_paMainloop = NULL;
-
 	return iret;
 }
 
@@ -1202,11 +1014,9 @@ static void get_latency(pa_stream* s)
 
 	if (pa_stream_get_latency(s, &l, &negative) != 0)
 	{
-		fprintf(stderr, "AUDIO: Pulseaudio pa_stream_get_latency() failed\n");
 		return;
 	}
 
-	//latency = l * (negative?-1:1);
 	latency = l; /*can only be negative in monitoring streams*/
 }
 
@@ -1234,10 +1044,7 @@ static void stream_request_cb(pa_stream* s, size_t length, void* data)
 		return;
 	}
 
-	uint64_t frame_length = NSEC_PER_SEC / audio_ctx->samprate; /*in nanosec*/
 	int64_t ts = 0;
-	int64_t buff_ts = 0;
-	uint32_t i = 0;
 
 	while (pa_stream_readable_size(s) > 0)
 	{
@@ -1248,13 +1055,8 @@ static void stream_request_cb(pa_stream* s, size_t length, void* data)
 		if (pa_stream_peek(s, &inputBuffer, &length) < 0){
 			return;
 		}
-		else {
-			//printf("%s:%d pa_stream_peek audio length is %d.\n", __FUNCTION__, __LINE__, length);
-		}
 
-
-		if (length == 0)
-		{
+		if (length == 0){
 			return; /*buffer is empty*/
 		}
 
@@ -1265,8 +1067,6 @@ static void stream_request_cb(pa_stream* s, size_t length, void* data)
 		if (audio_ctx->last_ts <= 0)
 			audio_ctx->last_ts = ts;
 
-		uint32_t numSamples = (uint32_t)length / sizeof(sample_t);
-
 		audio_ctx->audio_param.on_audio_callback(inputBuffer, length, audio_ctx->audio_param.user_data);
 
 		pa_stream_drop(s); /*clean the samples*/
@@ -1290,9 +1090,6 @@ void* pulse_read_audio(void* data)
 	AudioMgrImpl* audio_mgr = (AudioMgrImpl*)data;
 	assert(audio_mgr != NULL);
 
-	IAudioMgrCallback* callback = audio_mgr->audio_get_callback();
-	assert(callback != NULL);
-
 	rvc_audio_context_t* audio_ctx = audio_mgr->audio_get_context();
 	/*assertions*/
 	assert(audio_ctx != NULL);
@@ -1316,7 +1113,7 @@ void* pulse_read_audio(void* data)
 
 	if (pa_context_connect(pa_ctx, NULL, PA_CONTEXT_NOFLAGS, NULL) < 0)
 	{
-		callback->debug("AUDIO: PULSE - unable to connect to server: pa_context_connect failed.");
+		audio_mgr->audiolog("AUDIO: PULSE - unable to connect to server: pa_context_connect failed.");
 		finish(pa_ctx, pa_ml);
 		return ((void*)-1);
 	}
@@ -1350,11 +1147,11 @@ void* pulse_read_audio(void* data)
 	/* set the sample spec (frame rate, channels and format) */
 	ss.rate = audio_ctx->samprate;
 	ss.channels = audio_ctx->channels;
-	ss.format = audio_ctx->eformat/*PA_SAMPLE_FLOAT32LE*/; /*for PCM -> PA_SAMPLE_S16LE*/
+	ss.format = audio_ctx->eformat;
 
 	recordstream = pa_stream_new(pa_ctx, "Record", &ss, NULL);
 	if (!recordstream)
-		callback->debug("AUDIO: (pulse audio) pa_stream_new failed (chan:%d rate:%d)",
+		audio_mgr->audiolog("AUDIO: (pulse audio) pa_stream_new failed (chan:%d rate:%d)",
 			ss.channels, ss.rate);
 
 	/* define the callbacks */
@@ -1373,7 +1170,7 @@ void* pulse_read_audio(void* data)
 		if (uvsersion >= RVC_PA_ADJUST_LATENCY_PROTOCOL_VERSION) {
 			pastream_flag |= PA_STREAM_ADJUST_LATENCY;
 		}
-		callback->debug("pa protocol version is %d.", uvsersion);
+		audio_mgr->audiolog("pa protocol version is %d.", uvsersion);
 	}
 	else {
 		bufattr.fragsize = bufattr.tlength = (uint32_t)-1;
@@ -1383,11 +1180,11 @@ void* pulse_read_audio(void* data)
 	pastream_flag |= PA_STREAM_AUTO_TIMING_UPDATE;
 
 	char* dev = audio_ctx->list_input_devices[audio_ctx->device].name;
-	callback->debug("AUDIO: (pulse audio) connecting to device %s (channels %d rate %d)", dev, ss.channels, ss.rate);
+	audio_mgr->audiolog("AUDIO: (pulse audio) connecting to device %s (channels %d rate %d)", dev, ss.channels, ss.rate);
 	r = pa_stream_connect_record(recordstream, dev, &bufattr, (pa_stream_flags_t)pastream_flag);
 	if (r < 0)
 	{
-		callback->debug("AUDIO: (pulse audio) skip latency adjustment");
+		audio_mgr->audiolog("AUDIO: (pulse audio) skip latency adjustment");
 		/*
 		 * Old pulse audio servers don't like the ADJUST_LATENCY flag,
 		 * so retry without that
@@ -1397,12 +1194,12 @@ void* pulse_read_audio(void* data)
 			(int32_t)PA_STREAM_AUTO_TIMING_UPDATE));
 	}
 	else {
-		callback->debug("pa_stream_connect_record success!");
+		audio_mgr->audiolog("pa_stream_connect_record success!");
 	}
 
 	if (r < 0)
 	{
-		callback->debug("AUDIO: (pulse audio) pa_stream_connect_record failed");
+		audio_mgr->audiolog("AUDIO: (pulse audio) pa_stream_connect_record failed");
 		finish(pa_ctx, pa_ml);
 		return ((void*)-1);
 	}
@@ -1419,7 +1216,7 @@ void* pulse_read_audio(void* data)
 		pa_mainloop_iterate(pa_ml, 1, NULL);
 	}
 	pa_stream_set_read_callback(recordstream, NULL, NULL);
-	callback->debug("AUDIO: (pulse audio) stream terminated(%i)", audio_ctx->stream_flag);
+	audio_mgr->audiolog("AUDIO: (pulse audio) stream terminated(%i)", audio_ctx->stream_flag);
 
 	pa_stream_disconnect(recordstream);
 	pa_stream_unref(recordstream);
@@ -1515,9 +1312,9 @@ rvc_audio_context_t* AudioMgrImpl::audio_get_context()
 	return m_audio_context;
 }
 
-IAudioMgrCallback* AudioMgrImpl::audio_get_callback()
+audiomgr_callback_t* AudioMgrImpl::audio_get_callback()
 {
-	return m_callback;
+	return &m_callback;
 }
 
 
@@ -1527,20 +1324,28 @@ int AudioMgrImpl::start_audio_capture()
 	assert(m_audio_context != NULL);
 
 	m_audio_context->stream_flag = AUDIO_STRM_ON;
-	//printf("%s:%d stream_flag = %d, audio context is 0x%08x.\n",__FUNCTION__, __LINE__, m_audio_context->stream_flag, m_audio_context);
 	/* start audio capture thread */
 	if (__THREAD_CREATE(&m_readthread, pulse_read_audio, this)){
-        if (m_callback)
-            m_callback->debug("AUDIO: (pulse audio) read thread creation failed");
+		audiolog("AUDIO: (pulse audio) read thread creation failed");
 		m_audio_context->stream_flag = AUDIO_STRM_OFF;
 		return (-1);
 	}
 	else {
-        if (m_callback)
-            m_callback->debug("AUDIO: (pulse audio) read thread creation success, and thread id is %u.", m_readthread);
+		audiolog("AUDIO: (pulse audio) read thread creation success, and thread id is %u.", m_readthread);
 	}
 
 	return 0;
 }
 
+void AudioMgrImpl::audiolog(const char* fmt, ...)
+{
+	if (m_callback.debug) {
+		va_list arg;
+		va_start(arg, fmt);
+		if(*m_callback.debug){
+			(*m_callback.debug)(m_callback.user_data, fmt, arg);
+		}
+		va_end(arg);
+	}
+}
 

+ 6 - 6
Other/libaudiomgr/linux/libaudiomgr_linux.h

@@ -11,7 +11,6 @@
 
 #include "audiodevicepulse.h"
 
-
 #ifndef MAX_PATH_EX
 #define MAX_PATH_EX 512
 #endif
@@ -119,7 +118,7 @@ typedef struct  rvc_volume_set_s {
 class AudioMgrImpl : public IAudioMgr
 {
 public:
-	AudioMgrImpl(IAudioMgrCallback* pCallback);
+	AudioMgrImpl(audiomgr_callback_t* pCallback);
 	~AudioMgrImpl();
 
 	int audio_mgr_initialize();
@@ -129,7 +128,9 @@ public:
 	int audio_get_device_id(const char* pstrname, bool binput);
 
 	int audio_get_device_volume(int* ivolume, const char* pstrname, bool binput);
+	int audiopulse_get_device_volume(int* ivolume, const char* pstrname, bool binput);
 	int audio_set_device_volume(int ivolume, const char* pstrname, bool binput);
+	int audiopulse_set_device_volume(int ivolume, const char* pstrname, bool binput);
 
 	int set_audio_capture_params(audiocap_param_t* param);
 	int start_audio_capture();
@@ -137,8 +138,8 @@ public:
 	int audio_mgr_destroy();
 
 	rvc_audio_context_t* audio_get_context();
-	IAudioMgrCallback* audio_get_callback();
-
+	audiomgr_callback_t* audio_get_callback();
+	void audiolog(const char* fmt, ...);
 
 private:
 	int audio_init_pulseaudio();
@@ -149,12 +150,11 @@ private:
 	int audio_set_pulseaudio_device(int index);
 	int audio_set_pulsecap_params(audiocap_param_t* param);
 	void audio_set_latency(double latency);
-
 	//int32_t InitPulseAudio();
 
 private:
 	rvc_audio_context_t* m_audio_context;
-	IAudioMgrCallback* m_callback;
+	audiomgr_callback_t m_callback;
 	__THREAD_TYPE m_readthread;
 
 	//AudioDevicePulse* m_audio_pulse;

+ 8 - 10
Other/libaudions/CMakeLists.txt

@@ -2,11 +2,9 @@ set(MODULE_NAME "libaudions")
 set(MODULE_PREFIX "IAUDIONSINTERFACE_FUNC")
 
 if(RVC_DEBUG_MODE)
-    set(SPBASE_LIB spbased)
-	set(RVCCOMM_LIB RVCCommD)
+	#set(RVCCOMM_LIB RVCCommD)
 else()
-    set(SPBASE_LIB spbase)
-	set(RVCCOMM_LIB RVCComm)
+	#set(RVCCOMM_LIB RVCComm)
 endif(RVC_DEBUG_MODE)
 
 set(${MODULE_PREFIX}_SRCS
@@ -52,20 +50,20 @@ add_library(${MODULE_NAME} SHARED ${${MODULE_PREFIX}_SRCS})
 
 
 target_include_directories(${MODULE_NAME} PRIVATE
-   "${CONAN_RVCFRAMEWORK_ROOT}/include"
-	${RVC_COMMON_INCLUDE_DIR}
+   #"${CONAN_RVCFRAMEWORK_ROOT}/include"
+	#${RVC_COMMON_INCLUDE_DIR}
 	webrtc_ns/include
 	)
 
 
 target_link_directories(${MODULE_NAME} PRIVATE
-	${CONAN_LIB_DIRS_RVCFRAMEWORK}
+	#${CONAN_LIB_DIRS_RVCFRAMEWORK}
 	)
 
 set(${MODULE_PREFIX}_LIBS PRIVATE
-	${SPBASE_LIB}
-	${TOOLKIT_LIB}
-	${RVCCOMM_LIB}
+	#${SPBASE_LIB}
+	#${TOOLKIT_LIB}
+	#${RVCCOMM_LIB}
 )
 
 target_compile_definitions(${MODULE_NAME} PUBLIC "IAUDIONSINTERFACE_API")

+ 2 - 2
Other/libaudions/iaudionsinterface.cpp

@@ -3,9 +3,9 @@
 #include "iaudionsinterface.h"
 #include "libaudions.h"
 
-IAUDIONSINTERFACE_API IAudioNs*  CreateIAudioNsObj()
+IAUDIONSINTERFACE_API IAudioNs*  CreateIAudioNsObj(audions_callback_t* pCallback)
 {
-	return new AudioNsImpl;
+	return new AudioNsImpl(pCallback);
 }
 
 IAUDIONSINTERFACE_API void DestroyIAudioNsObj(IAudioNs* pIAudioNs)

+ 13 - 3
Other/libaudions/iaudionsinterface.h

@@ -7,11 +7,21 @@
 #else
 #define IAUDIONSINTERFACE_API __declspec(dllimport)
 #endif
-#else
+# elif ( defined(__GNUC__) &&  __GNUC__ >= 4 )
+#define IAUDIONSINTERFACE_API __attribute__((visibility("default")))
+#else // RVC_OS_WIN
 #define IAUDIONSINTERFACE_API
-#endif
+#endif // RVC_OS_WIN
+
 
 #include <stdint.h>
+#include <stdarg.h>
+
+typedef struct audions_callback_s {
+	void (*debug)(void* user_data, const char* fmt, va_list arg);
+	void* user_data;
+}audions_callback_t;
+
 
 class IAudioNs
 {
@@ -21,7 +31,7 @@ public:
 	virtual void ReleaseObj() = 0;
 };
 
-extern "C" IAUDIONSINTERFACE_API IAudioNs* CreateIAudioNsObj();
+extern "C" IAUDIONSINTERFACE_API IAudioNs* CreateIAudioNsObj(audions_callback_t* pCallback);
 extern "C" IAUDIONSINTERFACE_API void DestroyIAudioNsObj(IAudioNs* pIAudioNs);
 
 #endif

+ 27 - 17
Other/libaudions/libaudions.cpp

@@ -2,8 +2,6 @@
 //
 
 //#include "stdafx.h"
-
-#include "SpBase.h"
 #include "libaudions.h"
 #include "signal_processing_library.h"
 
@@ -13,13 +11,14 @@
 #endif
 
 
-AudioNsImpl::AudioNsImpl()
+AudioNsImpl::AudioNsImpl(audions_callback_t* pCallback)
 {
-	Dbg("AudioNsImpl construction.");
-
+	memcpy(&m_nscallback, pCallback, sizeof(audions_callback_t));
+	NsLog("AudioNsImpl construction.");
+	
 	m_NsHandle = NULL;
 	if (0 == WebRtcNs_Create(&m_NsHandle)){
-		Dbg("AudioNsImpl success.");
+		NsLog("AudioNsImpl success.");
 	}
 	m_audio_sample_rate = 16000;
 	m_audio_capture_peroid = 20;
@@ -28,11 +27,11 @@ AudioNsImpl::AudioNsImpl()
 
 AudioNsImpl::~AudioNsImpl()
 {
-	Dbg("AudioNsImpl Deconstruction.");
+	NsLog("AudioNsImpl Deconstruction.");
 	if (NULL != m_NsHandle){
 		int iRet = WebRtcNs_Free(m_NsHandle);
 		if (0 == iRet){
-			Dbg("WebRtcNs Free success.");
+			NsLog("WebRtcNs Free success.");
 		}
 	}
 }
@@ -47,16 +46,16 @@ int AudioNsImpl::SetNsParams(uint32_t uSampleRate, uint32_t uAudioCapturePeroid,
 	if (0 == WebRtcNs_Init(m_NsHandle, uSampleRate)){
 		iRet = WebRtcNs_set_policy(m_NsHandle, iMode);
 		if (0 == iRet){
-			Dbg("WebRtcNs init and set policy success.");
+			NsLog("WebRtcNs init and set policy success.");
 		}
 		else{
-			Dbg("WebRtcNs set policy failed.");
+			NsLog("WebRtcNs set policy failed.");
 		}
 	}
 	else{
-		Dbg("WebRtcNs Init failed.");
+		NsLog("WebRtcNs Init failed.");
 	}
-	Dbg("audio sample rate is %d, audio frame time is %dms, noise suppression policy is %d.",m_audio_sample_rate, m_audio_capture_peroid, m_ns_policy);
+	NsLog("audio sample rate is %d, audio frame time is %dms, noise suppression policy is %d.",m_audio_sample_rate, m_audio_capture_peroid, m_ns_policy);
 
 	return iRet;
 }
@@ -77,7 +76,7 @@ int AudioNsImpl::NsProcess(char* pDst, uint32_t uDstLen, char* pSrc, uint32_t uS
 		iRet = NsProcess32kAudioSampleRate(pDst, uDstLen, pSrc, uSrcLen);
 		break;
 	default:
-		Dbg("Rvc_NsProcess not support audio sample rate.");
+		NsLog("Rvc_NsProcess not support audio sample rate.");
 		break;
 	}
 
@@ -98,7 +97,7 @@ int AudioNsImpl::NsProcess8kAudioSampleRate(char* pDst, uint32_t uDstLen, char*
 			short shBufferOut[80] = {0};
 			memcpy(shBufferIn, (char*)pSrc+i*80*sizeof(short), sizeof(short)*80);
 			if (iRet = WebRtcNs_Process(m_NsHandle ,shBufferIn  ,NULL ,shBufferOut , NULL)){
-				Dbg("Noise_Suppression WebRtcNs_Process 8k input err!");
+				NsLog("Noise_Suppression WebRtcNs_Process 8k input err!");
 			}
 			else{
 				memcpy((char*)pDst+i*80*sizeof(short),shBufferOut,80*sizeof(short));
@@ -126,7 +125,7 @@ int AudioNsImpl::NsProcess16kAudioSampleRate(char* pDst, uint32_t uDstLen, char*
 			short shBufferOut[160] = {0};
 			memcpy(shBufferIn, (char*)pSrc+i*160*sizeof(short), sizeof(short)*160);
 			if (iRet = WebRtcNs_Process(m_NsHandle ,shBufferIn  ,NULL ,shBufferOut , NULL)){
-				Dbg("Noise_Suppression WebRtcNs_Process 16k input err!");
+				NsLog("Noise_Suppression WebRtcNs_Process 16k input err!");
 			}
 			else{
 				memcpy((char*)pDst+i*160*sizeof(short),shBufferOut,160*sizeof(short));
@@ -162,7 +161,7 @@ int AudioNsImpl::NsProcess32kAudioSampleRate(char* pDst, uint32_t uDstLen, char*
 
 			//将需要降噪的数据以高频和低频传入对应接口,同时需要注意返回数据也是分高频和低频
 			if (iRet == WebRtcNs_Process(m_NsHandle, shInL, shInH, shOutL, shOutH)){
-				Dbg("Noise_Suppression WebRtcNs_Process 32k input err!");
+				NsLog("Noise_Suppression WebRtcNs_Process 32k input err!");
 			}
 			else
 			{
@@ -177,8 +176,19 @@ int AudioNsImpl::NsProcess32kAudioSampleRate(char* pDst, uint32_t uDstLen, char*
 	return iRet;
 }
 
+
+void AudioNsImpl::NsLog(const char* fmt, ...)
+{
+	if (m_nscallback.debug){
+		va_list arg;
+		va_start(arg, fmt);
+		(*m_nscallback.debug)(m_nscallback.user_data, fmt, arg);
+		va_end(arg);
+	}
+}
+
 void AudioNsImpl::ReleaseObj()
 {
-	Dbg("AudioNsImpl ReleaseObj.");
+	NsLog("AudioNsImpl ReleaseObj.");
 	delete this;
 }

+ 3 - 1
Other/libaudions/libaudions.h

@@ -10,7 +10,7 @@
 class AudioNsImpl : public IAudioNs
 {
 public:
-	AudioNsImpl();
+	AudioNsImpl(audions_callback_t* pCallback);
 	~AudioNsImpl();
 
 	virtual int SetNsParams(uint32_t uSampleRate, uint32_t uAudioCapturePeroid, int iMode);
@@ -21,12 +21,14 @@ private:
 	int NsProcess8kAudioSampleRate(char* pDst, uint32_t uDstLen, char* pSrc, uint32_t uSrcLen);
 	int NsProcess16kAudioSampleRate(char* pDst, uint32_t uDstLen, char* pSrc, uint32_t uSrcLen);
 	int NsProcess32kAudioSampleRate(char* pDst, uint32_t uDstLen, char* pSrc, uint32_t uSrcLen);
+	void NsLog(const char* fmt, ...);
 
 private:
 	NsHandle *m_NsHandle;
 	uint32_t m_audio_sample_rate;				//单位HZ
 	uint32_t m_audio_capture_peroid;			//单位ms
 	int m_ns_policy;	
+	audions_callback_t m_nscallback;
 };
 
 

+ 1 - 1
Other/libvideocapture/ivideocaptureinterface.cpp

@@ -2,7 +2,7 @@
 #include "./linux/videocapture_linux.h"
 
 
-IVideoCapture* CreateVideoCaptureObj(ICaptureCallback* pCallback)
+IVideoCapture* CreateVideoCaptureObj(videocap_callback_t* pCallback)
 {
 	return new VideoCaptureImpl(pCallback);
 }

+ 9 - 8
Other/libvideocapture/ivideocaptureinterface.h

@@ -12,6 +12,7 @@
 #define LIBVIDEOCAPTURE_API
 #endif // RVC_OS_WIN
 
+#include <stdarg.h>
 
 /**
  * video capture header file
@@ -121,12 +122,13 @@ typedef struct videocap_param_s
 }videocap_param_t;
 
 
-struct ICaptureCallback
-{
-	virtual void Debug(const char* fmt, ...) = 0;
-	virtual void OnCaptureFailed() = 0;
-	virtual void OnVideoCaptureExcption() = 0;
-};
+typedef struct videocap_callback_s {
+	void (*debug)(void* user_data, const char* fmt, va_list arg);
+	void (*oncapturefailed)();
+	void (*onvideocapexcption)();
+	void* user_data;
+}videocap_callback_t;
+
 
 class IVideoCapture 
 {
@@ -138,10 +140,9 @@ public:
 	virtual int GetCamBrightness(int* ibright) = 0;
 	virtual int SetCamBrightness(int ibright) = 0;
 	virtual int SetCamAutoBrightness() = 0;
-
 };
 
 
-extern "C" LIBVIDEOCAPTURE_API IVideoCapture* CreateVideoCaptureObj(ICaptureCallback* pCallback);
+extern "C" LIBVIDEOCAPTURE_API IVideoCapture* CreateVideoCaptureObj(videocap_callback_t* pCallback);
 extern "C" LIBVIDEOCAPTURE_API void DestroyVideoCaptureObj(IVideoCapture* pIVideoCapture);
 

+ 134 - 204
Other/libvideocapture/linux/videocapture_linux.cpp

@@ -47,19 +47,22 @@ int GetFourccName(char* strbuf, uint32_t ulen, uint32_t fourcc)
 	return iret;
 }
 
-VideoCaptureImpl::VideoCaptureImpl(ICaptureCallback* pCallback)
+VideoCaptureImpl::VideoCaptureImpl(videocap_callback_t* pCallback)
 {
-	m_callback = pCallback;
+	memcpy(&m_callback, pCallback, sizeof(videocap_callback_t));
 	m_capture = NULL;
 	m_bCaptureStarted = false;
 
 	m_deviceId = -1;
 	m_deviceFd = -1;
 
-	m_capture_width = 0;
-	m_capture_height = 0;
-	m_dest_cap_width = 0;
-	m_dest_cap_height = 0;
+	m_in_cap_width = 0;
+	m_in_cap_height = 0;
+	m_real_cap_width = 0;
+	m_real_cap_height = 0;
+	m_out_cap_width = 0;
+	m_out_cap_height = 0;
+
 	m_rotate = libyuv::kRotate0;
 	m_frame_fmt = VIDEO_FORMAT_I420;
 	m_captureVideoType = VideoType::kI420;
@@ -137,14 +140,10 @@ int VideoCaptureImpl::VideoCaptureSetParam(videocap_param_t* param)
 		}
 	}
 	else {
-		if (m_callback) {
-			m_callback->Debug("%s", "param->option & VIDEOCAP_OPT_EANBLE_RESIZE success.");
-		}
+			CapLog("%s", "param->option & VIDEOCAP_OPT_EANBLE_RESIZE success.");
 	}
 
-	if (m_callback){
-		m_callback->Debug("%s:%d param->option = %d.", __FUNCTION__, __LINE__, param->option);
-	}
+	CapLog("%s:%d param->option = %d.", __FUNCTION__, __LINE__, param->option);
 	
 	m_capture = (videocap_t*)malloc(sizeof(videocap_t));
 	if (!m_capture) {
@@ -157,9 +156,8 @@ int VideoCaptureImpl::VideoCaptureSetParam(videocap_param_t* param)
 	if (param->option & VIDEOCAP_OPT_ENABLE_GRAB) {
 		int width = mode_width[param->cap_mode];
 		int height = mode_height[param->cap_mode];
-		if (m_callback){
-			m_callback->Debug("%s:%d, width = %d, height = %d.", __FUNCTION__, __LINE__, width, height);
-		}
+
+		CapLog("%s:%d, width = %d, height = %d.", __FUNCTION__, __LINE__, width, height);
 		
 		if (video_frame_alloc(width, height, param->frame_fmt, &m_capture->cap_frame) != 0) {
 			free(m_capture);
@@ -168,10 +166,9 @@ int VideoCaptureImpl::VideoCaptureSetParam(videocap_param_t* param)
 		video_frame_fill_black(&m_capture->cap_frame);
 	}
 	else{
-		if (m_callback){
-			m_callback->Debug("param->option & VIDEOCAP_OPT_ENABLE_GRAB is false");
-		}
+		CapLog("param->option & VIDEOCAP_OPT_ENABLE_GRAB is false");
 	}
+
 	if (param->option & VIDEOCAP_OPT_ENABLE_ASYNC_GRAB) {
 
 	}
@@ -179,9 +176,8 @@ int VideoCaptureImpl::VideoCaptureSetParam(videocap_param_t* param)
 	if (param->option & VIDEOCAP_OPT_EANBLE_RESIZE) {
 		int width = mode_width[param->res_mode];
 		int height = mode_height[param->res_mode];
-		if (m_callback){
-			m_callback->Debug("%s:%d, width = %d, height = %d.", __FUNCTION__, __LINE__, width, height);
-		}
+		
+		CapLog("%s:%d, width = %d, height = %d.", __FUNCTION__, __LINE__, width, height);
 		
 		if (video_frame_alloc(width, height, param->frame_fmt, &m_capture->res_frame) != 0) {
 			if (param->option & VIDEOCAP_OPT_ENABLE_GRAB) {
@@ -211,18 +207,17 @@ int VideoCaptureImpl::VideoCaptureSetParam(videocap_param_t* param)
 			return -1;
 		}
 	}
-	if (m_callback) {
-		m_callback->Debug("%s:%d, param->irotate %d.", __FUNCTION__, __LINE__, param->irotate);
-	}
+
+	CapLog("%s:%d, param->irotate %d.", __FUNCTION__, __LINE__, param->irotate);
 	
 	m_rotate = RotateTrans(param->irotate);
 
-	m_dest_cap_width = mode_width[m_capture->param.cap_mode];
-	m_dest_cap_height = mode_height[m_capture->param.cap_mode];
+	m_in_cap_width = m_out_cap_width = mode_width[m_capture->param.cap_mode];
+	m_in_cap_height = m_out_cap_height = mode_height[m_capture->param.cap_mode];
 
 	if (libyuv::kRotate90 == m_rotate || libyuv::kRotate270 == m_rotate){
-		m_dest_cap_width = mode_height[m_capture->param.cap_mode];
-		m_dest_cap_height = mode_width[m_capture->param.cap_mode];
+		m_out_cap_width = mode_height[m_capture->param.cap_mode];
+		m_out_cap_height = mode_width[m_capture->param.cap_mode];
 	}
 	
 	return 0;
@@ -344,25 +339,20 @@ int32_t VideoCaptureImpl::IncomingFrame(uint8_t* videoFrame,
 	const int32_t height = frameInfo.height;
 
 	if (0 == m_ilogcount){
-		if (m_callback){
-			m_callback->Debug("IncomingFrame capture_time is %d, videoType=%d, rotate=%d, videoFrameLength=%d, width=%d, height=%d, and destination width=%d, height=%d.", captureTime, frameInfo.videoType, m_rotate, videoFrameLength, width, height, m_dest_cap_width, m_dest_cap_height);
-		}
+		CapLog("IncomingFrame capture_time is %d, videoType=%d, rotate=%d, videoFrameLength=%d, width=%d, height=%d, and destination width=%d, height=%d.", captureTime, frameInfo.videoType, m_rotate, videoFrameLength, width, height, m_out_cap_width, m_out_cap_height);
 		m_ilogcount++;
 	}
 	
 	// Not encoded, convert to I420.
 	if (frameInfo.videoType != VideoType::kMJPEG &&
 		CalcBufferSize(frameInfo.videoType, width, abs(height)) != videoFrameLength) {
-		if (m_callback) {
-			m_callback->Debug("Wrong incoming frame length.");
-		}
-
+		CapLog("Wrong incoming frame length.");
 		return -1;
 	}
 
-	int stride_y = width;
-	int stride_u = (width + 1)/2;
-	int stride_v = (width + 1)/2;
+	int stride_y = m_in_cap_width;
+	int stride_u = (m_in_cap_width + 1)/2;
+	int stride_v = (m_in_cap_width + 1)/2;
 
 	//uint8_t* i420y = (uint8_t*)AlignedMalloc(I420DataSize(height, stride_y, stride_u, stride_v), kBufferAlignment);
 	//uint8_t* brg24 = (uint8_t*)AlignedMalloc(RGB24DataSize(m_dest_cap_height, m_dest_cap_width, (m_dest_cap_width+1)/2, (m_dest_cap_width + 1) / 2), kBufferAlignment);
@@ -370,56 +360,52 @@ int32_t VideoCaptureImpl::IncomingFrame(uint8_t* videoFrame,
 	int conversionResult = libyuv::ConvertToI420(videoFrame, videoFrameLength,
 		m_i420,
 		stride_y,
-		m_i420 + stride_y * height,
+		m_i420 + stride_y * m_in_cap_height,
 		stride_u,
-		m_i420 + stride_y * height + stride_u * ((height + 1) / 2),
+		m_i420 + stride_y * m_in_cap_height + stride_u * ((m_in_cap_height + 1) / 2),
 		stride_v,
 		0, 
-		0,  // No Cropping
+		(height - m_in_cap_height) / 2,  // No Cropping
 		width, 
 		height,
 		width,
-		height,
+		m_in_cap_height,
 		libyuv::kRotate180,
 		ConvertVideoType(frameInfo.videoType)
 	);
 
 	if (conversionResult < 0) {
-		if (m_callback){
-			m_callback->Debug("Failed to convert capture frame from type %d to I420 for %s.", static_cast<int>(frameInfo.videoType), strerror(errno));
-		}
+		CapLog("Failed to convert capture frame from type %d to I420 for %s.", static_cast<int>(frameInfo.videoType), strerror(errno));
 		return -1;
 	}
 
 	//{
 	//	video_frame frmi420 = { 0 };
 	//	frmi420.data[0] = m_i420;
-	//	frmi420.linesize[0] = m_dest_cap_width * 3 / 2;
-	//	frmi420.width = m_dest_cap_width;
-	//	frmi420.height = m_dest_cap_height;
+	//	frmi420.linesize[0] = m_in_cap_height * 3 / 2;
+	//	frmi420.width = m_in_cap_width;
+	//	frmi420.height = m_in_cap_height;
 	//	frmi420.format = VIDEO_FORMAT_I420;
 	//	//m_capture->param.on_frame_i420(m_capture->param.user_data, &frmi420);
 	//	char stroptname[260] = { 0 };
-	//	snprintf(stroptname, 260, "%d_%d_%d_%d_i420.bmp", m_ilogcount, (int)m_rotate, m_dest_cap_width, m_dest_cap_height);
+	//	snprintf(stroptname, 260, "%d_%d_%d_%d_i420.bmp", m_ilogcount, (int)m_rotate, m_in_cap_width, m_in_cap_height);
 	//	video_frame_save_bmpfile(stroptname, &frmi420);
 	//}
 
 	if (libyuv::kRotate0 == m_rotate || libyuv::kRotate180 == m_rotate){
 		conversionResult = libyuv::ConvertFromI420(m_i420,
 					stride_y,
-					m_i420 + stride_y * m_capture_height,
+					m_i420 + stride_y * m_in_cap_height,
 					stride_u,
-					m_i420 + stride_y * m_capture_height + stride_u * ((m_capture_height + 1) / 2),
+					m_i420 + stride_y * m_in_cap_height + stride_u * ((m_in_cap_height + 1) / 2),
 					stride_v,
 					m_rgb24,
-					m_dest_cap_width * 3,
-					m_dest_cap_width,
-					m_dest_cap_height,
+					m_out_cap_width * 3,
+					m_out_cap_width,
+					m_out_cap_height,
 					ConvertVideoType(kRGB24));
 		if (conversionResult < 0) {
-			if (m_callback) {
-				m_callback->Debug("Failed to convert capture frame from I420 to RGB24 for %s.", strerror(errno));
-			}
+			CapLog("Failed to convert capture frame from I420 to RGB24 for %s.", strerror(errno));
 			return -1;
 		}
 	}
@@ -429,63 +415,59 @@ int32_t VideoCaptureImpl::IncomingFrame(uint8_t* videoFrame,
 			if (libyuv::kRotate90 == m_rotate) {
 				erotate = libyuv::kRotate270;
 			}
-			int opt_stride_y = m_dest_cap_width;
-			int opt_stride_u = (m_dest_cap_width + 1) / 2;
-			int opt_stride_v = (m_dest_cap_width + 1) / 2;
+			int opt_stride_y = m_out_cap_width;
+			int opt_stride_u = (m_out_cap_width + 1) / 2;
+			int opt_stride_v = (m_out_cap_width + 1) / 2;
 			//uint8_t* iopt420 = (uint8_t*)AlignedMalloc(I420DataSize(m_dest_cap_height, opt_stride_y, opt_stride_u, opt_stride_v), kBufferAlignment);
 			int rotateResult = libyuv::I420Rotate(m_i420,
 				stride_y,
-				m_i420 + stride_y * height,
+				m_i420 + stride_y * m_in_cap_height,
 				stride_u,
-				m_i420 + stride_y * height + stride_u * ((height + 1) / 2),
+				m_i420 + stride_y * m_in_cap_height + stride_u * ((m_in_cap_height + 1) / 2),
 				stride_v,
 				m_opti420,
 				opt_stride_y,
-				m_opti420 + opt_stride_y * m_dest_cap_height,
+				m_opti420 + opt_stride_y * m_out_cap_height,
 				opt_stride_u,
-				m_opti420 + opt_stride_y * m_dest_cap_height + opt_stride_u * ((m_dest_cap_height + 1) / 2),
+				m_opti420 + opt_stride_y * m_out_cap_height + opt_stride_u * ((m_out_cap_height + 1) / 2),
 				opt_stride_v,
-				width,
-				height,
+				m_in_cap_width,
+				m_in_cap_height,
 				erotate);
 
 			if (rotateResult < 0) {
-				if (m_callback) {
-					m_callback->Debug("Failed to Rotate Frame %d for %s.", (int)erotate, strerror(errno));
-				}
+				CapLog("Failed to Rotate Frame %d for %s.", (int)erotate, strerror(errno));
 				return -1;
 			}
 
 			//{
 			//	video_frame frmi420 = { 0 };
 			//	frmi420.data[0] = m_opti420;
-			//	frmi420.linesize[0] = m_dest_cap_width * 3 / 2;
-			//	frmi420.width = m_dest_cap_width;
-			//	frmi420.height = m_dest_cap_height;
+			//	frmi420.linesize[0] = m_out_cap_width * 3 / 2;
+			//	frmi420.width = m_out_cap_width;
+			//	frmi420.height = m_out_cap_height;
 			//	frmi420.format = VIDEO_FORMAT_I420;
 			//	//m_capture->param.on_frame_i420(m_capture->param.user_data, &frmi420);
 			//	char stroptname[260] = { 0 };
-			//	snprintf(stroptname, 260, "%d_%d_%d_%d_i420.bmp", m_ilogcount, (int)m_rotate, m_dest_cap_width, m_dest_cap_height);
+			//	snprintf(stroptname, 260, "%d_%d_%d_%d_i420.bmp", m_ilogcount, (int)m_rotate, m_out_cap_width, m_out_cap_height);
 			//	video_frame_save_bmpfile(stroptname, &frmi420);
 			//}
 			//yu12_to_dib24(brg24, iopt420, m_dest_cap_width, m_dest_cap_height);
 
 			conversionResult = libyuv::ConvertFromI420(m_opti420,
 				opt_stride_y,
-				m_opti420 + opt_stride_y * m_dest_cap_height,
+				m_opti420 + opt_stride_y * m_out_cap_height,
 				opt_stride_u,
-				m_opti420 + opt_stride_y * m_dest_cap_height + opt_stride_u * ((m_dest_cap_height + 1) / 2),
+				m_opti420 + opt_stride_y * m_out_cap_height + opt_stride_u * ((m_out_cap_height + 1) / 2),
 				opt_stride_v,
 				m_rgb24,
-				m_dest_cap_width * 3,
-				m_dest_cap_width,
-				m_dest_cap_height,
+				m_out_cap_width * 3,
+				m_out_cap_width,
+				m_out_cap_height,
 				ConvertVideoType(kRGB24));
 				
 			if (conversionResult < 0) {
-				if (m_callback) {
-					m_callback->Debug("Failed to convert capture frame from I420 to RGB24 for %s.", strerror(errno));
-				}
+				CapLog("Failed to convert capture frame from I420 to RGB24 for %s.", strerror(errno));
 				return -1;
 			}
 			//AlignedFree(iopt420);
@@ -496,14 +478,14 @@ int32_t VideoCaptureImpl::IncomingFrame(uint8_t* videoFrame,
 	if (NULL != m_capture->param.on_frame) {
 		video_frame frm = { 0 };
 		frm.data[0] = m_rgb24;
-		frm.linesize[0] = m_dest_cap_width * 3;
-		frm.width = m_dest_cap_width;
-		frm.height = m_dest_cap_height;
+		frm.linesize[0] = m_out_cap_width * 3;
+		frm.width = m_out_cap_width;
+		frm.height = m_out_cap_height;
 		frm.format = VIDEO_FORMAT_RGB24;
 
 		m_capture->param.on_frame(m_capture->param.user_data, &frm);
 		//char strrgbname[260] = { 0 };
-		//snprintf(strrgbname, 260, "%d_%d_%d_%d_rgb.bmp", m_ilogcount, (int)m_rotate, m_dest_cap_width, m_dest_cap_height);
+		//snprintf(strrgbname, 260, "%d_%d_%d_%d_rgb.bmp", m_ilogcount, (int)m_rotate, m_out_cap_width, m_out_cap_height);
 		//video_frame_save_bmpfile(strrgbname, &frm);
 		//m_ilogcount++;
 	}
@@ -528,7 +510,6 @@ static void* VideoCaptureProcess(void *arg)
 	VideoCaptureImpl* pVideoCapture = (VideoCaptureImpl*)arg;
 	int iDeviceFd = pVideoCapture->GetCaptureVideoFd();
 
-	ICaptureCallback* pcallback = pVideoCapture->GetCaptureCallback();
 	while (false == pVideoCapture->GetStopCaptureFlag())
 	{
 		FD_ZERO(&rSet);
@@ -540,24 +521,24 @@ static void* VideoCaptureProcess(void *arg)
 		if (retVal < 0 && errno != EINTR)  // continue if interrupted
 		{
 			// select failed
-			if (pcallback){
-				pcallback->Debug("exit for select failed.");
+			if (pVideoCapture){
+				pVideoCapture->CapLog("exit for select failed.");
 			}
 			
 			return NULL;
 		}
 		else if (retVal == 0) {
 			// select timed out
-			if (pcallback){
-				pcallback->Debug("exit for select timed out.");
+			if (pVideoCapture){
+				pVideoCapture->CapLog("exit for select timed out.");
 			}
 			
 			return NULL;
 		}
 		else if (!FD_ISSET(iDeviceFd, &rSet)) {
 			// not event on camera handle
-			if (pcallback){
-				pcallback->Debug("exit for not event on camera handle.");
+			if (pVideoCapture){
+				pVideoCapture->CapLog("exit for not event on camera handle.");
 			}
 			
 			return NULL;
@@ -571,8 +552,8 @@ static void* VideoCaptureProcess(void *arg)
 			// dequeue a buffer - repeat until dequeued properly!
 			while (ioctl(iDeviceFd, VIDIOC_DQBUF, &buf) < 0) {
 				if (errno != EINTR) {
-					if (pcallback){
-						pcallback->Debug("could not sync on a buffer on device %s.", strerror(errno));
+					if (pVideoCapture){
+						pVideoCapture->CapLog("could not sync on a buffer on device %s.", strerror(errno));
 					}
 					return NULL;
 				}
@@ -588,8 +569,8 @@ static void* VideoCaptureProcess(void *arg)
 			pVideoCapture->IncomingFrame((unsigned char*)buffer_pool[buf.index].start, buf.length, frameInfo);
 			// enqueue the buffer again
 			if (ioctl(iDeviceFd, VIDIOC_QBUF, &buf) == -1) {
-				if (pcallback){
-					pcallback->Debug("Failed to enqueue capture buffer");
+				if (pVideoCapture){
+					pVideoCapture->CapLog("Failed to enqueue capture buffer");
 				}
 			}
 		}
@@ -604,8 +585,8 @@ static void* VideoCaptureProcess(void *arg)
 int VideoCaptureImpl::StartVideoCapture()
 {	
 	if (m_bCaptureStarted){
-		if (m_capture_width == mode_width[m_capture->param.cap_mode] &&
-			m_capture_height == mode_height[m_capture->param.cap_mode] &&
+		if (m_real_cap_width == mode_width[m_capture->param.cap_mode] &&
+			m_real_cap_height == mode_height[m_capture->param.cap_mode] &&
 			m_frame_fmt == m_capture->param.frame_fmt){
 			return 0;
 		}
@@ -617,9 +598,7 @@ int VideoCaptureImpl::StartVideoCapture()
 	char device[20] = {0};
 	snprintf(device, 20,"/dev/video%d", (int)m_deviceId);
 	if ((m_deviceFd = open(device, O_RDWR | O_NONBLOCK, 0)) < 0) {
-		if (m_callback){
-			m_callback->Debug("error in opening %s for %s.", device, strerror(errno));
-		}
+		CapLog("error in opening %s for %s.", device, strerror(errno));
 		return -1;
 	}
 
@@ -649,15 +628,12 @@ int VideoCaptureImpl::StartVideoCapture()
 	memset(&fmt, 0, sizeof(fmt));
 	fmt.index = 0;
 	fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	if (m_callback){
-		m_callback->Debug("Video Capture enumerates supported image formats:");
-	}
+	CapLog("Video Capture enumerates supported image formats:");
+	
 	while (ioctl(m_deviceFd, VIDIOC_ENUM_FMT, &fmt) == 0) {
 		char strformat[32] = { 0 };
 		GetFourccName(strformat, 32, fmt.pixelformat);
-		if (m_callback) {
-			m_callback->Debug("pixelformat=%s, description='%s'", strformat, fmt.description);
-		}
+		CapLog("pixelformat=%s, description='%s'", strformat, fmt.description);
 		// Match the preferred order.
 		for (int i = 0; i < nFormats; i++) {
 			if (fmt.pixelformat == fmts[i] && i < fmtsIdx)
@@ -668,18 +644,14 @@ int VideoCaptureImpl::StartVideoCapture()
 	}
 
 	if (fmtsIdx == nFormats) {
-		if (m_callback) {
-			m_callback->Debug("no supporting video formats found");
-		}
+		CapLog("no supporting video formats found");
 		close(m_deviceFd);
 		return -1;
 	}
 	else {
 		char strformat[32] = { 0 };
 		GetFourccName(strformat, 32, fmts[fmtsIdx]);
-		if (m_callback){
-			m_callback->Debug("we prefer format %s.", strformat);
-		}
+		CapLog("we prefer format %s.", strformat);
 	}
 
 	struct v4l2_format video_fmt;
@@ -689,11 +661,8 @@ int VideoCaptureImpl::StartVideoCapture()
 	video_fmt.fmt.pix.width = mode_width[m_capture->param.cap_mode];
 	video_fmt.fmt.pix.height = mode_height[m_capture->param.cap_mode];
 	video_fmt.fmt.pix.pixelformat = fmts[fmtsIdx];
-
-	if (m_callback){
-		m_callback->Debug("video_fmt.fmt.pix.width = %d, video_fmt.fmt.pix.height = %d.", video_fmt.fmt.pix.width, video_fmt.fmt.pix.height);
-	}
-
+	CapLog("video_fmt.fmt.pix.width = %d, video_fmt.fmt.pix.height = %d.", video_fmt.fmt.pix.width, video_fmt.fmt.pix.height);
+	
 	if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
 		m_captureVideoType = VideoType::kYUY2;
 	else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420)
@@ -706,29 +675,23 @@ int VideoCaptureImpl::StartVideoCapture()
 
 	// set format and frame size now
 	if (ioctl(m_deviceFd, VIDIOC_S_FMT, &video_fmt) < 0) {
-		if (m_callback){
-			m_callback->Debug("error in VIDIOC_S_FMT for %s.", strerror(errno));
-		}
+		CapLog("error in VIDIOC_S_FMT for %s.", strerror(errno));
 		close(m_deviceFd);
 		return -1;
 	}
 	else
 	{
 		if (ioctl(m_deviceFd, VIDIOC_G_FMT, &video_fmt) < 0){
-			if (m_callback){
-				m_callback->Debug("error in VIDIOC_G_FMT for %s.", strerror(errno));
-			}
+			CapLog("error in VIDIOC_G_FMT for %s.", strerror(errno));
 			close(m_deviceFd);
 			return -1;
 		}
 		else
 		{
 			// initialize current width and height
-			m_capture_width = video_fmt.fmt.pix.width;
-			m_capture_height = video_fmt.fmt.pix.height;
-			if (m_callback){
-				m_callback->Debug("real camera capture m_capture_width = %d, m_capture_height = %d.", m_capture_width, m_capture_height);
-			}
+			m_real_cap_width = video_fmt.fmt.pix.width;
+			m_real_cap_height = video_fmt.fmt.pix.height;
+			CapLog("real camera capture m_capture_width = %d, m_capture_height = %d.", m_real_cap_width, m_real_cap_height);
 		}
 	}
 
@@ -738,9 +701,7 @@ int VideoCaptureImpl::StartVideoCapture()
 	memset(&streamparms, 0, sizeof(streamparms));
 	streamparms.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 	if (ioctl(m_deviceFd, VIDIOC_G_PARM, &streamparms) < 0) {
-		if (m_callback){
-			m_callback->Debug("error in VIDIOC_G_PARM,and error info is %s.", strerror(errno));
-		}
+		CapLog("error in VIDIOC_G_PARM,and error info is %s.", strerror(errno));
 		driver_framerate_support = false;
 		// continue
 	}
@@ -752,26 +713,18 @@ int VideoCaptureImpl::StartVideoCapture()
 			streamparms.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 			streamparms.parm.capture.timeperframe.numerator = 1;
 			streamparms.parm.capture.timeperframe.denominator = (int32_t)m_capture->param.fps;
-			if (m_callback){
-				m_callback->Debug("Set Camera video capture timeperframe numerator is %d, denominator is %d.", streamparms.parm.capture.timeperframe.numerator, streamparms.parm.capture.timeperframe.denominator);
-			}
+			CapLog("Set Camera video capture timeperframe numerator is %d, denominator is %d.", streamparms.parm.capture.timeperframe.numerator, streamparms.parm.capture.timeperframe.denominator);
 			
 			if (ioctl(m_deviceFd, VIDIOC_S_PARM, &streamparms) < 0) {
-				if (m_callback){
-					m_callback->Debug("Failed to set the framerate. error info is %s.", strerror(errno));
-				}
+				CapLog("Failed to set the framerate. error info is %s.", strerror(errno));
 				driver_framerate_support = false;
 			}
 			else {
 				m_currentFrameRate = (int32_t)m_capture->param.fps;
-				if (m_callback){
-					m_callback->Debug("Set Camera video capture rate to %d, and numerator is %d, denominator is %d.", m_currentFrameRate, streamparms.parm.capture.timeperframe.numerator, streamparms.parm.capture.timeperframe.denominator);
-				}
+				CapLog("Set Camera video capture rate to %d, and numerator is %d, denominator is %d.", m_currentFrameRate, streamparms.parm.capture.timeperframe.numerator, streamparms.parm.capture.timeperframe.denominator);
 				
-				if (ioctl(m_deviceFd, VIDIOC_G_PARM, &streamparms) == 0) {
-					if (m_callback){
-						m_callback->Debug("Get video capture numerator is %d, denominator is %d.", streamparms.parm.capture.timeperframe.numerator, streamparms.parm.capture.timeperframe.denominator);
-					}
+				if (ioctl(m_deviceFd, VIDIOC_G_PARM, &streamparms) == 0) {	
+					CapLog("Get video capture numerator is %d, denominator is %d.", streamparms.parm.capture.timeperframe.numerator, streamparms.parm.capture.timeperframe.denominator);
 				}
 			}
 		}
@@ -780,14 +733,12 @@ int VideoCaptureImpl::StartVideoCapture()
 	// If driver doesn't support framerate control, need to hardcode.
 	// Hardcoding the value based on the frame size.
 	if (!driver_framerate_support) {
-		if (m_capture_width >= 800 && m_captureVideoType != VideoType::kMJPEG) {
+		if (m_in_cap_width >= 800 && m_captureVideoType != VideoType::kMJPEG) {
 			m_currentFrameRate = 15;
 		}
 		else {
 			m_currentFrameRate = 5;
-			if (m_callback){
-				m_callback->Debug("The Camera not support set video capture framerate, set capture rate to %d.", m_currentFrameRate);
-			}
+			CapLog("The Camera not support set video capture framerate, set capture rate to %d.", m_currentFrameRate);
 		}
 	}
 
@@ -797,22 +748,16 @@ int VideoCaptureImpl::StartVideoCapture()
 	}
 
 	if (!AllocateVideoCapturebuffer()) {
-		if (m_callback){
-			m_callback->Debug("failed to allocate video capture buffers");
-		}
+		CapLog("failed to allocate video capture buffers");
 		close(m_deviceFd);
 		return -1;
 	}
 	else{
-		if (m_callback){
-			m_callback->Debug("allocate video capture buffers success!");
-		}
+		CapLog("allocate video capture buffers success!");
 	}
 
 	if (-1 == pthread_create(&m_CaptureThreadId, NULL, VideoCaptureProcess, this)) {
-		if (m_callback){
-			m_callback->Debug("Create Video Capture Thread Failed!");
-		}
+		CapLog("Create Video Capture Thread Failed!");
 		close(m_deviceFd);
 		return -1;
 	}
@@ -821,9 +766,7 @@ int VideoCaptureImpl::StartVideoCapture()
 	enum v4l2_buf_type type;
 	type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 	if (ioctl(m_deviceFd, VIDIOC_STREAMON, &type) == -1) {
-		if (m_callback){
-			m_callback->Debug("failed to turn on stream for %s.", strerror(errno));
-		}
+		CapLog("failed to turn on stream for %s.", strerror(errno));
 		close(m_deviceFd);
 		return -1;
 	}
@@ -850,9 +793,7 @@ bool VideoCaptureImpl::AllocateVideoBuffers()
 
 	//向设备申请缓冲区
 	if (ioctl(m_deviceFd, VIDIOC_REQBUFS, &rbuffer) < 0){
-		if (m_callback){
-			m_callback->Debug("Could not get buffers from device for %s.", strerror(errno));
-		}
+		CapLog("Could not get buffers from device for %s.", strerror(errno));
 		return false;
 	}
 
@@ -908,9 +849,7 @@ bool VideoCaptureImpl::DeAllocateVideoBuffers()
 	enum v4l2_buf_type type;
 	type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 	if (ioctl(m_deviceFd, VIDIOC_STREAMOFF, &type) < 0){
-		if (m_callback){
-			m_callback->Debug("VIDIOC_STREAMOFF error. error no: %d", errno);
-		}
+		CapLog("VIDIOC_STREAMOFF error. error no: %d", errno);
 	}
 
 	return true;
@@ -920,17 +859,17 @@ bool VideoCaptureImpl::DeAllocateVideoBuffers()
 bool VideoCaptureImpl::AlignedMallocVideoBuffer()
 {
 	bool bret = false;
-	int stride_y = m_capture_width;
-	int stride_u = (m_capture_width + 1) / 2;
-	int stride_v = (m_capture_width + 1) / 2;
+	int stride_y = m_in_cap_width;
+	int stride_u = (m_in_cap_width + 1) / 2;
+	int stride_v = (m_in_cap_width + 1) / 2;
 
-	m_i420 = (uint8_t*)AlignedMalloc(I420DataSize(m_capture_height, stride_y, stride_u, stride_v), kBufferAlignment);
-	m_rgb24 = (uint8_t*)AlignedMalloc(RGB24DataSize(m_dest_cap_height, m_dest_cap_width, (m_dest_cap_width + 1) / 2, (m_dest_cap_width + 1) / 2), kBufferAlignment);
+	m_i420 = (uint8_t*)AlignedMalloc(I420DataSize(m_in_cap_height, stride_y, stride_u, stride_v), kBufferAlignment);
+	m_rgb24 = (uint8_t*)AlignedMalloc(RGB24DataSize(m_out_cap_height, m_out_cap_width, (m_out_cap_width + 1) / 2, (m_out_cap_width + 1) / 2), kBufferAlignment);
 
-	int opt_stride_y = m_dest_cap_width;
-	int opt_stride_u = (m_dest_cap_width + 1) / 2;
-	int opt_stride_v = (m_dest_cap_width + 1) / 2;
-	m_opti420 = (uint8_t*)AlignedMalloc(I420DataSize(m_dest_cap_height, opt_stride_y, opt_stride_u, opt_stride_v), kBufferAlignment);
+	int opt_stride_y = m_out_cap_width;
+	int opt_stride_u = (m_out_cap_width + 1) / 2;
+	int opt_stride_v = (m_out_cap_width + 1) / 2;
+	m_opti420 = (uint8_t*)AlignedMalloc(I420DataSize(m_out_cap_height, opt_stride_y, opt_stride_u, opt_stride_v), kBufferAlignment);
 
 	if (m_i420 && m_rgb24 && m_opti420){
 		bret = true;
@@ -966,11 +905,6 @@ bool VideoCaptureImpl::VideoCaptureStarted()
 	return m_bCaptureStarted;
 }
 
-ICaptureCallback* VideoCaptureImpl::GetCaptureCallback()
-{
-	return m_callback;
-}
-
 int VideoCaptureImpl::GetCaptureVideoFd()
 {
 	return m_deviceFd;
@@ -984,12 +918,12 @@ VideoType VideoCaptureImpl::GetCaptureVideoType()
 
 int VideoCaptureImpl::GetCapture_Width()
 {
-	return m_capture_width;
+	return m_real_cap_width;
 }
 
 int VideoCaptureImpl::GetCapture_Height()
 {
-	return m_capture_height;
+	return m_real_cap_height;
 }
 
 bool VideoCaptureImpl::GetStopCaptureFlag()
@@ -1005,14 +939,10 @@ int VideoCaptureImpl::StopVideoCapture()
 
 		if (0 == pthread_join(m_CaptureThreadId, NULL))		{
 			m_CaptureThreadId = 0;
-			if (m_callback){
-				m_callback->Debug("thread join video capture thread success.");
-			}
+			CapLog("thread join video capture thread success.");
 		}
 		else {
-			if (m_callback){
-				m_callback->Debug("thread join video capture thread failed for %s.", strerror(errno));
-			}
+			CapLog("thread join video capture thread failed for %s.", strerror(errno));
 		}
 
 		DeAllocateVideoBuffers();
@@ -1020,9 +950,7 @@ int VideoCaptureImpl::StopVideoCapture()
 		close(m_deviceFd);
 		m_deviceFd = -1;
 
-		if (m_callback) {
-			m_callback->Debug("video capture has stopped!");
-		}
+		CapLog("video capture has stopped!");
 	}
 
 	return 0;
@@ -1040,9 +968,7 @@ int VideoCaptureImpl::GetCamBrightness(int* ibright)
 	struct v4l2_control ctrl;
 	ctrl.id = V4L2_CID_BRIGHTNESS;
 	if (ioctl(m_deviceFd,VIDIOC_G_CTRL,&ctrl) == -1){
-		if (m_callback){
-			m_callback->Debug("VIDIOC_S_CTRL get V4L2_CID_BRIGHTNESS error for %s", strerror(errno));
-		}
+		CapLog("VIDIOC_S_CTRL get V4L2_CID_BRIGHTNESS error for %s", strerror(errno));
 	}
 	else {
 		//m_callback->Debug("VIDIOC_S_CTRL get V4L2_CID_BRIGHTNESS success and brightness is %d", ctrl.value);
@@ -1060,9 +986,7 @@ int VideoCaptureImpl::SetCamBrightness(int ibright)
 	ctrl.id = V4L2_CID_BRIGHTNESS;
 	ctrl.value = TransToRealBrightnessValue(ibright);
 	if (ioctl(m_deviceFd, VIDIOC_S_CTRL, &ctrl) == -1){
-		if (m_callback){
-			m_callback->Debug("VIDIOC_S_CTRL set V4L2_CID_BRIGHTNESS error for %s", strerror(errno));
-		}
+		CapLog("VIDIOC_S_CTRL set V4L2_CID_BRIGHTNESS error for %s", strerror(errno));
 	}
 	else{
 		//m_callback->Debug("VIDIOC_S_CTRL set V4L2_CID_BRIGHTNESS success %d", ctrl.value);
@@ -1099,14 +1023,10 @@ bool VideoCaptureImpl::GetCamBrightnessInfo()
 	struct v4l2_queryctrl qctrl;
 	qctrl.id = V4L2_CID_BRIGHTNESS;
 	if (ioctl(m_deviceFd, VIDIOC_QUERYCTRL, &qctrl) == -1) {
-		if (m_callback){
-			m_callback->Debug("VIDIOC_QUERYCTRL get V4L2_CID_BRIGHTNESS error for %s", strerror(errno));
-		}
+		CapLog("VIDIOC_QUERYCTRL get V4L2_CID_BRIGHTNESS error for %s", strerror(errno));
 	}
 	else {
-		if (m_callback){
-			m_callback->Debug("VIDIOC_QUERYCTRL get V4L2_CID_BRIGHTNESS success {min(%d) - max(%d)},default is %d", qctrl.minimum, qctrl.maximum, qctrl.default_value);
-		}
+		CapLog("VIDIOC_QUERYCTRL get V4L2_CID_BRIGHTNESS success {min(%d) - max(%d)},default is %d", qctrl.minimum, qctrl.maximum, qctrl.default_value);
 		m_idefaultbrightness = qctrl.default_value;
 		m_iminbrightness = qctrl.minimum;
 		m_imaxbrightness = qctrl.maximum;
@@ -1180,3 +1100,13 @@ libyuv::RotationMode VideoCaptureImpl::RotateTrans(int irotate)
 	return rotation_mode;
 }
 
+
+void VideoCaptureImpl::CapLog(const char* fmt, ...)
+{
+	if (m_callback.debug) {
+		va_list arg;
+		va_start(arg, fmt);
+		(*m_callback.debug)(m_callback.user_data, fmt, arg);
+		va_end(arg);
+	}
+}

+ 14 - 7
Other/libvideocapture/linux/videocapture_linux.h

@@ -47,7 +47,7 @@ struct Buffer
 class VideoCaptureImpl : public IVideoCapture
 {
 public:
-	VideoCaptureImpl(ICaptureCallback* pCallback);
+	VideoCaptureImpl(videocap_callback_t* pCallback);
 	~VideoCaptureImpl();
 
 	virtual int VideoCaptureSetParam(videocap_param_t* param);
@@ -60,7 +60,6 @@ public:
 
 	bool GetCamBrightnessInfo();
 	bool VideoCaptureStarted();
-	ICaptureCallback* GetCaptureCallback();
 	int GetCaptureVideoFd();
 	bool AllocateVideoBuffers();
 	bool DeAllocateVideoBuffers();
@@ -76,16 +75,18 @@ public:
 	bool GetStopCaptureFlag();
 	int32_t IncomingFrame(uint8_t* videoFrame, size_t videoFrameLength,	const VideoCaptureCapability& frameInfo, int64_t captureTime = 0);
 	Buffer* GetCaptureBuffer();
+	void CapLog(const char* fmt, ...);
 
 private:
 	int TransToRealBrightnessValue(int ibright);
 	int TransFromRealBrightnessValue(int ibright);
 	libyuv::RotationMode RotateTrans(int irotate);
+	
 
 private:
 	enum { kNoOfV4L2Bufffers = 4 };
 
-	ICaptureCallback* m_callback;
+	videocap_callback_t m_callback;
 	videocap_t* m_capture;
 	bool m_bCaptureStarted;
 	bool m_bStopCapture;
@@ -95,10 +96,16 @@ private:
 	int m_deviceFd;
 
 	int m_frame_fmt;
-	int m_capture_width;
-	int m_capture_height;
-	int m_dest_cap_width;
-	int m_dest_cap_height;
+	
+	int m_in_cap_width;
+	int m_in_cap_height;
+
+	int m_real_cap_width;
+	int m_real_cap_height;
+	
+	int m_out_cap_width;
+	int m_out_cap_height;
+
 	libyuv::RotationMode m_rotate;
 	VideoType m_captureVideoType;
 	int m_currentFrameRate;

+ 2 - 2
Other/libvideorender/CMakeLists.txt

@@ -12,8 +12,8 @@ endif(RVC_DEBUG_MODE)
 set(${MODULE_PREFIX}_SRCS
     ivideorenderinterface.h
 	ivideorenderinterface.cpp
-	./linux/videorender_linux.h
-	./linux/videorender_linux.cpp
+	libvideorender.h
+	libvideorender.cpp
 )
 
 add_library(${MODULE_NAME} SHARED ${${MODULE_PREFIX}_SRCS})

+ 2 - 2
Other/libvideorender/ivideorenderinterface.cpp

@@ -1,8 +1,8 @@
 #include "ivideorenderinterface.h"
-#include "./linux/videorender_linux.h"
+#include "libvideorender.h"
 
 
-IVideoRender* CreateVideoRenderObj(IRenderCallback* pCallback)
+IVideoRender* CreateVideoRenderObj(videorender_callback_t* pCallback)
 {
 	return new VideoRenderImpl(pCallback);
 }

+ 19 - 7
Other/libvideorender/ivideorenderinterface.h

@@ -13,6 +13,14 @@
 #endif // RVC_OS_WIN
 
 #include <stdint.h>
+#include <stdarg.h>
+
+typedef enum
+{
+	RVC_FLIP_NONE = 0x00000000,     /**< Do not flip */
+	RVC_FLIP_HORIZONTAL = 0x00000001,    /**< flip horizontally */
+	RVC_FLIP_VERTICAL = 0x00000002     /**< flip vertically */
+} RVC_RendererFlip;
 
 struct video_frame;
 
@@ -26,14 +34,18 @@ typedef struct videorender_param_s {
 	uint32_t uwinflags;
 	bool bpersonarea;
 	int ivideoformat;
+	bool bmoveable;
 }videorender_param_t;
 
-struct IRenderCallback
+
+typedef struct videorender_callback_s
 {
-	virtual void Debug(const char* fmt, ...) = 0;
-	virtual void OnRenderFailed() = 0;
-	virtual void OnVideoRenderExcption() = 0;
-};
+	void (*debug)(void* user_data, const char* fmt, va_list arg);
+	void (*onrenderfailed)();
+	void (*onvideorenderexcption)();
+	void* user_data;
+}videorender_callback_t;
+
 
 class IVideoRender 
 {
@@ -44,11 +56,11 @@ public:
 	virtual void VideoRenderDestroy() = 0;
 	virtual int ShowVideoWindow() = 0;
 	virtual int HideVideoWindow() = 0;
-	virtual int RenderVideoFrame(video_frame* pframe) = 0;
+	virtual int RenderVideoFrame(video_frame* pframe, RVC_RendererFlip eFlipType = RVC_FLIP_NONE) = 0;
 };
 
 
-extern "C" LIBVIDEORENDER_API IVideoRender* CreateVideoRenderObj(IRenderCallback* pCallback);
+extern "C" LIBVIDEORENDER_API IVideoRender* CreateVideoRenderObj(videorender_callback_t* pCallback);
 extern "C" LIBVIDEORENDER_API void DestroyVideoRenderObj(IVideoRender* pIVideoRender);
 extern "C" LIBVIDEORENDER_API int VideoRender_Init();
 extern "C" LIBVIDEORENDER_API int VideoRender_Term();

+ 171 - 58
Other/libvideorender/linux/videorender_linux.cpp → Other/libvideorender/libvideorender.cpp

@@ -1,13 +1,27 @@
-#include"videorender_linux.h"
-#include "../../libvideoframework/videoutil.h"
+#include"libvideorender.h"
+#include "../libvideoframework/videoutil.h"
 
 
-VideoRenderImpl::VideoRenderImpl(IRenderCallback* pCallback)
+//Refresh Event
+#ifndef REFRESH_EVENT
+#define REFRESH_EVENT  (SDL_USEREVENT + 1)
+#endif
+
+#ifndef RVC_DEFAULT_DELAY_TIME
+#define RVC_DEFAULT_DELAY_TIME 1
+#endif
+
+
+VideoRenderImpl::VideoRenderImpl(videorender_callback_t* pCallback)
 {
 	m_sdl_window = NULL;
 	m_rending_texture = NULL;
 	m_renderer = NULL;
-	m_callback = pCallback;
+	memcpy(&m_callback, pCallback, sizeof(videorender_callback_t));
+
+	m_refresh_flag = false;
+	m_bmoveable = false;
+	m_refresh_thread = NULL;
 
 	m_cx = SDL_WINDOWPOS_UNDEFINED;
 	m_cy = SDL_WINDOWPOS_UNDEFINED;
@@ -15,7 +29,6 @@ VideoRenderImpl::VideoRenderImpl(IRenderCallback* pCallback)
 	m_height = 0;
 	m_videoformat = VIDEO_FORMAT_RGB24;
 	m_flags = SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_BORDERLESS | SDL_WINDOW_HIDDEN | SDL_WINDOW_ALWAYS_ON_TOP | SDL_WINDOW_SKIP_TASKBAR | SDL_WINDOW_POPUP_MENU;
-	m_convertbuffer = NULL;
 }
 
 
@@ -35,11 +48,6 @@ VideoRenderImpl::~VideoRenderImpl()
 		SDL_DestroyWindow(m_sdl_window);
 		m_sdl_window = NULL;
 	}
-
-	if (NULL != m_convertbuffer){
-		delete []m_convertbuffer;
-		m_convertbuffer = NULL;
-	}
 		
 	//SDL_Quit();
 }
@@ -69,10 +77,6 @@ int VideoRenderImpl::SetWindowProperty(videorender_param_t* tparam)
 
 	m_videoformat = tparam->ivideoformat;
 
-	if (VIDEO_FORMAT_RGB24 == m_videoformat){
-		m_convertbuffer = new unsigned char[m_videowidth* m_videoheight*4];
-	}
-
 	iRet = 0;
 
 	return iRet;
@@ -92,15 +96,15 @@ SDL_PixelFormatEnum VideoRenderImpl::GetPixelFormat()
 int VideoRenderImpl::VideoRenderSetParam(videorender_param_t* tparam)
 {
 	if (SetWindowProperty(tparam)){
-		m_callback->Debug("SetWindowProperty failed for param error.");
+		RenderLog("SetWindowProperty failed for param error.");
 		return -1;
 	}
 
 	if (NULL == m_sdl_window){
-		// if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0){
-			// m_callback->Debug("RENDER: Couldn't initialize SDL2: %s", SDL_GetError());
-			// return -1;
-		// }
+		//if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0){
+		//	m_callback->Debug("RENDER: Couldn't initialize SDL2: %s", SDL_GetError());
+		//	return -1;
+		//}
 
 		SDL_SetHint("SDL_HINT_RENDER_SCALE_QUALITY", "1");
 
@@ -114,7 +118,7 @@ int VideoRenderImpl::VideoRenderSetParam(videorender_param_t* tparam)
 		);
 
 		if (NULL == m_sdl_window){
-			m_callback->Debug("RENDER: (SDL2) Couldn't open window: %s", SDL_GetError());
+			RenderLog("RENDER: (SDL2) Couldn't open window: %s", SDL_GetError());
 			VideoRenderDestroy();
 			return -2;
 		}
@@ -123,14 +127,14 @@ int VideoRenderImpl::VideoRenderSetParam(videorender_param_t* tparam)
 		SDL_DisplayMode display_mode;
 		int err = SDL_GetDesktopDisplayMode(display_index, &display_mode);
 		if (0 == err){
-			m_callback->Debug("RENDER: video display %i ->  %dx%dpx @ %dhz",
+			RenderLog("RENDER: video display %i ->  %dx%dpx @ %dhz",
 					display_index,
 					display_mode.w,
 					display_mode.h,
 					display_mode.refresh_rate);
 		}
 		else {
-			m_callback->Debug("RENDER: Couldn't determine display mode for video display %i", display_index);
+			RenderLog("RENDER: Couldn't determine display mode for video display %i", display_index);
 		}
 
 		if (m_width > display_mode.w) {
@@ -146,19 +150,19 @@ int VideoRenderImpl::VideoRenderSetParam(videorender_param_t* tparam)
 	/* Allocate a renderer info struct*/
 	SDL_RendererInfo* rend_info = (SDL_RendererInfo*)malloc(sizeof(SDL_RendererInfo));
 	if (NULL == rend_info){
-		m_callback->Debug("RENDER: Couldn't allocate memory for the renderer info data structure");
+		RenderLog("RENDER: Couldn't allocate memory for the renderer info data structure");
 		VideoRenderDestroy();
 		return -5;
 	}
 	
 	/* Print the list of the available renderers*/
-	m_callback->Debug("RENDER: Available SDL2 rendering drivers:");
+	RenderLog("RENDER: Available SDL2 rendering drivers:");
 	for (int i = 0; i < SDL_GetNumRenderDrivers(); i++){
 		if (SDL_GetRenderDriverInfo(i, rend_info) < 0){
-			m_callback->Debug("Couldn't get SDL2 render driver information: %s", SDL_GetError());
+			RenderLog("Couldn't get SDL2 render driver information: %s", SDL_GetError());
 		}
 		else {
-			m_callback->Debug(" %2d: %s", i, rend_info->name);
+			RenderLog(" %2d: %s", i, rend_info->name);
 			//m_callback->Debug("    SDL_RENDERER_TARGETTEXTURE [%c]", (rend_info->flags & SDL_RENDERER_TARGETTEXTURE) ? 'X' : ' ');
 			//m_callback->Debug("    SDL_RENDERER_SOFTWARE      [%c]", (rend_info->flags & SDL_RENDERER_SOFTWARE) ? 'X' : ' ');
 			//m_callback->Debug("    SDL_RENDERER_ACCELERATED   [%c]", (rend_info->flags & SDL_RENDERER_ACCELERATED) ? 'X' : ' ');
@@ -174,8 +178,8 @@ int VideoRenderImpl::VideoRenderSetParam(videorender_param_t* tparam)
 
 	if (m_renderer == NULL)
 	{
-		m_callback->Debug("RENDER: (SDL2) Couldn't get a accelerated renderer: %s", SDL_GetError());
-		m_callback->Debug("RENDER: (SDL2) trying with a software renderer");
+		RenderLog("RENDER: (SDL2) Couldn't get a accelerated renderer: %s", SDL_GetError());
+		RenderLog("RENDER: (SDL2) trying with a software renderer");
 
 		m_renderer = SDL_CreateRenderer(m_sdl_window, -1,
 			SDL_RENDERER_TARGETTEXTURE |
@@ -183,8 +187,8 @@ int VideoRenderImpl::VideoRenderSetParam(videorender_param_t* tparam)
 
 		if (m_renderer == NULL)
 		{
-			m_callback->Debug("RENDER: (SDL2) Couldn't get a software renderer: %s", SDL_GetError());
-			m_callback->Debug("RENDER: (SDL2) giving up...");
+			RenderLog("RENDER: (SDL2) Couldn't get a software renderer: %s", SDL_GetError());
+			RenderLog("RENDER: (SDL2) giving up...");
 			VideoRenderDestroy();
 			return -3;
 		}
@@ -193,16 +197,16 @@ int VideoRenderImpl::VideoRenderSetParam(videorender_param_t* tparam)
 	/* Allocate a renderer info struct*/
 	SDL_RendererInfo* render_info = (SDL_RendererInfo*)malloc(sizeof(SDL_RendererInfo));
 	if (NULL == render_info){
-		m_callback->Debug("RENDER: Couldn't allocate memory for the renderer info data structure");
+		RenderLog("RENDER: Couldn't allocate memory for the renderer info data structure");
 		VideoRenderDestroy();
 		return -5;
 	}
 	
 	/* Print the name of the current rendering driver */
 	if (SDL_GetRendererInfo(m_renderer, render_info) < 0){
-		m_callback->Debug("Couldn't get SDL2 rendering driver information: %s", SDL_GetError());
+		RenderLog("Couldn't get SDL2 rendering driver information: %s", SDL_GetError());
 	}
-	m_callback->Debug("RENDER: rendering driver in use: %s", render_info->name);
+	RenderLog("RENDER: rendering driver in use: %s", render_info->name);
 	//m_callback->Debug("    SDL_RENDERER_TARGETTEXTURE [%c]", (render_info->flags & SDL_RENDERER_TARGETTEXTURE) ? 'X' : ' ');
 	//m_callback->Debug("    SDL_RENDERER_SOFTWARE      [%c]", (render_info->flags & SDL_RENDERER_SOFTWARE) ? 'X' : ' ');
 	//m_callback->Debug("    SDL_RENDERER_ACCELERATED   [%c]", (render_info->flags & SDL_RENDERER_ACCELERATED) ? 'X' : ' ');
@@ -220,7 +224,7 @@ int VideoRenderImpl::VideoRenderSetParam(videorender_param_t* tparam)
 		m_videoheight);
 
 	if (m_rending_texture == NULL){
-		m_callback->Debug("RENDER: (SDL2) Couldn't get a texture for rendering: %s", SDL_GetError());
+		RenderLog("RENDER: (SDL2) Couldn't get a texture for rendering: %s", SDL_GetError());
 		VideoRenderDestroy();
 		return -4;
 	}
@@ -229,14 +233,89 @@ int VideoRenderImpl::VideoRenderSetParam(videorender_param_t* tparam)
 }
 
 
+static int refresh_video(void *opaque)
+{
+	VideoRenderImpl* pImpl = (VideoRenderImpl*)opaque;
+	pImpl->RenderLog("function enter %s:%d", __FUNCTION__, __LINE__);
+	while (pImpl->GetReFreshFlag()) {
+		SDL_Event event;
+		event.type = REFRESH_EVENT;
+		SDL_PushEvent(&event);
+		SDL_Delay(RVC_DEFAULT_DELAY_TIME);
+	}
+	pImpl->RenderLog("function leave %s:%d", __FUNCTION__, __LINE__);
+
+	return 0;
+}
+
+
+static SDL_HitTestResult SDLCALL SDL_HitTestCallback(SDL_Window *win, const SDL_Point *area, void *data)
+{
+	int w, h;
+	const int RESIZE_BORDER = 8;
+	const int DRAGGABLE_TITLE = 32;
+
+	VideoRenderImpl* pImpl = (VideoRenderImpl*)data;
+
+	SDL_GetWindowSize(win, &w, &h);
+
+	if (area->x < RESIZE_BORDER) {
+		if (area->y < RESIZE_BORDER) {
+			pImpl->RenderLog("SDL_HITTEST_RESIZE_TOPLEFT");
+			return SDL_HITTEST_RESIZE_TOPLEFT;
+		} else if (area->y >= (h-RESIZE_BORDER)) {
+			pImpl->RenderLog("SDL_HITTEST_RESIZE_BOTTOMLEFT");
+			return SDL_HITTEST_RESIZE_BOTTOMLEFT;
+		} else {
+			pImpl->RenderLog("SDL_HITTEST_RESIZE_LEFT");
+			return SDL_HITTEST_RESIZE_LEFT;
+		}
+	} else if (area->x >= (w-RESIZE_BORDER)) {
+		if (area->y < RESIZE_BORDER) {
+			pImpl->RenderLog("SDL_HITTEST_RESIZE_TOPRIGHT");
+			return SDL_HITTEST_RESIZE_TOPRIGHT;
+		} else if (area->y >= (h-RESIZE_BORDER)) {
+			pImpl->RenderLog("SDL_HITTEST_RESIZE_BOTTOMRIGHT");
+			return SDL_HITTEST_RESIZE_BOTTOMRIGHT;
+		} else {
+			pImpl->RenderLog("SDL_HITTEST_RESIZE_RIGHT");
+			return SDL_HITTEST_RESIZE_RIGHT;
+		}
+	} else if (area->y >= (h-RESIZE_BORDER)) {
+		pImpl->RenderLog("SDL_HITTEST_RESIZE_BOTTOM");
+		return SDL_HITTEST_RESIZE_BOTTOM;
+	} else if (area->y < RESIZE_BORDER) {
+		pImpl->RenderLog("SDL_HITTEST_RESIZE_TOP");
+		return SDL_HITTEST_RESIZE_TOP;
+	} else if (area->y < DRAGGABLE_TITLE) {
+		pImpl->RenderLog("SDL_HITTEST_DRAGGABLE");
+		return SDL_HITTEST_DRAGGABLE;
+	}
+	return SDL_HITTEST_NORMAL;
+}
+
+
+bool VideoRenderImpl::GetReFreshFlag()
+{
+	return m_refresh_flag;
+}
+
 int VideoRenderImpl::StartVideoRender()
 {
+	m_refresh_flag = true;
+	m_refresh_thread = SDL_CreateThread(refresh_video,"refresh video thread", this);
+	RenderLog("%s:%d m_refresh_thread is 0x%08x.",__FUNCTION__, __LINE__, m_refresh_thread);
+	if (m_bmoveable){
+		SDL_SetWindowHitTest(m_sdl_window, SDL_HitTestCallback, this);
+	}
+
 	return 0;
 }
 
 int VideoRenderImpl::ShowVideoWindow()
 {
 	int iret = -1;
+
 	if (NULL != m_sdl_window){
 		SDL_ShowWindow(m_sdl_window);
 		iret = 0;
@@ -258,6 +337,15 @@ int VideoRenderImpl::HideVideoWindow()
 int VideoRenderImpl::StopVideoRender()
 {
 	HideVideoWindow();
+	
+	m_refresh_flag = false;
+
+	RenderLog("%s:%d m_refresh_thread is 0x%08x.",__FUNCTION__, __LINE__, m_refresh_thread);
+	if (NULL != m_refresh_thread){
+		SDL_WaitThread(m_refresh_thread, NULL);
+		RenderLog("%s:%d video refresh thread exit.",__FUNCTION__, __LINE__);
+	}
+	
 	return 0;
 }
 
@@ -268,39 +356,51 @@ void VideoRenderImpl::VideoRenderDestroy()
 }
 
 
-int VideoRenderImpl::RenderVideoFrame(video_frame* pframe)
+int VideoRenderImpl::RenderVideoFrame(video_frame* pframe, RVC_RendererFlip eFlipType)
 {
 	int iret = -1;
 	if (NULL == m_sdl_window || NULL == pframe || NULL == m_renderer || NULL == m_rending_texture){
 		return iret;
 	}
 
-	SDL_SetRenderDrawColor(m_renderer, 0, 0, 0, 255); /*black*/
-	SDL_RenderClear(m_renderer);
+	SDL_Event event;
+	SDL_WaitEvent(&event);
 
-	/* since data is continuous we can use SDL_UpdateTexture
-	 * instead of SDL_UpdateYUVTexture.
-	 * no need to use SDL_Lock/UnlockTexture (it doesn't seem faster)
-	 */
-	//SDL_QueryTexture()
+	if(REFRESH_EVENT == event.type){
+		SDL_SetRenderDrawColor(m_renderer, 0, 0, 0, 255); /*black*/
+		SDL_RenderClear(m_renderer);
 
-	if (VIDEO_FORMAT_RGB24 == pframe->format){
-		//ConVert24to32(pframe->data[0], m_convertbuffer, pframe->width, pframe->height);
-		SDL_UpdateTexture(m_rending_texture, NULL, pframe->data[0], pframe->width*3);
-		SDL_Point point = {m_videowidth/2, m_videoheight/2};
-		SDL_RenderCopyEx(m_renderer, m_rending_texture, NULL, NULL, 0, &point, SDL_FLIP_VERTICAL);
-	}
-	else if(VIDEO_FORMAT_I420 == pframe->format){
-		SDL_UpdateTexture(m_rending_texture, NULL, pframe->data[0], pframe->width);
-		SDL_RenderCopy(m_renderer, m_rending_texture, NULL, NULL);
-	}
-	else
-	{
-		m_callback->Debug("%s:%d not support format, return", __FUNCTION__, __LINE__);
-		return iret;
-	}
+		/* since data is continuous we can use SDL_UpdateTexture
+		* instead of SDL_UpdateYUVTexture.
+		* no need to use SDL_Lock/UnlockTexture (it doesn't seem faster)
+		*/
+		//SDL_QueryTexture()
+
+		if (VIDEO_FORMAT_RGB24 == pframe->format || VIDEO_FORMAT_I420 == pframe->format){
+			if (VIDEO_FORMAT_RGB24 == pframe->format){
+				SDL_UpdateTexture(m_rending_texture, NULL, pframe->data[0], pframe->width*3);
+			}
+			else{
+				SDL_UpdateTexture(m_rending_texture, NULL, pframe->data[0], pframe->width);
+			}
+		
+			if (RVC_FLIP_NONE == eFlipType){
+				SDL_RenderCopy(m_renderer, m_rending_texture, NULL, NULL);
+			}
+			else{
+				SDL_Point point = {m_videowidth/2, m_videoheight/2};
+				SDL_RenderCopyEx(m_renderer, m_rending_texture, NULL, NULL, 0, &point, (SDL_RendererFlip)eFlipType);
+			}
+		}
+		else{
+			RenderLog("%s:%d not support format, return", __FUNCTION__, __LINE__);
+			return iret;
+		}
+
+		SDL_RenderPresent(m_renderer);
 
-	SDL_RenderPresent(m_renderer);
+		SDL_Delay(RVC_DEFAULT_DELAY_TIME);
+	}
 
 	iret = 0;
 
@@ -308,6 +408,19 @@ int VideoRenderImpl::RenderVideoFrame(video_frame* pframe)
 }
 
 
+void VideoRenderImpl::RenderLog(const char* fmt, ...)
+{
+	if (m_callback.debug) {
+		va_list arg;
+		va_start(arg, fmt);
+		if (*m_callback.debug){
+			(*m_callback.debug)(m_callback.user_data, fmt, arg);
+		}
+		va_end(arg);
+	}
+}
+
+
 void VideoRenderImpl::ConVert24to32(unsigned char* image_in, unsigned char* image_out, int w, int h) 
 {
 	for (int i = 0; i < h; i++)

+ 9 - 6
Other/libvideorender/linux/videorender_linux.h → Other/libvideorender/libvideorender.h

@@ -1,6 +1,6 @@
 #pragma once
 
-#include "../ivideorenderinterface.h"
+#include "ivideorenderinterface.h"
 #include <SDL2/SDL.h>
 #include <SDL2/SDL_video.h>
 #include <SDL2/SDL_render.h>
@@ -11,7 +11,7 @@
 class VideoRenderImpl : public IVideoRender
 {
 public:
-	VideoRenderImpl(IRenderCallback* pCallback);
+	VideoRenderImpl(videorender_callback_t* pCallback);
 	~VideoRenderImpl();
 
 	int VideoRenderSetParam(videorender_param_t* tparam);
@@ -20,19 +20,21 @@ public:
 	void VideoRenderDestroy();
 	int ShowVideoWindow();
 	int HideVideoWindow();
-	int RenderVideoFrame(video_frame* pframe);
+	int RenderVideoFrame(video_frame* pframe, RVC_RendererFlip eFlipType = RVC_FLIP_NONE);
 
 	int SetWindowProperty(videorender_param_t* tparam);
 	SDL_PixelFormatEnum GetPixelFormat();
 	void ConVert24to32(unsigned char* image_in, unsigned char* image_out, int w, int h);
-
+	bool GetReFreshFlag();
+	void RenderLog(const char* fmt, ...);
 
 private:
 	SDL_Window* m_sdl_window;
 	SDL_Texture* m_rending_texture;
 	SDL_Renderer* m_renderer;
-	IRenderCallback* m_callback;
-	unsigned char* m_convertbuffer;
+	videorender_callback_t m_callback;
+	SDL_Thread *m_refresh_thread;
+	bool m_refresh_flag;
 
 	int m_cx;
 	int m_cy;
@@ -42,4 +44,5 @@ private:
 	uint32_t m_height;
 	uint32_t m_flags;
 	int m_videoformat;
+	bool m_bmoveable;
 };

+ 48 - 77
Other/libwmvrecord/FFmpegWriter.cpp

@@ -79,7 +79,7 @@ static int write_frame(AVFormatContext *fmt_ctx, const AVRational *time_base, AV
 }
 
 /* Add an output stream. */
-static BOOL add_stream(LogApi* pLogApi, OutputStream *ost, AVFormatContext *oc,
+static bool add_stream(LogApi* pLogApi, OutputStream *ost, AVFormatContext *oc,
                        AVCodec **codec,
                        enum AVCodecID codec_id,
                        int width, int height, int colorbit, int nfps,
@@ -91,23 +91,19 @@ static BOOL add_stream(LogApi* pLogApi, OutputStream *ost, AVFormatContext *oc,
     /* find the encoder */
     *codec = avcodec_find_encoder(codec_id);
     if (!(*codec)) {
-        fprintf(stderr, "Could not find encoder for '%s'\n",
-                avcodec_get_name(codec_id));
-        pLogApi->Debug("add_stream failed for Could not find encoder for '%s'", avcodec_get_name(codec_id));
-        return FALSE;
+        pLogApi->Debug("add_stream failed for Could not find encoder for %s", avcodec_get_name(codec_id));
+        return false;
     }
 
     ost->st = avformat_new_stream(oc, NULL);
     if (!ost->st) {
-        fprintf(stderr, "Could not allocate stream\n");
-        return FALSE;
+        return false;
     }
     ost->st->id = oc->nb_streams-1;
     c = avcodec_alloc_context3(*codec);
     if (!c) {
-        fprintf(stderr, "Could not alloc an encoding context\n");
         pLogApi->Debug("add_stream failed for Could not alloc an encoding context");
-        return FALSE;
+        return false;
     }
     ost->enc = c;
 
@@ -182,7 +178,7 @@ static BOOL add_stream(LogApi* pLogApi, OutputStream *ost, AVFormatContext *oc,
 
     pLogApi->Debug("add_stream success get encoder for '%s'", avcodec_get_name(codec_id));
 
-	return TRUE;
+	return true;
 }
 
 /**************************************************************/
@@ -196,7 +192,6 @@ static AVFrame *alloc_audio_frame(enum AVSampleFormat sample_fmt,
     int ret;
 
     if (!frame) {
-        fprintf(stderr, "Error allocating an audio frame\n");
         return NULL;
     }
 
@@ -208,7 +203,6 @@ static AVFrame *alloc_audio_frame(enum AVSampleFormat sample_fmt,
     if (nb_samples) {
         ret = av_frame_get_buffer(frame, 0);
         if (ret < 0) {
-            fprintf(stderr, "Error allocating an audio buffer\n");
 			av_frame_free(&frame);
             return NULL;
         }
@@ -217,7 +211,7 @@ static AVFrame *alloc_audio_frame(enum AVSampleFormat sample_fmt,
     return frame;
 }
 
-static BOOL open_audio(LogApi* pLogApi, AVFormatContext *oc, AVCodec *codec, OutputStream *ost, AVDictionary *opt_arg, enum AVSampleFormat in_sample_fmt)
+static bool open_audio(LogApi* pLogApi, AVFormatContext *oc, AVCodec *codec, OutputStream *ost, AVDictionary *opt_arg, enum AVSampleFormat in_sample_fmt)
 {
     AVCodecContext *c;
     int nb_samples;
@@ -232,9 +226,8 @@ static BOOL open_audio(LogApi* pLogApi, AVFormatContext *oc, AVCodec *codec, Out
     ret = avcodec_open2(c, codec, &opt);
     av_dict_free(&opt);
     if (ret < 0) {
-        fprintf(stderr, "Could not open audio codec: %d\n", ret);
         pLogApi->Debug("open_audio failed for Could not open audio codec: %s, ret :%d", avcodec_get_name(codec->id), ret);
-        return FALSE;
+        return false;
     }
 
     if (c->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)
@@ -250,17 +243,15 @@ static BOOL open_audio(LogApi* pLogApi, AVFormatContext *oc, AVCodec *codec, Out
     /* copy the stream parameters to the muxer */
     ret = avcodec_parameters_from_context(ost->st->codecpar, c);
     if (ret < 0) {
-        fprintf(stderr, "Could not copy the stream parameters\n");
         pLogApi->Debug("open_audio failed for Could not copy the stream parameters");
-        return FALSE;
+        return false;
     }
 
     /* create resampler context */
         ost->swr_ctx = swr_alloc();
         if (!ost->swr_ctx) {
-            fprintf(stderr, "Could not allocate resampler context\n");
             pLogApi->Debug("open_audio failed for Could not allocate resampler context");
-            return FALSE;
+            return false;
         }
 
         /* set options */
@@ -273,14 +264,13 @@ static BOOL open_audio(LogApi* pLogApi, AVFormatContext *oc, AVCodec *codec, Out
 
         /* initialize the resampling context */
         if ((ret = swr_init(ost->swr_ctx)) < 0) {
-            fprintf(stderr, "Failed to initialize the resampling context\n");
             pLogApi->Debug("open_audio failed for Failed to initialize the resampling context");
-            return FALSE;
+            return false;
         }
 
         pLogApi->Debug("open_audio success encoder for %s, nb_samples:%d", avcodec_get_name(codec->id), nb_samples);
 
-	return TRUE;
+	return true;
 }
 
 /* Prepare a 16 bit dummy audio frame of 'frame_size' samples and
@@ -346,7 +336,6 @@ static int write_audio_frame(LogApi* pLogApi, AVFormatContext *oc, OutputStream
                           ost->frame->data, dst_nb_samples,
                           (const uint8_t **)frame->data, frame->nb_samples);
         if (ret < 0) {
-            fprintf(stderr, "Error while converting\n");
             pLogApi->Debug("write_audio_frame failed for Error while converting");
             return -1;
         }
@@ -363,7 +352,6 @@ static int write_audio_frame(LogApi* pLogApi, AVFormatContext *oc, OutputStream
 
     ret = avcodec_encode_audio2(c, &pkt, frame, &got_packet);
     if (ret < 0) {
-        fprintf(stderr, "Error encoding audio frame: %d\n", ret);
         pLogApi->Debug("write_audio_frame failed for Error encoding audio frame: %d", ret);
         return -1;
     }
@@ -372,8 +360,6 @@ static int write_audio_frame(LogApi* pLogApi, AVFormatContext *oc, OutputStream
         //pLogApi->Debug("write_audio_frame got_packet");
         ret = write_frame(oc, &c->time_base, ost->st, &pkt);
         if (ret < 0) {
-            fprintf(stderr, "Error while writing audio frame: %d\n",
-                    ret);
             pLogApi->Debug("write_audio_frame failed for Error while writing audio frame: %d", ret);
             return -1;
         }
@@ -401,7 +387,6 @@ static AVFrame *alloc_picture(enum AVPixelFormat pix_fmt, int width, int height)
     /* allocate the buffers for the frame data */
     ret = av_frame_get_buffer(picture, 32);
     if (ret < 0) {
-        fprintf(stderr, "Could not allocate frame data.\n");
 		av_frame_free(&picture);
         return NULL;
     }
@@ -409,7 +394,7 @@ static AVFrame *alloc_picture(enum AVPixelFormat pix_fmt, int width, int height)
     return picture;
 }
 
-static BOOL open_video(LogApi* pLogApi, AVFormatContext *oc, AVCodec *codec, OutputStream *ost, AVDictionary *opt_arg, enum AVPixelFormat input_pix_fmt)
+static bool open_video(LogApi* pLogApi, AVFormatContext *oc, AVCodec *codec, OutputStream *ost, AVDictionary *opt_arg, enum AVPixelFormat input_pix_fmt)
 {
     int ret;
     AVCodecContext *c = ost->enc;
@@ -430,17 +415,15 @@ static BOOL open_video(LogApi* pLogApi, AVFormatContext *oc, AVCodec *codec, Out
     ret = avcodec_open2(c, codec, &opt);
     av_dict_free(&opt);
     if (ret < 0) {
-        fprintf(stderr, "Could not open video codec: %d\n", ret);
         pLogApi->Debug("open_video failed for Could not open video codec: %s, ret :%d", avcodec_get_name(codec->id), ret);
-        return FALSE;
+        return false;
     }
 
     /* allocate and init a re-usable frame */
     ost->frame = alloc_picture(c->pix_fmt, c->width, c->height);
     if (!ost->frame) {
-        fprintf(stderr, "Could not allocate video frame\n");
         pLogApi->Debug("open_video failed for Could not allocate video frame");
-        return FALSE;
+        return false;
     }
 
     /* If the output format is not input_pix_fmt, then a temporary input_pix_fmt
@@ -450,25 +433,23 @@ static BOOL open_video(LogApi* pLogApi, AVFormatContext *oc, AVCodec *codec, Out
     if (c->pix_fmt != input_pix_fmt) {
         ost->tmp_frame = alloc_picture(input_pix_fmt, c->width, c->height);
         if (!ost->tmp_frame) {
-            fprintf(stderr, "Could not allocate temporary picture\n");
             pLogApi->Debug("Could not allocate temporary picture");
-            return FALSE;
+            return false;
         }
     }
 
     /* copy the stream parameters to the muxer */
     ret = avcodec_parameters_from_context(ost->st->codecpar, c);
     if (ret < 0) {
-        fprintf(stderr, "Could not copy the stream parameters\n");
         pLogApi->Debug("open_video failed for Could not copy the stream parameters");
-        return FALSE;
+        return false;
     }
 
     pLogApi->Debug("open_video success encoder for %s, output_fmt: %s,input_fmt: %s", avcodec_get_name(codec->id), 
         av_get_pix_fmt_name(c->pix_fmt), av_get_pix_fmt_name(input_pix_fmt));
     pLogApi->Debug("open_video success encoder, time_base num: %d,den: %d", c->time_base.num, c->time_base.den);
 
-	return TRUE;
+	return true;
 }
 
 /* Prepare a dummy image. */
@@ -512,8 +493,6 @@ static AVFrame *get_video_frame(OutputStream *ost, char *data, int len, AVPixelF
                 c->pix_fmt,
                 SCALE_FLAGS, NULL, NULL, NULL);
             if (!ost->sws_ctx) {
-                fprintf(stderr,
-                    "Could not initialize the conversion context\n");
                 return NULL;
             }
         }
@@ -575,7 +554,6 @@ static int write_video_frame(LogApi* pLogApi, AVFormatContext *oc, OutputStream
     /* encode the image */
     ret = avcodec_encode_video2(c, &pkt, frame, &got_packet);
     if (ret < 0) {
-        fprintf(stderr, "Error encoding video frame: %d\n", ret);
         pLogApi->Debug("open_video failed for Error encoding video frame: %d", ret);
         return -1;
     }
@@ -588,7 +566,6 @@ static int write_video_frame(LogApi* pLogApi, AVFormatContext *oc, OutputStream
     }
 
     if (ret < 0) {
-        fprintf(stderr, "Error while writing video frame: %d\n", ret);
         pLogApi->Debug("open_video failed for Error while writing video frame: %d", ret);
         return -1;
     }
@@ -608,25 +585,25 @@ static void close_stream(AVFormatContext *oc, OutputStream *ost)
 /**************************************************************/
 /* media file output */
 
-BOOL FFmpegWmvWriter::InitWmvWriter(char* filename, int width, int height, int colorbit, int nfps,
+bool FFmpegWmvWriter::InitWmvWriter(char* filename, int width, int height, int colorbit, int nfps,
     int nSanplePsec, int nchannels, int nBitPerSample, int nmaxspacing, int nquality, int nOutBitRate, int iAudioType)
 {
     int ret;
     AVDictionary *opt = NULL;
     int i;
-	BOOL result = TRUE;
+	bool result = true;
 
 	if (nBitPerSample != 8 && nBitPerSample != 16 && nBitPerSample != 32){
         m_pLogApi->Debug("InitWmvWriter Failed for BitPerSample = %d", nBitPerSample);
-		return FALSE;
+		return false;
 	}
 	if (nchannels != 1 && nchannels != 2){
         m_pLogApi->Debug("InitWmvWriter Failed for channels = %d", nchannels);
-		return FALSE;
+		return false;
 	}
 	if (colorbit != 24){
         m_pLogApi->Debug("InitWmvWriter Failed for colorbit = %d", colorbit);
-		return FALSE;
+		return false;
 	}
 
     if (colorbit == 24){
@@ -638,7 +615,7 @@ BOOL FFmpegWmvWriter::InitWmvWriter(char* filename, int width, int height, int c
     avformat_alloc_output_context2(&oc, NULL, NULL, filename);
     if (!oc) {
         m_pLogApi->Debug("InitWmvWriter Failed for avformat_alloc_output_context2, filename = %s", filename);
-        return FALSE;
+        return false;
     }
 
     //av_log_set_level(AV_LOG_DEBUG);
@@ -651,7 +628,7 @@ BOOL FFmpegWmvWriter::InitWmvWriter(char* filename, int width, int height, int c
      * and initialize the codecs. */
     if (fmt->video_codec != AV_CODEC_ID_NONE) {
         result = add_stream(m_pLogApi, video_st, oc, &video_codec, fmt->video_codec, width, height, colorbit, nfps, nSanplePsec, nchannels);
-		if (result == FALSE){
+		if (result == false){
 			Close();
             m_pLogApi->Debug("InitWmvWriter Failed for add_stream, video_codec = %d", fmt->video_codec);
 			return result;
@@ -660,7 +637,7 @@ BOOL FFmpegWmvWriter::InitWmvWriter(char* filename, int width, int height, int c
     }
     if (fmt->audio_codec != AV_CODEC_ID_NONE) {
         result = add_stream(m_pLogApi, audio_st, oc, &audio_codec, fmt->audio_codec, width, height, colorbit, nfps, nSanplePsec, nchannels);
-		if (result == FALSE){
+		if (result == false){
 			Close();
             m_pLogApi->Debug("InitWmvWriter Failed for add_stream, audio_codec = %d", fmt->audio_codec);
 			return result;
@@ -672,7 +649,7 @@ BOOL FFmpegWmvWriter::InitWmvWriter(char* filename, int width, int height, int c
      * video codecs and allocate the necessary encode buffers. */
     if (have_video){
         result = open_video(m_pLogApi, oc, video_codec, video_st, opt, input_pix_fmt);
-		if (result == FALSE){
+		if (result == false){
 			Close();
             m_pLogApi->Debug("InitWmvWriter Failed for open_video, video_codec = %d", fmt->video_codec);
 			return result;
@@ -681,21 +658,21 @@ BOOL FFmpegWmvWriter::InitWmvWriter(char* filename, int width, int height, int c
     if (have_audio){
 		if (nBitPerSample == 8){
 			result = open_audio(m_pLogApi, oc, audio_codec, audio_st, opt, AV_SAMPLE_FMT_U8);
-			if (result == FALSE){
+			if (result == false){
 				Close();
                 m_pLogApi->Debug("InitWmvWriter Failed for open_audio, AV_SAMPLE_FMT_U8");
 				return result;
 			}				
 		}else if (nBitPerSample == 16){
 			result = open_audio(m_pLogApi, oc, audio_codec, audio_st, opt, AV_SAMPLE_FMT_S16);
-			if (result == FALSE){
+			if (result == false){
 				Close();
                 m_pLogApi->Debug("InitWmvWriter Failed for open_audio, AV_SAMPLE_FMT_S16");
 				return result;
 			}				
 		}else if (nBitPerSample == 32) {
             result = open_audio(m_pLogApi, oc, audio_codec, audio_st, opt, AV_SAMPLE_FMT_FLT);
-            if (result == FALSE) {
+            if (result == false) {
                 Close();
                 m_pLogApi->Debug("InitWmvWriter Failed for open_audio, AV_SAMPLE_FMT_FLT");
                 return result;
@@ -709,11 +686,9 @@ BOOL FFmpegWmvWriter::InitWmvWriter(char* filename, int width, int height, int c
     if (!(fmt->flags & AVFMT_NOFILE)) {
         ret = avio_open(&oc->pb, filename, AVIO_FLAG_WRITE);
         if (ret < 0) {
-            fprintf(stderr, "Could not open '%s': %d\n", filename,
-                    ret);
 			Close();
             m_pLogApi->Debug("InitWmvWriter Failed for avio_open, %s", filename);
-            return FALSE;
+            return false;
         }
     }
 
@@ -724,32 +699,30 @@ BOOL FFmpegWmvWriter::InitWmvWriter(char* filename, int width, int height, int c
 
 
 
-BOOL FFmpegWmvWriter::StartWrite() {
+bool FFmpegWmvWriter::StartWrite() 
+{
 	AVDictionary *opt = NULL;
-
     /* Write the stream header, if any. */
     int ret = avformat_write_header(oc, &opt);
     if (ret < 0) {
-        fprintf(stderr, "Error occurred when opening output file: %d\n",
-            ret);
         m_pLogApi->Debug("StartWrite Failed when opening output file: %d", ret);
-        return FALSE;
+        return false;
     }
 
     m_pLogApi->Debug("FFmpegWmvWriter StartWrite success");
 
-	return TRUE;
+	return true;
 }
 
 
-BOOL FFmpegWmvWriter::End() {
+bool FFmpegWmvWriter::End() {
     /* Write the trailer, if any. The trailer must be written before you
      * close the CodecContexts open when you wrote the header; otherwise
      * av_write_trailer() may try to use memory that was freed on
      * av_codec_close(). */
 	if (oc == NULL){
         m_pLogApi->Debug("End Failed when oc is null");
-		return FALSE;
+		return false;
 	}
 	
     av_write_trailer(oc);
@@ -758,7 +731,7 @@ BOOL FFmpegWmvWriter::End() {
     av_log_set_callback(NULL);
 
     m_pLogApi->Debug("FFmpegWmvWriter End success");
-	return TRUE;
+	return true;
 }
 
 void FFmpegWmvWriter::Close(){
@@ -791,11 +764,10 @@ void FFmpegWmvWriter::Close(){
     m_pLogApi->Debug("FFmpegWmvWriter Close success");
 }
 
-BOOL FFmpegWmvWriter::ReceiveAudioData(BYTE* pData, DWORD len) {
-#if 1
+bool FFmpegWmvWriter::ReceiveAudioData(unsigned char* pData, unsigned long len) {
 	if (oc == NULL || audio_st == NULL || !have_audio){
         m_pLogApi->Debug("ReceiveAudioData Failed when oc is null");
-		return FALSE;
+		return false;
 	}
     //插入audio_input_buffer
     audio_input_buffer->putBytes(pData, len);
@@ -811,7 +783,7 @@ BOOL FFmpegWmvWriter::ReceiveAudioData(BYTE* pData, DWORD len) {
         int result = write_audio_frame(m_pLogApi, oc, audio_st, audio_input_buffer);
         if (result < 0) {
             m_pLogApi->Debug("write_audio_frame Failed, %d", result);
-            return FALSE;
+            return false;
         }
     }
     //重设置audio_input_buffer,避免buffer过大
@@ -820,24 +792,23 @@ BOOL FFmpegWmvWriter::ReceiveAudioData(BYTE* pData, DWORD len) {
     audio_input_buffer->getBytes(tmp_buffer, bytesRemaining);
     audio_input_buffer->resize(bytesRemaining);
     audio_input_buffer->putBytes(tmp_buffer, bytesRemaining);
-#endif
-	return TRUE;
+
+	return true;
 }
 
 
-BOOL FFmpegWmvWriter::ReceiveVideoData(BYTE* pData, DWORD len) {
-#if 1
+bool FFmpegWmvWriter::ReceiveVideoData(unsigned char* pData, unsigned long len) 
+{
 	if (oc == NULL || video_st == NULL || !have_video){
         m_pLogApi->Debug("ReceiveVideoData Failed when oc is null");
-		return FALSE;
+		return false;
 	}
 
     //m_pLogApi->Debug("ReceiveVideoData len:%d", len);
     int result = write_video_frame(m_pLogApi, oc, video_st, (char*)pData, len, input_pix_fmt);
 	if (result < 0){
         m_pLogApi->Debug("write_video_frame Failed, %d", result);
-		return FALSE;
+		return false;
 	}
-#endif
-	return TRUE;
+	return true;
 }

+ 7 - 7
Other/libwmvrecord/FFmpegWriter.h

@@ -25,13 +25,13 @@ extern "C"
 
 #endif // __cplusplus
 
-#include "SpBase.h"
 #include "ByteBuffer.h"
 
 typedef struct OutputStream_t OutputStream;
 
-struct __declspec(novtable) LogApi
+class LogApi
 {
+public:
 	virtual void Debug(const char* fmt, ...) = 0;
 };
 
@@ -56,11 +56,11 @@ private://内部成员变量
 	ByteBuffer* audio_input_buffer;
 	void Close();
 public:
-	BOOL InitWmvWriter(char* filename, int width, int height, int colorbit, int nfps,
+	bool InitWmvWriter(char* filename, int width, int height, int colorbit, int nfps,
 		int nSanplePsec, int nchannels, int nBitPerSample, int nmaxspacing, int nquality, int nOutBitRate, int iAudioType);
-	BOOL StartWrite();
-	BOOL End();
-	BOOL ReceiveAudioData(BYTE* pData, DWORD len);
-	BOOL ReceiveVideoData(BYTE* pData, DWORD len);
+	bool StartWrite();
+	bool End();
+	bool ReceiveAudioData(unsigned char* pData, unsigned long ulen);
+	bool ReceiveVideoData(unsigned char* pData, unsigned long ulen);
 };
 

+ 1 - 1
Other/libwmvrecord/WmvWriter.h

@@ -11,7 +11,7 @@
 #include "winmedia.h"
 #include <Vfw.h>
 //#include "logfile.h"
-#include "SpBase.h"
+//#include "SpBase.h"
 
 #define  _ENABLE_VBR_
 

+ 63 - 47
Other/libwmvrecord/libwmvrecord.cpp

@@ -288,6 +288,11 @@ public:
 		}
 	}
 
+	CWmvHostApi* GetHostApi()
+	{
+		return m_pHostApi;
+	}
+
 private:
 	HANDLE m_hEventWait; // CreateEvent
 	BOOL m_bStopRecord;
@@ -417,13 +422,27 @@ private:
 		}
 	}
 
+	static void __recordlog(void* user_data, const char* fmt, va_list arg)
+	{
+		libwmvrecord_impl* pRecord = (libwmvrecord_impl*)user_data;
+		if (NULL != pRecord){
+			CWmvHostApi* pHost = pRecord->GetHostApi();
+			if (NULL != pHost){
+				pHost->Debug(fmt, arg);
+			}
+		}
+	}
+
 	//开始录制视频
 	BOOL StartRecord()
 	{
 		ResetEvent(m_hEventWait);
 		m_pWriter = new FFmpegWmvWriter(this);
 		if (m_bIsAudioNsOn){
-			m_pAudioNsObj = CreateIAudioNsObj();
+			audions_callback_t t_callback = { 0 };
+			t_callback.debug = &__recordlog;
+			t_callback.user_data = this;
+			m_pAudioNsObj = CreateIAudioNsObj(&t_callback);
 		}
 		m_hRecordThread = (HANDLE)_beginthreadex(NULL, 0, VideoRecordThread, (LPVOID)this, 0, (unsigned int*)&m_nRecordthreadId);
 		return TRUE;
@@ -451,7 +470,7 @@ private:
 			int width2  = 0;
 			int height2 = 0;
 			size = m_videoqueue->GetFrameSize(width1,height1);
-			m_pHostApi->Debug("eSingleSide Record, videoqueue size: %d,  width1: %d, height1: %d.", size, width1, height1);
+			//m_pHostApi->Debug("eSingleSide Record, video queue size: %d,  width1: %d, height1: %d.", size, width1, height1);
 			if (size)
 			{
 				(width1>height1)?(nWidth=nHeight=width1):(nWidth=nHeight=height1);
@@ -472,7 +491,7 @@ private:
 				nHeight += 50;
 				size = nWidth*nHeight*3;
 			}
-			m_pHostApi->Debug("eSingleSide Record, bSubtitle: %d, size: %d, nWidth: %d, nHeight: %d.", m_SubtitleParam.bSubtitle, size, nWidth, nHeight);
+			//m_pHostApi->Debug("eSingleSide Record, bSubtitle: %d, size: %d, nWidth: %d, nHeight: %d.", m_SubtitleParam.bSubtitle, size, nWidth, nHeight);
 		}
 		else   
 		{
@@ -579,8 +598,8 @@ private:
 
 						BOOL bGetLocalvideo = FALSE;
 						bGetLocalvideo = GetVideoFrame(&tmp_frm,1,m_videoqueue);	//获取本地视频的数组形式数据
-						m_pHostApi->Debug("ePad2Agent Record have remotevideoqueue, local videoqueue format: %d, width: %d, height: %d.",
-							tmp_frm.format, tmp_frm.width, tmp_frm.height);
+						m_pHostApi->Debug("%s mode have remote video queue, local video queue format: %d, width: %d, height: %d.",
+							record_type_table[m_eRecordType], tmp_frm.format, tmp_frm.width, tmp_frm.height);
 						if (bGetLocalvideo)
 						{
 							//本地录像需要偏移量
@@ -589,8 +608,8 @@ private:
 							{
 								nOffset = (Video->height-h)/2*Video->width*3;
 							}
-							m_pHostApi->Debug("ePad2Agent Record , local videoqueue offset: %d, Videowidth: %d, Videoheight: %d, width: %d, height: %d.",
-								nOffset, Video->width, Video->height, w, h);
+							m_pHostApi->Debug("%s mode local video queue offset: %d, Video width: %d, Video height: %d, width: %d, height: %d.",
+								record_type_table[m_eRecordType], nOffset, Video->width, Video->height, w, h);
 
 							for (int i= 0;i<tmp_frm.height && i<Video->height;i++)
 							{
@@ -607,8 +626,8 @@ private:
 						tmp_frm.height = h;
 						BOOL bGetRemotevideo = FALSE;
 						bGetRemotevideo = GetVideoFrame(&tmp_frm,1,m_remotevideoqueue);
-						m_pHostApi->Debug("ePad2Agent Record have remotevideoqueue, remotevideoqueue format: %d, width: %d, height: %d.",
-							tmp_frm.format, tmp_frm.width, tmp_frm.height);
+						m_pHostApi->Debug("%s mode have remote video queue, remote video queue format: %d, width: %d, height: %d.",
+							record_type_table[m_eRecordType], tmp_frm.format, tmp_frm.width, tmp_frm.height);
 						if (bGetRemotevideo)
 						{
 							for (int i= 0;i<tmp_frm.height&&i<Video->height;i++)
@@ -637,8 +656,8 @@ private:
 				if (!m_SubtitleParam.bSubtitle || !m_SubtitleParam.bSubtitleSection)
 				{
 					bool result =  m_videoqueue->GetVideo(Video,flags);
-					m_pHostApi->Debug("eSingleSide Record No bSubtitle, local videoqueue format: %d, width: %d, height: %d.",
-						Video->format, Video->width, Video->height);
+					m_pHostApi->Debug("%s mode No bSubtitle, local video queue format: %d, width: %d, height: %d.",
+						record_type_table[m_eRecordType], Video->format, Video->width, Video->height);
 					return result;
 				}
 				else
@@ -651,11 +670,11 @@ private:
 					videoq_frame*tmp_frm = new videoq_frame;
 					//下移30
 					tmp_frm->data = Video->data+ Video->width*30*3;
-					m_pHostApi->Debug("eSingleSide Record , local videoqueue offset: %d, Videowidth: %d, width: %d, height: %d.",
-						Video->width * 30 * 3, Video->width, width, height);
+					m_pHostApi->Debug("%s mode local video queue offset: %d, Video width: %d, width: %d, height: %d.",
+						record_type_table[m_eRecordType], Video->width * 30 * 3, Video->width, width, height);
 					bRslt = m_videoqueue->GetVideo(tmp_frm, flags);
-					m_pHostApi->Debug("eSingleSide Record , local videoqueue format: %d, width: %d, height: %d.",
-						tmp_frm->format, tmp_frm->width, tmp_frm->height);
+					m_pHostApi->Debug("%s mode local video queue format: %d, width: %d, height: %d.",
+						record_type_table[m_eRecordType], tmp_frm->format, tmp_frm->width, tmp_frm->height);
 					if (!bRslt)
 					{
 						delete tmp_frm;
@@ -696,12 +715,12 @@ private:
 					videoq_frame*tmp_frm = new videoq_frame;
 					//if (!m_SubtitleParam.bSubtitle || !m_SubtitleParam.bSubtitleSection)
 					tmp_frm->data = localtmp_frm.data[0]+ width*(width-height)/2*3;    //在画布中加上偏移量
-					m_pHostApi->Debug("eStand2Agent Record , local videoqueue offset: %d, width: %d, height: %d.",
-						width* (width - height) / 2 * 3, width, height);
+					m_pHostApi->Debug("%s mode local video queue offset: %d, width: %d, height: %d.",
+						record_type_table[m_eRecordType], width* (width - height) / 2 * 3, width, height);
 					//横向摄像头拼接
 					bRslt = m_videoqueue->GetVideo(tmp_frm, flags);
-					m_pHostApi->Debug("eStand2Agent Record , local videoqueue format: %d, width: %d, height: %d.",
-						tmp_frm->format, tmp_frm->width, tmp_frm->height);
+					m_pHostApi->Debug("%s mode local video queue format: %d, width: %d, height: %d.",
+						record_type_table[m_eRecordType], tmp_frm->format, tmp_frm->width, tmp_frm->height);
 					if (!bRslt)
 					{
 						delete tmp_frm;
@@ -714,12 +733,12 @@ private:
 				{
 					videoq_frame*tmp_frm = new videoq_frame;
 					tmp_frm->data = localtmp_frm.data[0] + (width-height)/2*3;  //在画布中加上偏移量
-					m_pHostApi->Debug("eStand2Agent Record , local videoqueue2 offset: %d, width: %d, height: %d.",
-						(width - height) / 2 * 3, width, height);
+					m_pHostApi->Debug("%s mode local videoqueue2 offset: %d, width: %d, height: %d.",
+						record_type_table[m_eRecordType], (width - height) / 2 * 3, width, height);
 					//竖向摄像头图像,拼接
 					bRslt = m_videoqueue2->GetVideo3(tmp_frm, flags);
-					m_pHostApi->Debug("eStand2Agent Record , local videoqueue2 format: %d, width: %d, height: %d.",
-						tmp_frm->format, tmp_frm->width, tmp_frm->height);
+					m_pHostApi->Debug("%s mode local videoqueue2 format: %d, width: %d, height: %d.",
+						record_type_table[m_eRecordType], tmp_frm->format, tmp_frm->width, tmp_frm->height);
 					if (!bRslt)
 					{
 						delete tmp_frm;	
@@ -767,8 +786,8 @@ private:
 					tmp_frm.height = h;
 					BOOL bGetRemotevideo = FALSE;
 					bGetRemotevideo = GetVideoFrame(&tmp_frm,1,m_remotevideoqueue);
-					m_pHostApi->Debug("eStand2Agent Record , remotevideoqueue format: %d, width: %d, height: %d.",
-						tmp_frm.format, tmp_frm.width, tmp_frm.height);
+					m_pHostApi->Debug("%s mode remote video queue format: %d, width: %d, height: %d.",
+						record_type_table[m_eRecordType], tmp_frm.format, tmp_frm.width, tmp_frm.height);
 					if (bGetRemotevideo)
 					{
 						for (int i= 0;i<tmp_frm.height&&i<Video->height;i++)
@@ -802,18 +821,18 @@ private:
 					if (!m_SubtitleParam.bSubtitle || !m_SubtitleParam.bSubtitleSection)
 					{
 						tmp_frm->data = Video->data+ Video->width*(width-height)/2*3;
-						m_pHostApi->Debug("eStand2Agent Record no remotevideoqueue, no bSubtitle offset: %d, width: %d, height: %d.",
-							Video->width* (width - height) / 2 * 3, width, height);
+						m_pHostApi->Debug("%s mode no remote video queue, no bSubtitle offset: %d, width: %d, height: %d.",
+							record_type_table[m_eRecordType], Video->width* (width - height) / 2 * 3, width, height);
 					}
 					else
 					{
 						tmp_frm->data = Video->data+ Video->width*((width-height)/2+30)*3;
-						m_pHostApi->Debug("eStand2Agent Record no remotevideoqueue, have bSubtitle offset: %d, width: %d, height: %d.",
-							Video->width* ((width - height) / 2 + 30) * 3, width, height);
+						m_pHostApi->Debug("%s mode no remote video queue, have bSubtitle offset: %d, width: %d, height: %d.",
+							record_type_table[m_eRecordType], Video->width* ((width - height) / 2 + 30) * 3, width, height);
 					}
 					bRslt = m_videoqueue->GetVideo(tmp_frm, flags);
-					m_pHostApi->Debug("eStand2Agent Record no remotevideoqueue, local videoqueue format: %d, width: %d, height: %d.",
-						tmp_frm->format, tmp_frm->width, tmp_frm->height);
+					m_pHostApi->Debug("%s mode no remote video queue, local video queue format: %d, width: %d, height: %d.",
+						record_type_table[m_eRecordType], tmp_frm->format, tmp_frm->width, tmp_frm->height);
 					if (!bRslt)
 					{
 						delete tmp_frm;
@@ -828,19 +847,19 @@ private:
 					if (!m_SubtitleParam.bSubtitle || !m_SubtitleParam.bSubtitleSection)
 					{
 						tmp_frm->data = Video->data + (width-height)/2*3;
-						m_pHostApi->Debug("eStand2Agent Record no remotevideoqueue, no bSubtitle offset: %d, width: %d, height: %d.",
-							(width - height) / 2 * 3, width, height);
+						m_pHostApi->Debug("%s mode no remote video queue, no bSubtitle offset: %d, width: %d, height: %d.",
+							record_type_table[m_eRecordType], (width - height) / 2 * 3, width, height);
 					}
 					else
 					{
 						tmp_frm->data = Video->data + (Video->width*30+(width-height)/2)*3;
-						m_pHostApi->Debug("eStand2Agent Record no remotevideoqueue, have bSubtitle offset: %d, width: %d, height: %d.",
-							(Video->width * 30 + (width - height) / 2) * 3, width, height);
+						m_pHostApi->Debug("%s mode no remote video queue, have bSubtitle offset: %d, width: %d, height: %d.",
+							record_type_table[m_eRecordType], (Video->width * 30 + (width - height) / 2) * 3, width, height);
 					}
 					//横向摄像头图像,拼接
 					bRslt = m_videoqueue2->GetVideo3(tmp_frm, flags);
-					m_pHostApi->Debug("eStand2Agent Record no remotevideoqueue, local videoqueue2 format: %d, width: %d, height: %d.",
-						tmp_frm->format, tmp_frm->width, tmp_frm->height);
+					m_pHostApi->Debug("%s mode no remote video queue, local videoqueue2 format: %d, width: %d, height: %d.",
+						record_type_table[m_eRecordType], tmp_frm->format, tmp_frm->width, tmp_frm->height);
 					if (!bRslt)
 					{
 						delete tmp_frm;	
@@ -1076,7 +1095,6 @@ private:
 	}
 
 
-	//edit by ly@2018/06/05
 	int VideoRecord()
 	{
 		BOOL bResult;
@@ -1150,16 +1168,14 @@ private:
 
 		int nVideoSizeFailedTimes = 0, nAudioSizeFailedTimes = 0; // add by ly 20160713
 
-		if (m_bWholeSection || !m_bSessionManage)
-		{
+		if (m_bWholeSection || !m_bSessionManage){
 			sprintf_s(m_WmvFileName,MAX_PATH,"%s%s_%d.wmv",m_PathName,m_FileName,WmvFileSerialNum);
 		}
-		else
-		{
+		else{
 			sprintf_s(m_WmvFileName,MAX_PATH,"%s%s_%d_end.wmv",m_PathName,m_FileName,WmvFileSerialNum);
 		}
 		m_pHostApi->Debug("m_WmvFileName = %s",m_WmvFileName);
-		//每次启动录像重新初始化,chh,20170906
+
 		m_bCloseVideo = FALSE;
 		m_bReNameVideo = FALSE;
 
@@ -1178,7 +1194,7 @@ private:
 							m_pHostApi->OnRecordFailed(true);
 							continue;
 						}
-						m_pHostApi->Debug("Get Video FrameSize,record type is  %s.",record_type_table[m_eRecordType]);
+						m_pHostApi->Debug("Get Video FrameSize,record type is %s.",record_type_table[m_eRecordType]);
 						nVideoFrameSize = GetVideoFrameSizeNew(nWidth,nHeight);
 						if(nVideoFrameSize <= 0)
 						{
@@ -1274,11 +1290,11 @@ private:
 					size_t uOutPutBitRate = GetAudioOutPutBitRate(audio->samplespersec,audio->nchannels,m_eAudioType);
 					if (m_bIsAudioNsOn && NULL != m_pAudioNsObj){
 						if (m_pAudioNsObj->SetNsParams(audio->samplespersec, CAPTURE_FRAME_TIME, m_iNsPolicy)){
-							Dbg("Ns audio set params failed!");
+							m_pHostApi->Debug("Ns audio set params failed!");
 						}						
 					}
-					m_pHostApi->Debug("InitWmvWriter samplespersec=%d,audioOutChannels=%d,audioOutBitRate=%d bps.",audio->samplespersec,audio->nchannels,uOutPutBitRate);
-					m_pHostApi->Debug("InitWmvWriter Width=%d,Height=%d,Fps=%d .", nWidth, nHeight, m_nFps);
+					m_pHostApi->Debug("InitWmvWriter audio param samplespersec=%d,audioOutChannels=%d,audioOutBitRate=%d bps.",audio->samplespersec,audio->nchannels,uOutPutBitRate);
+					m_pHostApi->Debug("InitWmvWriter video param Width=%d,Height=%d,Fps=%d.", nWidth, nHeight, m_nFps);
 					bResult = m_pWriter->InitWmvWriter(m_WmvFileName,nWidth,nHeight,24,m_nFps,audio->samplespersec,
 							audio->nchannels,audio->bitspersample,6,m_videoquality,uOutPutBitRate, (int)m_eAudioType);
 					delete audio->data;

+ 9 - 2
Plugins/MediaDevDetectBasePulse/mainform.cpp

@@ -96,7 +96,12 @@ QList<AudioDeviceInfo> MainForm::availableDevices(DevMode mode)
     return devList;
 }
 
-MainForm::MainForm(QWidget *parent) :
+static void __audiomgrlog(void* user_data, const char* fmt, va_list arg)
+{
+	
+}
+
+MainForm::MainForm(QWidget *parent):
     QWidget(parent),
     ui(new Ui::MainForm), deviceInfoLib(nullptr), rootFilePath(), m_pAudioMgr(NULL)
 {
@@ -132,7 +137,9 @@ bool MainForm::loadExportFunctions()
     qDebug() << "Enter loadExportFunctions" << " " << libAbsolutePath;
 
     if (m_pAudioMgr == NULL) {
-        m_pAudioMgr = CreateAudioMgrObj(NULL);
+		audiomgr_callback_t t_callback = { 0 };
+		t_callback.debug = &__audiomgrlog;
+        m_pAudioMgr = CreateAudioMgrObj(&t_callback);
         if (m_pAudioMgr == NULL) {
             qDebug() << "Initialize AudioMgr failed";
             return false;