1280 lines
38 KiB
C++
1280 lines
38 KiB
C++
/*
|
|
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
#include "ChannelDlg.h"
|
|
#include "VideoSize.h"
|
|
#include "CaptureDevicePool.h"
|
|
#include "ChannelPool.h"
|
|
|
|
#include <Mmsystem.h>
|
|
#include <dbt.h>
|
|
|
|
|
|
#include "assert.h"
|
|
|
|
|
|
#include <process.h> // threads.
|
|
|
|
#if defined _WIN32
|
|
#define SLEEP_10_SEC ::Sleep(10000)
|
|
#define GET_TIME_IN_MS timeGetTime
|
|
#endif
|
|
|
|
|
|
// Hack to convert char to TCHAR, using two buffers to be able to
|
|
// call twice in the same statement
|
|
TCHAR convertTemp1[256] = {0};
|
|
TCHAR convertTemp2[256] = {0};
|
|
bool convertBufferSwitch(false);
|
|
TCHAR* CharToTchar(const char* str, int len)
|
|
{
|
|
#ifdef _UNICODE
|
|
TCHAR* temp = convertBufferSwitch ? convertTemp1 : convertTemp2;
|
|
convertBufferSwitch = !convertBufferSwitch;
|
|
memset(temp, 0, sizeof(convertTemp1));
|
|
MultiByteToWideChar(CP_UTF8, 0, str, len, temp, 256);
|
|
return temp;
|
|
#else
|
|
return str;
|
|
#endif
|
|
}
|
|
|
|
// Hack to convert TCHAR to char
|
|
char convertTemp3[256] = {0};
|
|
char* TcharToChar(TCHAR* str, int len)
|
|
{
|
|
#ifdef _UNICODE
|
|
memset(convertTemp3, 0, sizeof(convertTemp3));
|
|
WideCharToMultiByte(CP_UTF8, 0, str, len, convertTemp3, 256, 0, 0);
|
|
return convertTemp3;
|
|
#else
|
|
return str;
|
|
#endif
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CDXChannelDlg dialog
|
|
|
|
CDXChannelDlg::CDXChannelDlg(VideoEngine* videoEngine,
|
|
CaptureDevicePool& captureDevicePool,
|
|
ChannelPool& channelPool,
|
|
void* voiceEngine
|
|
,CWnd* pParent,CDXChannelDlgObserver* observer,
|
|
int parentChannel/*=-1*/)
|
|
: CDialog(CDXChannelDlg::IDD, pParent),
|
|
_canAddLog(true),
|
|
_dialogObserver(observer),
|
|
_videoEngine(videoEngine),
|
|
_captureDevicePool(captureDevicePool),
|
|
_channelPool(channelPool),
|
|
_parentChannel(parentChannel),
|
|
#ifndef NO_VOICE_ENGINE
|
|
_voiceEngine((VoiceEngine*) voiceEngine),
|
|
#endif
|
|
_callbackEvent(::CreateEvent( NULL, FALSE, FALSE, NULL)),
|
|
_externalTransport(NULL)
|
|
{
|
|
strcpy(_logMsg,"");
|
|
_channelId = -1;
|
|
_audioChannel=-1;
|
|
_captureId=-1;
|
|
|
|
//_transport = NULL;
|
|
|
|
|
|
//{{AFX_DATA_INIT(CDXChannelDlg)
|
|
//}}AFX_DATA_INIT
|
|
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
|
|
|
|
InitializeCriticalSection(&_critCallback);
|
|
unsigned int threadID;
|
|
_callbackThread=(HANDLE)_beginthreadex(NULL,1024*1024,CallbackThread,(void*)this,0, &threadID);
|
|
|
|
|
|
}
|
|
|
|
void CDXChannelDlg::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CDXChannelDlg)
|
|
DDX_Control(pDX, IDC_DEVICE, m_ctrlDevice);
|
|
DDX_Control(pDX, IDC_CODEC_LIST, m_ctrlCodec);
|
|
DDX_Control(pDX, IDC_CAPTURE, m_ctrlLiveRemoteVideo);
|
|
DDX_Control(pDX, IDC_LIVEVIDEO, m_ctrlLiveVideo);
|
|
DDX_Control(pDX, IDC_LOCAL_PORT1, m_localPort1);
|
|
DDX_Control(pDX, IDC_REMOTE_PORT1, m_remotePort1);
|
|
DDX_Control(pDX, IDC_IPADDRESS1, m_remoteIp1);
|
|
DDX_Control(pDX, IDC_CODEC_SIZE, m_ctrlCodecSize);
|
|
DDX_Control(pDX, IDC_RTCPMODE, m_ctrlRtcpMode);
|
|
DDX_Control(pDX, IDC_PACKETBURST, m_ctrlPacketBurst);
|
|
DDX_Control(pDX, IDC_BITRATE, m_ctrlBitrate);
|
|
DDX_Control(pDX, IDC_MIN_FRAME_RATE, m_ctrlMinFrameRate);
|
|
DDX_Control(pDX, IDC_TMMBR,m_cbTmmbr);
|
|
DDX_Control(pDX, IDC_EXTTRANSPORT,m_cbExternalTransport);
|
|
DDX_Control(pDX, IDC_PACKETLOSS,m_ctrlPacketLoss);
|
|
DDX_Control(pDX, IDC_DELAY,m_ctrlDelay);
|
|
DDX_Control(pDX, IDC_FREEZELOG,m_cbFreezeLog);
|
|
DDX_Control(pDX,IDC_INFORMATION,m_ctrlInfo);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
// ON_WM_SYSKEYDOWN ALT+key
|
|
|
|
BEGIN_MESSAGE_MAP(CDXChannelDlg, CDialog)
|
|
//{{AFX_MSG_MAP(CDXChannelDlg)
|
|
ON_WM_SYSCOMMAND()
|
|
ON_WM_RBUTTONUP()
|
|
//ON_WM_DEVICECHANGE()
|
|
ON_WM_PAINT()
|
|
ON_WM_QUERYDRAGICON()
|
|
ON_BN_CLICKED(IDC_STARTSEND, OnStartSend)
|
|
ON_BN_CLICKED(IDC_STOPSend, OnStopSend)
|
|
//ON_WM_TIMER()
|
|
ON_WM_DESTROY()
|
|
//}}AFX_MSG_MAP
|
|
ON_CBN_SELCHANGE(IDC_CODEC_LIST, OnCbnSelchangeCodecList)
|
|
ON_CBN_SELCHANGE(IDC_DEVICE, OnCbnSelchangeDevice)
|
|
ON_CBN_SELCHANGE(IDC_CODEC_SIZE, OnCbnSelchangeSize)
|
|
ON_CBN_SELCHANGE(IDC_BITRATE, OnCbnSelchangeBitrate)
|
|
//ON_MESSAGE(WM_DISPLAYCHANGE, OnDisplayChange)
|
|
ON_CBN_SELCHANGE(IDC_MIN_FRAME_RATE, OnCbnSelchangeMinFrameRate)
|
|
ON_BN_CLICKED(IDC_STARTLISTEN, OnBnClickedStartlisten)
|
|
ON_BN_CLICKED(IDC_STOPLISTEN, OnBnClickedStoplisten)
|
|
ON_BN_CLICKED(IDC_TMMBR, &CDXChannelDlg::OnBnClickedTmmbr)
|
|
ON_CBN_SELCHANGE(IDC_RTCPMODE, &CDXChannelDlg::OnCbnSelchangeRtcpmode)
|
|
ON_BN_CLICKED(IDC_PROT_NACK, &CDXChannelDlg::OnBnClickedProtNack)
|
|
ON_BN_CLICKED(IDC_PROT_NONE, &CDXChannelDlg::OnBnClickedProtNone)
|
|
ON_BN_CLICKED(IDC_PROT_FEC, &CDXChannelDlg::OnBnClickedProtFec)
|
|
ON_BN_CLICKED(IDC_FREEZELOG, &CDXChannelDlg::OnBnClickedFreezelog)
|
|
ON_BN_CLICKED(IDC_CAMERACAP, &CDXChannelDlg::OnBnClickedCameracap)
|
|
ON_BN_CLICKED(IDC_EXTTRANSPORT, &CDXChannelDlg::OnBnClickedExttransport)
|
|
ON_CBN_SELCHANGE(IDC_PACKETLOSS, &CDXChannelDlg::OnCbnSelchangePacketloss)
|
|
ON_CBN_SELCHANGE(IDC_DELAY, &CDXChannelDlg::OnCbnSelchangeDelay)
|
|
ON_BN_CLICKED(IDC_BTN_RECORD_INCOMING, &CDXChannelDlg::OnBnClickedBtnRecordIncoming)
|
|
ON_BN_CLICKED(IDC_BTN_RECORD_OUTGOING, &CDXChannelDlg::OnBnClickedBtnRecordOutgoing)
|
|
ON_BN_CLICKED(IDC_BTN_CREATE_SLAVE, &CDXChannelDlg::OnBnClickedBtnCreateSlave)
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CDXChannelDlg message handlers
|
|
|
|
|
|
BOOL CDXChannelDlg::OnInitDialog()
|
|
{
|
|
CDialog::OnInitDialog();
|
|
|
|
// Set the icon for this dialog. The framework does this automatically
|
|
// when the application's main window is not a dialog
|
|
SetIcon(m_hIcon, TRUE); // Set big icon
|
|
SetIcon(m_hIcon, FALSE); // Set small icon
|
|
|
|
|
|
::SendMessage(m_ctrlMinFrameRate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("5"));
|
|
::SendMessage(m_ctrlMinFrameRate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("6"));
|
|
::SendMessage(m_ctrlMinFrameRate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("7"));
|
|
::SendMessage(m_ctrlMinFrameRate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("8"));
|
|
::SendMessage(m_ctrlMinFrameRate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("9"));
|
|
::SendMessage(m_ctrlMinFrameRate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("10"));
|
|
::SendMessage(m_ctrlMinFrameRate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("11"));
|
|
::SendMessage(m_ctrlMinFrameRate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("12"));
|
|
::SendMessage(m_ctrlMinFrameRate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("13"));
|
|
::SendMessage(m_ctrlMinFrameRate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("14"));
|
|
::SendMessage(m_ctrlMinFrameRate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("15"));
|
|
::SendMessage(m_ctrlMinFrameRate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("16"));
|
|
::SendMessage(m_ctrlMinFrameRate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("17"));
|
|
::SendMessage(m_ctrlMinFrameRate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("18"));
|
|
::SendMessage(m_ctrlMinFrameRate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("19"));
|
|
::SendMessage(m_ctrlMinFrameRate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("20"));
|
|
::SendMessage(m_ctrlMinFrameRate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("21"));
|
|
::SendMessage(m_ctrlMinFrameRate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("22"));
|
|
::SendMessage(m_ctrlMinFrameRate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("23"));
|
|
::SendMessage(m_ctrlMinFrameRate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("24"));
|
|
::SendMessage(m_ctrlMinFrameRate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("25"));
|
|
::SendMessage(m_ctrlMinFrameRate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("26"));
|
|
::SendMessage(m_ctrlMinFrameRate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("27"));
|
|
::SendMessage(m_ctrlMinFrameRate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("28"));
|
|
::SendMessage(m_ctrlMinFrameRate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("29"));
|
|
::SendMessage(m_ctrlMinFrameRate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("30"));
|
|
m_ctrlMinFrameRate.SetCurSel(25);
|
|
|
|
// Codec sizes
|
|
for(VideoSize i=VideoSize::UNDEFINED;i<VideoSize::NUMBER_OF_VIDEO_SIZE;i=VideoSize(i+1))
|
|
{
|
|
char sizeStr[64];
|
|
int width=0;
|
|
int height=0;
|
|
GetWidthHeight(i,width,height);
|
|
sprintf(sizeStr,"%d x %d",width,height);
|
|
::SendMessage(m_ctrlCodecSize.m_hWnd, CB_ADDSTRING, 0,(LPARAM) CharToTchar(sizeStr,-1));
|
|
}
|
|
m_ctrlCodecSize.SetCurSel(8);
|
|
|
|
// RTCP mode
|
|
/*
|
|
kRtcpNone = 0,
|
|
kRtcpCompound_RFC4585 = 1,
|
|
kRtcpNonCompound_RFC5506 = 2 */
|
|
::SendMessage(m_ctrlRtcpMode.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("RTCP_NONE"));
|
|
::SendMessage(m_ctrlRtcpMode.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("RTCP_COMPOUND_RFC4585"));
|
|
::SendMessage(m_ctrlRtcpMode.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("RTCP_NON_COMPOUND_RFC5506"));
|
|
m_ctrlRtcpMode.SetCurSel(2);
|
|
|
|
|
|
//Packet Burst
|
|
::SendMessage(m_ctrlPacketBurst.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("0"));
|
|
::SendMessage(m_ctrlPacketBurst.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("10"));
|
|
::SendMessage(m_ctrlPacketBurst.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("20"));
|
|
::SendMessage(m_ctrlPacketBurst.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("30"));
|
|
m_ctrlPacketBurst.SetCurSel(0);
|
|
|
|
|
|
//Send Bitrate
|
|
::SendMessage(m_ctrlBitrate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("50"));
|
|
::SendMessage(m_ctrlBitrate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("100"));
|
|
::SendMessage(m_ctrlBitrate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("200"));
|
|
::SendMessage(m_ctrlBitrate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("300"));
|
|
::SendMessage(m_ctrlBitrate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("500"));
|
|
::SendMessage(m_ctrlBitrate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("1000"));
|
|
::SendMessage(m_ctrlBitrate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("2000"));
|
|
::SendMessage(m_ctrlBitrate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("3000"));
|
|
::SendMessage(m_ctrlBitrate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("4000"));
|
|
::SendMessage(m_ctrlBitrate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("5000"));
|
|
::SendMessage(m_ctrlBitrate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("6000"));
|
|
::SendMessage(m_ctrlBitrate.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("7000"));
|
|
|
|
m_ctrlBitrate.SetCurSel(3);
|
|
|
|
// External transport packet loss
|
|
::SendMessage(m_ctrlPacketLoss.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("0"));
|
|
::SendMessage(m_ctrlPacketLoss.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("2"));
|
|
::SendMessage(m_ctrlPacketLoss.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("4"));
|
|
::SendMessage(m_ctrlPacketLoss.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("6"));
|
|
::SendMessage(m_ctrlPacketLoss.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("8"));
|
|
::SendMessage(m_ctrlPacketLoss.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("10"));
|
|
::SendMessage(m_ctrlPacketLoss.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("12"));
|
|
::SendMessage(m_ctrlPacketLoss.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("14"));
|
|
::SendMessage(m_ctrlPacketLoss.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("16"));
|
|
::SendMessage(m_ctrlPacketLoss.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("18"));
|
|
::SendMessage(m_ctrlPacketLoss.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("20"));
|
|
m_ctrlPacketLoss.SetCurSel(0);
|
|
|
|
// External transport delay
|
|
::SendMessage(m_ctrlDelay.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("0"));
|
|
::SendMessage(m_ctrlDelay.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("30"));
|
|
::SendMessage(m_ctrlDelay.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("60"));
|
|
::SendMessage(m_ctrlDelay.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("90"));
|
|
::SendMessage(m_ctrlDelay.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("120"));
|
|
::SendMessage(m_ctrlDelay.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("150"));
|
|
::SendMessage(m_ctrlDelay.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("180"));
|
|
::SendMessage(m_ctrlDelay.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("210"));
|
|
m_ctrlDelay.SetCurSel(0);
|
|
|
|
|
|
_vieBase=ViEBase::GetInterface(_videoEngine);
|
|
TEST_MUSTPASS(_vieBase==0,-5);
|
|
|
|
_vieCapture=ViECapture::GetInterface(_videoEngine);
|
|
TEST_MUSTPASS(_vieCapture==0,-5);
|
|
|
|
_vieRTPRTCP=ViERTP_RTCP::GetInterface(_videoEngine);
|
|
TEST_MUSTPASS(_vieRTPRTCP==0,-5);
|
|
|
|
_vieRender=ViERender::GetInterface(_videoEngine);
|
|
TEST_MUSTPASS(_vieRender==0,-5);
|
|
|
|
_vieCodec=ViECodec::GetInterface(_videoEngine);
|
|
TEST_MUSTPASS(_vieCodec==0,-5);
|
|
_vieNetwork=ViENetwork::GetInterface(_videoEngine);
|
|
TEST_MUSTPASS(_vieNetwork==0,-5);
|
|
|
|
_vieFile=ViEFile::GetInterface(_videoEngine);
|
|
TEST_MUSTPASS(_vieFile==0,-5);
|
|
|
|
#ifndef NO_VOICE_ENGINE
|
|
|
|
_veBase = VoEBase::GetInterface(_voiceEngine);
|
|
_veNetwork = VoENetwork::GetInterface(_voiceEngine);
|
|
_veCodec = VoECodec::GetInterface(_voiceEngine);
|
|
_veRTCP = VoERTP_RTCP::GetInterface(_voiceEngine);
|
|
TEST_MUSTPASS(_vieBase->SetVoiceEngine(_voiceEngine),-5);
|
|
#endif
|
|
|
|
int err = 0;
|
|
|
|
char str[64];
|
|
bool found = false;
|
|
|
|
|
|
int captureIdx = 0;
|
|
while (-1 !=_vieCapture->GetCaptureDevice(captureIdx,str,sizeof(str),NULL,0))
|
|
{
|
|
char* tmp = strstr(str,"(VFW)");
|
|
if (!tmp)
|
|
{
|
|
::SendMessage(m_ctrlDevice.m_hWnd, CB_ADDSTRING, 0,(LPARAM)CharToTchar(str,-1));
|
|
found = true;
|
|
}
|
|
captureIdx++;
|
|
memset(str, 0, 64);
|
|
}
|
|
WIN32_FIND_DATA FindFileData;
|
|
HANDLE hFind;
|
|
//char fileSearch[256];
|
|
//strcpy(fileSearch,_T("*.avi"));
|
|
hFind = FindFirstFile(_T("*.avi"), &FindFileData);
|
|
if (hFind != INVALID_HANDLE_VALUE)
|
|
{
|
|
|
|
::SendMessage(m_ctrlDevice.m_hWnd, CB_ADDSTRING, 0,(LPARAM)(FindFileData.cFileName));
|
|
while(FindNextFile(hFind,&FindFileData))
|
|
{
|
|
::SendMessage(m_ctrlDevice.m_hWnd, CB_ADDSTRING, 0,(LPARAM)(FindFileData.cFileName));
|
|
}
|
|
FindClose(hFind);
|
|
}
|
|
|
|
|
|
|
|
::SendMessage(m_ctrlDevice.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("Conference"));
|
|
::SendMessage(m_ctrlDevice.m_hWnd, CB_ADDSTRING, 0,(LPARAM)_T("None"));
|
|
|
|
if (!found)
|
|
{
|
|
strncpy(str,"N/A",64);
|
|
::SendMessage(m_ctrlDevice.m_hWnd, CB_ADDSTRING, 0,(LPARAM)CharToTchar(str,-1));
|
|
}
|
|
m_ctrlDevice.SetCurSel(0);
|
|
|
|
//Codecs
|
|
int numOfCodecs = _vieCodec->NumberOfCodecs();
|
|
for(int i=0; i<numOfCodecs;++i)
|
|
{
|
|
VideoCodec codec;
|
|
if(-1 !=_vieCodec->GetCodec(i,codec))
|
|
{
|
|
::SendMessage(m_ctrlCodec.m_hWnd, CB_ADDSTRING, 0,(LPARAM)CharToTchar(codec.plName,-1));
|
|
}
|
|
}
|
|
m_ctrlCodec.SetCurSel(0);
|
|
|
|
#ifndef NO_VOICE_ENGINE
|
|
CodecInst voiceCodec;
|
|
int numOfVeCodecs = _veCodec->NumOfCodecs();
|
|
for(int i=0; i<numOfVeCodecs;++i)
|
|
{
|
|
if(_veCodec->GetCodec(i,voiceCodec)!=-1)
|
|
{
|
|
if(strncmp(voiceCodec.plname,"ISAC",4)==0)
|
|
break;
|
|
|
|
|
|
}
|
|
}
|
|
|
|
_audioChannel = _veBase->CreateChannel();
|
|
|
|
|
|
TEST_MUSTPASS(_veRTCP->SetRTCPStatus(_audioChannel, true),-5);
|
|
TEST_MUSTPASS(_veCodec->SetSendCodec(_audioChannel, voiceCodec),-5);
|
|
TEST_MUSTPASS(_veBase->StartPlayout(_audioChannel),-5);
|
|
|
|
#endif //NO_VOICE_ENGINE
|
|
|
|
if(_parentChannel==-1)
|
|
{
|
|
TEST_MUSTPASS(_vieBase->CreateChannel(_channelId),-5);
|
|
}
|
|
else // This is a slave channel
|
|
{
|
|
TEST_MUSTPASS(_vieBase->CreateChannel(_channelId,_parentChannel),-5);
|
|
}
|
|
#ifndef NO_VOICE_ENGINE
|
|
TEST_MUSTPASS(_vieBase->ConnectAudioChannel(_channelId,_audioChannel),-5);
|
|
#endif
|
|
|
|
_channelPool.AddChannel(_channelId);
|
|
|
|
//Set Receive codec
|
|
{
|
|
VideoCodec codec;
|
|
int numOfCodecs = _vieCodec->NumberOfCodecs();;
|
|
for(int i=0; i<numOfCodecs;++i)
|
|
{
|
|
if(-1 !=_vieCodec->GetCodec(i,codec))
|
|
{
|
|
if(codec.codecType == webrtc::kVideoCodecVP8)
|
|
{
|
|
codec.codecSpecific.VP8.feedbackModeOn = true;
|
|
codec.codecSpecific.VP8.pictureLossIndicationOn = true;
|
|
}
|
|
TEST_MUSTPASS(_vieCodec->SetReceiveCodec(_channelId,codec),-5);
|
|
}
|
|
}
|
|
}
|
|
|
|
//TMMBR
|
|
m_cbTmmbr.SetCheck(BST_CHECKED);
|
|
OnBnClickedTmmbr();
|
|
|
|
//Packet Burst
|
|
m_ctrlPacketBurst.SetCurSel(0);
|
|
|
|
|
|
//Protection method none
|
|
CButton *opProtection = (CButton *) GetDlgItem(IDC_PROT_NONE);
|
|
opProtection->SetCheck(BST_CHECKED);
|
|
OnBnClickedProtNone();
|
|
|
|
|
|
// Configure the renderer
|
|
ConfigureRender();
|
|
|
|
TEST_MUSTPASS(_vieCodec->RegisterEncoderObserver(_channelId,*this),kViECodecObserverAlreadyRegistered);
|
|
TEST_MUSTPASS(_vieCodec->RegisterDecoderObserver(_channelId,*this),-5);
|
|
|
|
TEST_MUSTPASS(_vieBase->RegisterObserver(*this),kViEBaseObserverAlreadyRegistered);
|
|
|
|
|
|
|
|
|
|
//Set captions based on channel id
|
|
m_remoteIp1.SetAddress(127,0,0,1);
|
|
CString port;
|
|
port.AppendFormat(_T("%d"),11111+_channelId*4);
|
|
m_remotePort1.SetWindowText(port);
|
|
m_localPort1.SetWindowText(port);
|
|
|
|
CString title;
|
|
this->GetWindowText(title);
|
|
if(_parentChannel==-1)
|
|
{
|
|
title.AppendFormat(_T("%s - channel %d"),title,_channelId);
|
|
}
|
|
else
|
|
{
|
|
title.AppendFormat(_T("%s - slave channel %d - parent %d"),title,_channelId,_parentChannel);
|
|
}
|
|
this->SetWindowText(title);
|
|
|
|
if(_parentChannel!=-1)
|
|
m_ctrlDevice.EnableWindow(FALSE); //Prevent from changing capture device
|
|
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
}
|
|
|
|
|
|
|
|
void CDXChannelDlg::OnTimer(UINT nIDEvent)
|
|
{
|
|
CDialog::OnTimer(nIDEvent);
|
|
}
|
|
|
|
void CDXChannelDlg::SetSendCodec()
|
|
{
|
|
// Get the codec stucture
|
|
int codecSel= m_ctrlCodec.GetCurSel();
|
|
VideoCodec codec;
|
|
TEST_MUSTPASS(_vieCodec->GetCodec(codecSel,codec),-5);
|
|
|
|
|
|
// Set Codec Size
|
|
VideoSize sizeSel=VideoSize(m_ctrlCodecSize.GetCurSel());
|
|
int width, height;
|
|
GetWidthHeight(sizeSel, width, height);
|
|
codec.width=width;
|
|
codec.height=height;
|
|
|
|
//Set the codec bitrate
|
|
CString bitrateStr;
|
|
m_ctrlBitrate.GetLBText(m_ctrlBitrate.GetCurSel(), bitrateStr);
|
|
int bitrate = _ttoi(bitrateStr.GetBuffer(0));
|
|
if(codec.codecType!=kVideoCodecI420)
|
|
{
|
|
codec.startBitrate=bitrate;
|
|
codec.maxBitrate=bitrate*4;
|
|
}
|
|
|
|
|
|
//Set the codec frame rate
|
|
codec.maxFramerate = m_ctrlMinFrameRate.GetCurSel() +5;
|
|
|
|
if(strncmp(codec.plName, "VP8", 5) == 0)
|
|
{
|
|
codec.codecSpecific.VP8.feedbackModeOn = true;
|
|
codec.codecSpecific.VP8.pictureLossIndicationOn = true;
|
|
TEST_MUSTPASS(_vieRTPRTCP->SetKeyFrameRequestMethod(_channelId, kViEKeyFrameRequestPliRtcp),-5);
|
|
}else
|
|
{
|
|
TEST_MUSTPASS(_vieRTPRTCP->SetKeyFrameRequestMethod(_channelId, kViEKeyFrameRequestPliRtcp),-5);
|
|
}
|
|
TEST_MUSTPASS(_vieCodec->SetSendCodec(_channelId, codec),-5);
|
|
|
|
if (codec.codecType == webrtc::kVideoCodecMPEG4)
|
|
{
|
|
unsigned char configParameterSize = 0;
|
|
_vieCodec->GetCodecConfigParameters(_channelId, codec.codecSpecific.MPEG4.configParameters, configParameterSize);
|
|
codec.codecSpecific.MPEG4.configParametersSize = configParameterSize;
|
|
_vieCodec->SetReceiveCodec(_channelId, codec);
|
|
}
|
|
if (codec.codecType == webrtc::kVideoCodecI420)
|
|
{ // Need to set the receive codec size
|
|
_vieCodec->SetReceiveCodec(_channelId, codec);
|
|
}
|
|
}
|
|
|
|
void CDXChannelDlg::SetSendDestination()
|
|
{
|
|
if(_externalTransport)
|
|
return;
|
|
|
|
BYTE part1, part2, part3, part4;
|
|
char sendIP1[16];
|
|
m_remoteIp1.GetAddress(part1, part2, part3, part4);
|
|
sprintf(sendIP1,"%d.%d.%d.%d",part1,part2,part3,part4);
|
|
|
|
CString strPort;
|
|
m_remotePort1.GetWindowText(strPort);
|
|
int remotePort1 = _ttoi(strPort.GetString());
|
|
|
|
#ifdef IPV6
|
|
char* recIP = "::0";
|
|
#else
|
|
char* recIP = "0.0.0.0";
|
|
#endif //IPV6
|
|
|
|
TEST_MUSTPASS(_vieNetwork->SetSendDestination(_channelId,sendIP1,remotePort1),kViENetworkAlreadySending);
|
|
|
|
#ifndef NO_VOICE_ENGINE
|
|
m_localPort1.GetWindowText(strPort);
|
|
int localPort1 = _ttoi(strPort.GetString());
|
|
int res=_veBase->SetLocalReceiver(_audioChannel,localPort1+2);
|
|
|
|
TEST_MUSTPASS(_veBase->SetSendDestination(_audioChannel, remotePort1+2, sendIP1),-5)
|
|
#endif
|
|
|
|
}
|
|
|
|
void CDXChannelDlg::SetLocalReceiver()
|
|
{
|
|
if(_externalTransport)
|
|
return;
|
|
|
|
CString strPort;
|
|
m_localPort1.GetWindowText(strPort);
|
|
int localPort1 = _ttoi(strPort.GetString());
|
|
|
|
|
|
|
|
// May fail because we are sending
|
|
TEST_MUSTPASS(_vieNetwork->SetLocalReceiver(_channelId, localPort1),-5);
|
|
|
|
#ifndef NO_VOICE_ENGINE
|
|
int res=_veBase->SetLocalReceiver(_audioChannel,localPort1+2);
|
|
#endif
|
|
|
|
|
|
|
|
}
|
|
|
|
void CDXChannelDlg::SetCaptureDevice()
|
|
{
|
|
if(_parentChannel!=-1) // don't accept changing input on slave channels.
|
|
return;
|
|
|
|
int camSel=-1;
|
|
camSel=m_ctrlDevice.GetCurSel();
|
|
|
|
CString captureStr;
|
|
//captureStr.Compare
|
|
m_ctrlDevice.GetLBText(camSel, captureStr);
|
|
if(captureStr!=_T("N/A") != 0)
|
|
{
|
|
|
|
TEST_MUSTPASS(_vieFile->StopPlayFile(_captureId),kViEFileNotPlaying);
|
|
TEST_MUSTPASS(_vieCapture->DisconnectCaptureDevice(_channelId),kViECaptureDeviceNotConnected);
|
|
TEST_MUSTPASS(_vieRender->RemoveRenderer(_captureId),kViERenderInvalidRenderId);
|
|
|
|
if(_captureId>=0x1001 && _captureId<0x10FF)// ID is a capture device
|
|
{
|
|
TEST_MUSTPASS(_captureDevicePool.ReturnCaptureDevice(_captureId),-5);
|
|
}
|
|
|
|
if(captureStr!=_T("None")==0)
|
|
{
|
|
_captureId=-1;
|
|
}
|
|
else if(_tcsstr(captureStr,_T(".avi"))!=NULL ) // Selected an AVI file
|
|
{
|
|
TEST_MUSTPASS(_vieFile->StartPlayFile(TcharToChar(captureStr.GetBuffer(),-1),_captureId,false,webrtc::kFileFormatAviFile),-5);
|
|
TEST_MUSTPASS(_vieRender->AddRenderer(_captureId,m_ctrlLiveVideo.m_hWnd, 0, 0.0f, 0.0f,1.0f,1.0f),-5);
|
|
TEST_MUSTPASS(_vieRender->StartRender(_captureId),-5);
|
|
TEST_MUSTPASS(_vieFile->SendFileOnChannel(_captureId,_channelId),-5);
|
|
TEST_MUSTPASS(_vieFile->StartPlayFileAsMicrophone(_captureId,_channelId,true),-5);
|
|
//TEST_MUSTPASS(_vieFile->StartPlayAudioLocally(_captureId,_channelId),-5);
|
|
}
|
|
else
|
|
{
|
|
|
|
char captureName[256];
|
|
char uniqueCaptureName[256];
|
|
|
|
TEST_MUSTPASS(_vieCapture->GetCaptureDevice(camSel,captureName,256,uniqueCaptureName,256),-5);
|
|
|
|
TEST_MUSTPASS(_captureDevicePool.GetCaptureDevice(_captureId,uniqueCaptureName),-5);
|
|
TEST_MUSTPASS(_vieCapture->StartCapture(_captureId),kViECaptureDeviceAlreadyStarted);
|
|
TEST_MUSTPASS(_vieCapture->RegisterObserver(_captureId,*this),kViECaptureObserverAlreadyRegistered);
|
|
|
|
TEST_MUSTPASS(_vieRender->AddRenderer(_captureId,m_ctrlLiveVideo.m_hWnd, 0, 0.0f, 0.0f,1.0f,1.0f),-5);
|
|
TEST_MUSTPASS(_vieCapture->ConnectCaptureDevice(_captureId,_channelId),-5);
|
|
TEST_MUSTPASS(_vieRender->StartRender(_captureId),-5);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CDXChannelDlg::OnBnClickedStartlisten()
|
|
{
|
|
|
|
|
|
// Configure the local ports
|
|
SetLocalReceiver();
|
|
|
|
//Configure the remote destination- needed in order to be able to respond to RTCP messages
|
|
SetSendDestination();
|
|
|
|
|
|
#ifndef NO_VOICE_ENGINE
|
|
TEST_MUSTPASS(_veBase->StartReceive(_audioChannel),-5);
|
|
#endif
|
|
TEST_MUSTPASS(_vieBase->StartReceive(_channelId),-5);
|
|
|
|
|
|
}
|
|
|
|
void CDXChannelDlg::OnStartSend()
|
|
{
|
|
|
|
// Set the send destination
|
|
SetSendDestination();
|
|
|
|
// Configure the local ports (Needed to be able to receive RTCP
|
|
//SetLocalReceiver();
|
|
|
|
|
|
// Set the send codec
|
|
SetSendCodec();
|
|
|
|
if(_captureId==-1) // If no capture device has been set.
|
|
SetCaptureDevice(); //Set the capture device
|
|
|
|
|
|
|
|
//TEST_MUSTPASS(_vieRTPRTCP->SetStartSequenceNumber(_channelId,1),-5);
|
|
|
|
// Start sending
|
|
TEST_MUSTPASS(_vieBase->StartSend(_channelId),-5);
|
|
|
|
|
|
#ifndef NO_VOICE_ENGINE
|
|
TEST_MUSTPASS(_veBase->StartSend(_audioChannel),-5);
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
void CDXChannelDlg::ConfigureRender()
|
|
{
|
|
TEST_MUSTPASS(_vieRender->AddRenderer(_channelId,m_ctrlLiveRemoteVideo.m_hWnd, 0, 0.0f, 0.0f,1.0f,1.0f),-5);
|
|
|
|
TEST_MUSTPASS(_vieFile->SetRenderStartImage(_channelId,"renderStartImage.jpg"),-5);
|
|
TEST_MUSTPASS(_vieRender->StartRender(_channelId),-5);
|
|
TEST_MUSTPASS(_vieFile->SetRenderTimeoutImage(_channelId,"renderTimeoutImage.jpg"),-5);
|
|
|
|
|
|
}
|
|
|
|
|
|
void CDXChannelDlg::OnStopSend()
|
|
{
|
|
|
|
#ifndef NO_VOICE_ENGINE
|
|
TEST_MUSTPASS(_veBase->StopSend(_audioChannel),-5);
|
|
#endif
|
|
|
|
|
|
TEST_MUSTPASS(_vieBase->StopSend(_channelId),kViEBaseNotSending); // Accept error Not sending
|
|
|
|
|
|
}
|
|
void CDXChannelDlg::OnBnClickedStoplisten()
|
|
{
|
|
|
|
|
|
#ifndef NO_VOICE_ENGINE
|
|
TEST_MUSTPASS(_veBase->StopReceive(_audioChannel),-5);
|
|
#endif
|
|
TEST_MUSTPASS(_vieBase->StopReceive(_channelId),-5);
|
|
}
|
|
|
|
|
|
void CDXChannelDlg::OnDestroy()
|
|
{
|
|
|
|
OnStopSend();
|
|
OnBnClickedStoplisten();
|
|
|
|
if(_vieCapture && _parentChannel==-1)
|
|
{
|
|
_vieCapture->DisconnectCaptureDevice(_channelId);
|
|
_captureDevicePool.ReturnCaptureDevice(_captureId);
|
|
}
|
|
if(_vieFile && _parentChannel!=-1)
|
|
{
|
|
TEST_MUSTPASS(_vieFile->StopPlayFile(_captureId),kViEFileNotPlaying);
|
|
}
|
|
|
|
|
|
|
|
|
|
if(_videoEngine)
|
|
{
|
|
if(_parentChannel==-1)
|
|
{
|
|
_vieCodec->DeregisterEncoderObserver(_channelId);
|
|
}
|
|
_vieBase->DeleteChannel(_channelId);
|
|
_channelPool.RemoveChannel(_channelId);
|
|
}
|
|
|
|
_videoEngine = NULL;
|
|
#ifndef NO_VOICE_ENGINE
|
|
|
|
if (_voiceEngine)
|
|
{
|
|
_veBase->DeleteChannel(_audioChannel);
|
|
_veBase->Release();
|
|
_veNetwork->Release();
|
|
_veCodec->Release();
|
|
_veRTCP->Release();
|
|
}
|
|
#endif
|
|
|
|
|
|
strcpy(_logMsg,"");
|
|
SetEvent(_callbackEvent);
|
|
MSG msg; // Wait until the callback thread exits. Need to handle messages since the callback thread can call SendMessage when updating UI
|
|
while(WaitForSingleObject(_callbackThread,10)==WAIT_TIMEOUT)
|
|
{
|
|
DWORD ret = PeekMessage( &msg, NULL, 0, 0,PM_REMOVE );
|
|
if (ret >0)
|
|
{
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
}
|
|
}
|
|
|
|
CloseHandle(_callbackThread);
|
|
CloseHandle(_callbackEvent);
|
|
DeleteCriticalSection(&_critCallback);
|
|
|
|
TEST_MUSTPASS(_vieCapture->Release()<0,-5);
|
|
TEST_MUSTPASS(_vieRTPRTCP->Release()<0,-5);
|
|
TEST_MUSTPASS(_vieRender->Release()<0,-5);
|
|
TEST_MUSTPASS(_vieCodec->Release()<0,-5);
|
|
TEST_MUSTPASS(_vieNetwork->Release()<0,-5);
|
|
TEST_MUSTPASS(_vieFile->Release()<0,-5);
|
|
TEST_MUSTPASS(_vieBase->Release()<0,-5);
|
|
|
|
|
|
|
|
#ifdef TEST_EXTERNAL_TRANSPORT
|
|
if(_transport)
|
|
delete _transport;
|
|
_transport = NULL;
|
|
#endif
|
|
|
|
delete _externalTransport;
|
|
|
|
CDialog::OnDestroy();
|
|
if(_dialogObserver)
|
|
{
|
|
_dialogObserver->ChannelDialogEnded(this);
|
|
}
|
|
}
|
|
|
|
void CDXChannelDlg::OnCancel()
|
|
{
|
|
DestroyWindow();
|
|
}
|
|
// If you add a minimize button to your dialog, you will need the code below
|
|
// to draw the icon. For MFC applications using the document/view model,
|
|
// this is automatically done for you by the framework.
|
|
|
|
void CDXChannelDlg::OnPaint()
|
|
{
|
|
if (IsIconic())
|
|
{
|
|
CPaintDC dc(this); // device context for painting
|
|
|
|
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
|
|
|
|
// Center icon in client rectangle
|
|
int cxIcon = GetSystemMetrics(SM_CXICON);
|
|
int cyIcon = GetSystemMetrics(SM_CYICON);
|
|
CRect rect;
|
|
GetClientRect(&rect);
|
|
int x = (rect.Width() - cxIcon + 1) / 2;
|
|
int y = (rect.Height() - cyIcon + 1) / 2;
|
|
|
|
// Draw the icon
|
|
dc.DrawIcon(x, y, m_hIcon);
|
|
}
|
|
else
|
|
{
|
|
CDialog::OnPaint();
|
|
}
|
|
}
|
|
|
|
BOOL CDXChannelDlg::OnDeviceChange( UINT nID, DWORD lParam)
|
|
{
|
|
if(nID == DBT_DEVNODES_CHANGED)
|
|
{
|
|
// SetCaptureDevice();
|
|
}
|
|
return CDialog::OnDeviceChange(nID, lParam);
|
|
}
|
|
|
|
|
|
void CDXChannelDlg::OnSysCommand(UINT nID, LPARAM lParam)
|
|
{
|
|
if(SC_MAXIMIZE == nID)
|
|
{}
|
|
CDialog::OnSysCommand(nID, lParam);
|
|
}
|
|
|
|
|
|
static bool fullScreen = false;
|
|
void CDXChannelDlg::OnRButtonUp( UINT nFlags, CPoint point)
|
|
{
|
|
CDialog::OnRButtonUp( nFlags, point);
|
|
}
|
|
|
|
// The system calls this to obtain the cursor to display while the user drags
|
|
// the minimized window.
|
|
HCURSOR CDXChannelDlg::OnQueryDragIcon()
|
|
{
|
|
return (HCURSOR) m_hIcon;
|
|
}
|
|
|
|
void CDXChannelDlg::OnCbnSelchangeCodecList()
|
|
{
|
|
SetSendCodec();
|
|
}
|
|
|
|
|
|
void CDXChannelDlg::OnCbnSelchangeSize()
|
|
{
|
|
SetSendCodec();
|
|
}
|
|
|
|
void CDXChannelDlg::OnCbnSelchangeDevice()
|
|
{
|
|
|
|
|
|
SetCaptureDevice();
|
|
|
|
}
|
|
|
|
|
|
void CDXChannelDlg::OnCbnSelchangeBitrate()
|
|
{
|
|
|
|
SetSendCodec();
|
|
|
|
}
|
|
|
|
void CDXChannelDlg::OnCbnSelchangeMinFrameRate()
|
|
{
|
|
|
|
SetSendCodec();
|
|
|
|
}
|
|
|
|
|
|
void CDXChannelDlg::OnBnClickedTmmbr()
|
|
{
|
|
|
|
TEST_MUSTPASS(_vieRTPRTCP->SetTMMBRStatus(_channelId,m_cbTmmbr.GetCheck()==BST_CHECKED),-5);
|
|
|
|
}
|
|
|
|
void CDXChannelDlg::OnCbnSelchangeRtcpmode()
|
|
{
|
|
|
|
/*
|
|
kRtcpNone = 0,
|
|
kRtcpCompound_RFC4585 = 1,
|
|
kRtcpNonCompound_RFC5506 = 2 */
|
|
ViERTCPMode mode=ViERTCPMode(m_ctrlRtcpMode.GetCurSel());
|
|
TEST_MUSTPASS(_vieRTPRTCP->SetRTCPStatus(_channelId,mode),-5);
|
|
|
|
}
|
|
|
|
void CDXChannelDlg::OnBnClickedFreezelog()
|
|
{
|
|
_canAddLog=m_cbFreezeLog.GetCheck()!=BST_CHECKED;
|
|
}
|
|
|
|
void CDXChannelDlg::OnBnClickedProtNack()
|
|
{
|
|
|
|
TEST_MUSTPASS(_vieRTPRTCP->SetNACKStatus(_channelId,true),-5);
|
|
|
|
}
|
|
|
|
void CDXChannelDlg::OnBnClickedProtNone()
|
|
{
|
|
|
|
TEST_MUSTPASS(_vieRTPRTCP->SetNACKStatus(_channelId,false),-5);
|
|
TEST_MUSTPASS(_vieRTPRTCP->SetFECStatus(_channelId,false,0,0),-5);
|
|
}
|
|
|
|
void CDXChannelDlg::OnBnClickedProtFec()
|
|
{
|
|
int noCodec=_vieCodec->NumberOfCodecs();
|
|
int redPayloadType=0;
|
|
int fecPayloadType=0;
|
|
for(unsigned char i=0;i<noCodec;++i)
|
|
{
|
|
VideoCodec codec;
|
|
_vieCodec->GetCodec(i,codec);
|
|
if(codec.codecType==webrtc::kVideoCodecRED)
|
|
{
|
|
redPayloadType=codec.plType;
|
|
}
|
|
if(codec.codecType==webrtc::kVideoCodecULPFEC)
|
|
{
|
|
fecPayloadType=codec.plType;
|
|
}
|
|
}
|
|
TEST_MUSTPASS(_vieRTPRTCP->SetFECStatus(_channelId,true,redPayloadType,fecPayloadType),-5);
|
|
}
|
|
|
|
void CDXChannelDlg::OnBnClickedCameracap()
|
|
{
|
|
char version[1024];
|
|
_vieBase->GetVersion(version);
|
|
MessageBox(CharToTchar(version,-1));
|
|
int p=strlen(version);
|
|
#ifndef NO_VOICE_ENGINE
|
|
_veBase->GetVersion(version);
|
|
MessageBox(CharToTchar(version,-1));
|
|
#endif
|
|
}
|
|
|
|
unsigned int WINAPI CDXChannelDlg::CallbackThread(LPVOID lpParameter)
|
|
{
|
|
static_cast<CDXChannelDlg*>(lpParameter)->CallbackThreadProcess();
|
|
return 0;
|
|
}
|
|
|
|
void CDXChannelDlg::CallbackThreadProcess()
|
|
{
|
|
while(1)
|
|
{
|
|
if(WAIT_OBJECT_0==WaitForSingleObject(_callbackEvent,INFINITE))
|
|
{
|
|
char smsg[512];
|
|
EnterCriticalSection(&_critCallback);
|
|
strncpy(smsg,_logMsg,strlen(_logMsg)+1);
|
|
strcpy(_logMsg,"");
|
|
|
|
|
|
LeaveCriticalSection(&_critCallback);
|
|
if(strstr(smsg,"Send")!=NULL)
|
|
{
|
|
unsigned short fractionLost=0;
|
|
unsigned int cumulativeLost=0;
|
|
unsigned int extendedMax=0;
|
|
unsigned int jitter=0;
|
|
int rttMs=0;
|
|
|
|
|
|
|
|
_vieRTPRTCP->GetReceivedRTCPStatistics(_channelId,
|
|
fractionLost,
|
|
cumulativeLost,
|
|
extendedMax,
|
|
jitter,
|
|
rttMs);
|
|
|
|
//int bw=0;
|
|
//if(_vieCodec->GetAvailableBandwidth(_channelId,bw)==0)
|
|
//{
|
|
// sprintf(smsg,"%s, rtt %d, loss %d,bw %d", smsg,rttMs,fractionLost,bw);
|
|
//}
|
|
//else
|
|
//{
|
|
// _vieBase->LastError(); // Reset last error.
|
|
//}
|
|
|
|
|
|
|
|
}
|
|
if(strlen(smsg))
|
|
{
|
|
m_ctrlInfo.InsertString(0,(LPCTSTR) CharToTchar(smsg,-1));
|
|
while(m_ctrlInfo.GetCount()==151)
|
|
m_ctrlInfo.DeleteString(150);
|
|
}
|
|
else
|
|
{
|
|
break; // End the callback thread
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
void CDXChannelDlg::AddToInfo(const char* msg)
|
|
{
|
|
if(!_canAddLog)
|
|
return;
|
|
EnterCriticalSection(&_critCallback);
|
|
|
|
SYSTEMTIME systemTime;
|
|
GetSystemTime(&systemTime);
|
|
|
|
if(strlen(_logMsg)==0)
|
|
{
|
|
SetEvent(_callbackEvent); // Notify of new
|
|
}
|
|
|
|
sprintf (_logMsg, "(%2u:%2u:%2u:%3u) %s", systemTime.wHour,
|
|
systemTime.wMinute,
|
|
systemTime.wSecond,
|
|
systemTime.wMilliseconds,
|
|
msg
|
|
);
|
|
|
|
|
|
|
|
LeaveCriticalSection(&_critCallback);
|
|
|
|
|
|
}
|
|
|
|
void CDXChannelDlg::IncomingRate(const int videoChannel,
|
|
unsigned int framerate,
|
|
unsigned int bitrate)
|
|
{
|
|
char str[64];
|
|
sprintf(str,"Incoming Fr:%d br %d\n", framerate, bitrate);
|
|
AddToInfo(str);
|
|
}
|
|
|
|
void CDXChannelDlg::RequestNewKeyFrame(int channel)
|
|
{
|
|
assert(!"(RequestNewKeyFrame why is it called");
|
|
}
|
|
void CDXChannelDlg::PerformanceAlarm(unsigned int cpuLoad)
|
|
{
|
|
char str[64];
|
|
sprintf(str,"Performance alarm %d",cpuLoad);
|
|
AddToInfo(str);
|
|
}
|
|
void CDXChannelDlg::OutgoingRate(const int videoChannel,
|
|
unsigned int framerate,
|
|
unsigned int bitrate)
|
|
{
|
|
char str[64];
|
|
sprintf(str,"Send Fr:%d br %d", framerate, bitrate);
|
|
AddToInfo(str);
|
|
}
|
|
void CDXChannelDlg::IncomingCodecChanged(const int videoChannel,
|
|
const VideoCodec& videoCodec)
|
|
{
|
|
char str[128];
|
|
sprintf(str,"Incoming codec channel:%d pltype:%d width:%d height:%d\n", videoChannel, videoCodec.plType, videoCodec.width,videoCodec.height);
|
|
AddToInfo(str);
|
|
}
|
|
void CDXChannelDlg::BrightnessAlarm(const int captureId,
|
|
const Brightness brightness)
|
|
{
|
|
|
|
switch(brightness)
|
|
{
|
|
case Normal:
|
|
AddToInfo("BrightnessAlarm - image ok.\n");
|
|
break;
|
|
case Bright:
|
|
AddToInfo("BrightnessAlarm - light image.\n");
|
|
break;
|
|
case Dark:
|
|
AddToInfo("BrightnessAlarm - dark image.\n");
|
|
break;
|
|
}
|
|
}
|
|
|
|
void CDXChannelDlg::CapturedFrameRate(const int captureId,
|
|
const unsigned char frameRate)
|
|
{
|
|
char str[64];
|
|
sprintf(str,"Local Camera Frame rate:%d \n", frameRate);
|
|
AddToInfo(str);
|
|
}
|
|
|
|
void CDXChannelDlg::NoPictureAlarm(const int captureId,
|
|
const CaptureAlarm alarm)
|
|
{
|
|
char str[64];
|
|
sprintf(str,"No Picture alarm\n");
|
|
AddToInfo(str);
|
|
|
|
}
|
|
|
|
|
|
void CDXChannelDlg::OnBnClickedExttransport()
|
|
{
|
|
if(m_cbExternalTransport.GetCheck()==BST_CHECKED)
|
|
{
|
|
m_localPort1.EnableWindow(FALSE);
|
|
m_remotePort1.EnableWindow(FALSE);
|
|
m_remoteIp1.EnableWindow(FALSE);
|
|
m_ctrlPacketLoss.EnableWindow(TRUE);
|
|
m_ctrlDelay.EnableWindow(TRUE);
|
|
_externalTransport= new tbExternalTransport(*_vieNetwork);
|
|
_vieNetwork->RegisterSendTransport(_channelId,*_externalTransport);
|
|
}
|
|
else
|
|
{
|
|
_vieNetwork->DeregisterSendTransport(_channelId);
|
|
|
|
delete _externalTransport;
|
|
_externalTransport=NULL;
|
|
m_localPort1.EnableWindow(TRUE);
|
|
m_remotePort1.EnableWindow(TRUE);
|
|
m_remoteIp1.EnableWindow(TRUE);
|
|
m_ctrlPacketLoss.EnableWindow(FALSE);
|
|
m_ctrlDelay.EnableWindow(FALSE);
|
|
}
|
|
}
|
|
|
|
|
|
void CDXChannelDlg::OnCbnSelchangePacketloss()
|
|
{
|
|
if(_externalTransport)
|
|
{
|
|
_externalTransport->SetPacketLoss(m_ctrlPacketLoss.GetCurSel()*2);
|
|
}
|
|
}
|
|
|
|
|
|
void CDXChannelDlg::OnCbnSelchangeDelay()
|
|
{
|
|
if(_externalTransport)
|
|
{
|
|
_externalTransport->SetNetworkDelay(m_ctrlDelay.GetCurSel()*30);
|
|
}
|
|
|
|
}
|
|
|
|
void CDXChannelDlg::OnBnClickedBtnRecordIncoming()
|
|
{
|
|
|
|
CButton *recordBtn = (CButton *) GetDlgItem(IDC_BTN_RECORD_INCOMING);
|
|
|
|
CString text;
|
|
recordBtn->GetWindowText(text);
|
|
if(text!=_T("Stop Rec Inc")!=0)
|
|
{
|
|
recordBtn->SetWindowText(_T("Stop Rec Inc"));
|
|
SYSTEMTIME time;
|
|
GetSystemTime(&time);
|
|
sprintf(_fileName,"IncomingChannel%d_%4d%2d%2d%2d%2d.avi",_channelId,time.wYear,time.wMonth,time.wDay,time.wHour,time.wMinute);
|
|
|
|
AudioSource audioSource=PLAYOUT;
|
|
webrtc::CodecInst audioCodec;
|
|
strcpy(audioCodec.plname,"L16");
|
|
audioCodec.rate = 256000;
|
|
audioCodec.plfreq = 16000;
|
|
audioCodec.pacsize = 160;
|
|
|
|
webrtc::VideoCodec videoCodec;
|
|
memset(&videoCodec,0,sizeof(videoCodec));
|
|
|
|
strcpy(videoCodec.plName,"VP8");
|
|
videoCodec.maxBitrate=1000;
|
|
videoCodec.startBitrate=1000;
|
|
videoCodec.width=352;
|
|
videoCodec.height=288;
|
|
videoCodec.codecType=webrtc::kVideoCodecVP8;
|
|
videoCodec.maxFramerate=30;
|
|
TEST_MUSTPASS(_vieFile->StartRecordIncomingVideo(_channelId,_fileName,audioSource,audioCodec, videoCodec),-5);
|
|
}
|
|
else
|
|
{
|
|
recordBtn->SetWindowText(_T("Record Incoming"));
|
|
TEST_MUSTPASS(_vieFile->StopRecordIncomingVideo(_channelId),-5);
|
|
CString msg;
|
|
msg.AppendFormat(_T("Recorded file %s"),_fileName);
|
|
MessageBox(msg);
|
|
}
|
|
}
|
|
|
|
void CDXChannelDlg::OnBnClickedBtnRecordOutgoing()
|
|
{
|
|
|
|
CButton *recordBtn = (CButton *) GetDlgItem(IDC_BTN_RECORD_OUTGOING);
|
|
CString text;
|
|
recordBtn->GetWindowText(text);
|
|
if(text!=_T("Stop Rec Out"))
|
|
{
|
|
recordBtn->SetWindowText(_T("Stop Rec Out"));
|
|
SYSTEMTIME time;
|
|
GetSystemTime(&time);
|
|
sprintf(_fileName,"OutgoingChannel%d_%4d%2d%2d%2d%2d.avi",_channelId,time.wYear,time.wMonth,time.wDay,time.wHour,time.wMinute);
|
|
|
|
AudioSource audioSource=MICROPHONE;
|
|
webrtc::CodecInst audioCodec;
|
|
strcpy(audioCodec.plname,"L16");
|
|
audioCodec.rate = 256000;
|
|
audioCodec.plfreq = 16000;
|
|
audioCodec.pacsize = 160;
|
|
|
|
webrtc::VideoCodec videoCodec;
|
|
memset(&videoCodec,0,sizeof(videoCodec));
|
|
|
|
strcpy(videoCodec.plName,"VP8");
|
|
videoCodec.maxBitrate=1000;
|
|
videoCodec.startBitrate=1000;
|
|
videoCodec.width=352;
|
|
videoCodec.height=288;
|
|
videoCodec.codecType=webrtc::kVideoCodecVP8;
|
|
videoCodec.maxFramerate=30;
|
|
TEST_MUSTPASS(_vieFile->StartRecordOutgoingVideo(_channelId,_fileName,audioSource,audioCodec,videoCodec),-5);
|
|
}
|
|
else
|
|
{
|
|
recordBtn->SetWindowText(_T("Record Outgoing"));
|
|
TEST_MUSTPASS(_vieFile->StopRecordOutgoingVideo(_channelId),-5);
|
|
CString msg;
|
|
msg.AppendFormat(_T("Recorded file %s"),_fileName);
|
|
MessageBox(msg);
|
|
}
|
|
}
|
|
|
|
void CDXChannelDlg::OnBnClickedBtnCreateSlave()
|
|
{
|
|
CDXChannelDlg* newSlave =new CDXChannelDlg(_videoEngine,_captureDevicePool,_channelPool,_voiceEngine,NULL,_dialogObserver,_channelId);
|
|
newSlave->Create(CDXChannelDlg::IDD,NULL);
|
|
}
|