Re: Access violation MFC/C++
Code:
long CPelcoDX8100Ctrl::GetPTZSpeed()
{
return m_iPTZSpeed;
}
void CPelcoDX8100Ctrl::SetPTZSpeed(long nNewValue)
{
m_iPTZSpeed = nNewValue;
SetModifiedFlag();
}
long CPelcoDX8100Ctrl::GetCameraId(LPCTSTR cameraName)
{
ST_CHANNEL_INFO stChInfo;
int ret = 0;
CString name = cameraName;
name.TrimRight();
for( int nCamNum=0;nCamNum< MAX_SUPPORT_CH ;nCamNum++)
{
ret = DxGetCameraInformation(m_hServer, nCamNum, &stChInfo);
if (name == stChInfo.szCameraName)
{
m_nCameraId = nCamNum;
m_bPTZEnabled = stChInfo.bPTZEnable;
break;
}
}
m_CameraName = name;
return m_bPTZEnabled; //return PTZenabled setting back to display
}
void CPelcoDX8100Ctrl::SetHServer(HSERVER hServer, int nDivision,LPLIVE_VID_CONF lpliveVidConf)
{
m_hServer = hServer;
m_nDivision = nDivision;
memcpy(&m_LiveVidConf,lpliveVidConf,sizeof(LIVE_VID_CONF));
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Live Stream
//
long CPelcoDX8100Ctrl::Connect(LPCTSTR address, short port, LPCTSTR userId, LPCTSTR password)
{
g_bPaused = false;
g_pServerInfo = new ST_SERVER_BASE_INFO();
if (!g_pServerInfo)
return 1;
memset(g_pServerInfo,0,sizeof(g_pServerInfo));
StringCbCopy(g_pServerInfo->szServerAddr, sizeof(g_pServerInfo->szServerAddr), address);
StringCbCopy(g_pServerInfo->szUserID, sizeof(g_pServerInfo->szUserID), userId);
StringCbCopy(g_pServerInfo->szUserPasswd, sizeof(g_pServerInfo->szUserPasswd), password);
g_pServerInfo->usServerPort = port;
g_pServerInfo->lpfnConectCallback = CPelcoDX8100Ctrl::OnConnectedCallback;
g_pServerInfo->lpfnDisconnectCallback = CPelcoDX8100Ctrl::OnDisconnectCallback;
DxSetSocketTimeOut(m_ConnectTimeout);
m_hServer = DxConnect(g_pServerInfo);
if (!m_hServer)
{
m_iLastError = DxGetLastError();
return m_iLastError;
}
return 0;
}
void CPelcoDX8100Ctrl::BeginLiveStream(LPCTSTR cameraName)
{
g_bPaused = true;
if(g_pOverlayWnd)
{
g_pOverlayWnd = NULL;
delete g_pOverlayWnd;
if(m_nDisplayMode == PLAYBACK_DISPLAY_MODE)
{
DxSearchStop( m_hServer );
DxPlaybackCtrl(m_hServer, _DXSDK_PLAYBACK_STOP);
}else
{
DxStopLiveStream( m_hServer );
}
}
g_pOverlayWnd = NULL;
g_pOverlayWnd = new COverlayWnd;
g_pOverlayWnd->CreateEx(WS_EX_ACCEPTFILES,NULL,"",WS_CHILD|WS_VISIBLE|WS_BORDER,CRect(0,0,533,400),this,NULL);
g_pOverlayWnd->InitDirectDraw();
g_pOverlayWnd->SetDivision(1);
LIVE_VID_CONF vidConf;
memset(&vidConf,0,sizeof(vidConf));
vidConf.btChEnable[m_nCameraId] = true;
vidConf.uiMinimumStreamIntervalMS = 5;
vidConf.VidForat = FORMAT_YUV16;
vidConf.lpfnVidStreamCallback = CPelcoDX8100Ctrl::OnImageDisplayCallback;
int ret = DxBeginLiveStream(m_hServer, &vidConf);
int nDivision[6] = {1,4,9,16,25,32};
SetDisplayMode(LIVE_DISPLAY_MODE);
SetHServer(m_hServer, nDivision[1] , &vidConf);
g_bPaused = false;
}
VOID CPelcoDX8100Ctrl::OnConnectedCallback(HSERVER hServer, LPST_CONNECT_INFO lpstConnectInfo)
{
}
VOID CPelcoDX8100Ctrl::OnDisconnectCallback(HSERVER hServer)
{
}
VOID CPelcoDX8100Ctrl::OnImageDisplayCallback(HSERVER hServer, LPST_LIVE_VID_ITEM lpstVidStream)
{
if(g_bPaused == false)
{
if( g_pOverlayWnd && g_pMyCtrl && g_pOverlayWnd->m_hWnd && g_pOverlayWnd->IsWindowVisible() )
{
g_pOverlayWnd->WriteOverlayScrn( lpstVidStream , (BYTE*)lpstVidStream->stFrameItem.lpVidBuffer );
g_pOverlayWnd->UpdateOverlay();
g_pMyCtrl->InternalResize();
}
}
}
VOID CPelcoDX8100Ctrl::OnLiveVideoStreamAborted(HSERVER hServer,INT nErrCode)
{
AfxMessageBox("Video Stream Aborted.\n");
}
void CPelcoDX8100Ctrl::SetDisplayMode(int DisplayMode) // 1 - live, 2 - playback
{
ASSERT(DisplayMode == LIVE_DISPLAY_MODE || DisplayMode == PLAYBACK_DISPLAY_MODE);
m_nDisplayMode = DisplayMode;
}
LRESULT CPelcoDX8100Ctrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
try
{
CString tmp;
switch(message)
{
case WM_KEYDOWN:
{
Connect("172.16.141.48", 9002, "admin", "admin");
GetCameraId("Front Door");
BeginLiveStream("Front Door");
//PTZSpeed = 45;
}
}
return COleControl::WindowProc(message, wParam, lParam);
}
catch(...)
{
return -1;
}
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Playback Funtionality
//
void CPelcoDX8100Ctrl::_PlaybackCtrl()
{
ASSERT( m_nDisplayMode != NONE_DISPLAY_MODE);
if(g_pOverlayWnd)
{
g_pOverlayWnd = NULL;
delete g_pOverlayWnd;
if(m_nDisplayMode == PLAYBACK_DISPLAY_MODE)
{
DxSearchStop( m_hServer );
DxPlaybackCtrl(m_hServer, _DXSDK_PLAYBACK_STOP);
}else
{
DxStopLiveStream( m_hServer );
}
}
g_pOverlayWnd = new COverlayWnd;
g_pOverlayWnd->CreateEx(WS_EX_ACCEPTFILES,NULL,"",WS_CHILD|WS_VISIBLE|WS_BORDER,CRect(0,0,533,400),this,NULL);
g_pOverlayWnd->InitDirectDraw();
g_pOverlayWnd->SetDivision(1);
ST_PLAYBACK_OPT stPlayOption;
memset( &stPlayOption,0,sizeof(ST_PLAYBACK_OPT) );
m_nCameraSelectedMask = 0;
// Get select video channel.
stPlayOption.btChannel[m_nCameraId] = TRUE;
m_nCameraSelectedMask = m_nCameraId;
//set of video Output format.
// FORMAT_YUV16 or FORMAT_RGB24 supported now
stPlayOption.VidForat = FORMAT_YUV16;
m_dStartTime += 2;
SYSTEMTIME st;
VariantTimeToSystemTime(m_dStartTime, &st);
stPlayOption.stStartTime.wYear = st.wYear;
stPlayOption.stStartTime.wMonth = st.wMonth;
stPlayOption.stStartTime.wDay = st.wDay;
stPlayOption.stStartTime.wHour = st.wHour; //AM
stPlayOption.stStartTime.wMinute = st.wMinute;
stPlayOption.stStartTime.wSecond = st.wSecond;
stPlayOption.stStartTime.wMilliseconds = st.wMilliseconds;
stPlayOption.stStartTime.wDayOfWeek = st.wDayOfWeek; //Monday. start is sunday = 0;
// Play Enable Audio channel.
stPlayOption.nPlayAudioCh = -1;
m_stLastReceivedTime = stPlayOption.stStartTime;// store last received time
// Callback Function address.
stPlayOption.lpfnPlaybackEventCallback = CPelcoDX8100Ctrl::OnSearchCallback;
// Set playback speed
switch(m_playbackSpeed) {
case 0:
stPlayOption.fPlaybackSpeed = _DXSDK_PLAYBACK_SPD_1; // 1X
break;
case 1:
stPlayOption.fPlaybackSpeed = _DXSDK_PLAYBACK_SPD_2; // 1X
break;
case 2:
stPlayOption.fPlaybackSpeed = _DXSDK_PLAYBACK_SPD_4; // 1X
break;
case 3:
stPlayOption.fPlaybackSpeed = _DXSDK_PLAYBACK_SPD_6; // 1X
break;
default:
stPlayOption.fPlaybackSpeed = _DXSDK_PLAYBACK_SPD_1; // 1X
}
DxSearchPlaybackSetOption(m_hServer, &stPlayOption);
// Set Playback Timeout
int nPlaybackTimeoutSeconds;
nPlaybackTimeoutSeconds = GetDlgItemInt(IDC_SEARCH_MAXINTERVAL, NULL, TRUE);
if(nPlaybackTimeoutSeconds < 0)
{
nPlaybackTimeoutSeconds = 0;
}
// Playback timeout
DxSetPlaybackTimeoutSeconds(m_hServer, nPlaybackTimeoutSeconds);
SetDisplayMode(PLAYBACK_DISPLAY_MODE);
}
void CPelcoDX8100Ctrl::_GetPlaybackOption()
{
g_bPaused = false;
ST_PLAYBACK_OPT stPlayOption;
memset( &stPlayOption,0,sizeof(ST_PLAYBACK_OPT) );
stPlayOption.btChannel[m_nCameraId] = TRUE;
// playback option apply only if camera selected
if(m_nCameraSelectedMask == 0)
{
stPlayOption.btChannel[0] = TRUE;
}
//set of video Output format.
// FORMAT_YUV16 or FORMAT_RGB24 supported now
stPlayOption.VidForat = FORMAT_YUV16;
stPlayOption.stStartTime = m_stLastReceivedTime;
// Callback Function address.
stPlayOption.lpfnPlaybackEventCallback = CPelcoDX8100Ctrl::OnSearchCallback;
// Set playback speed
switch(m_playbackSpeed)
{
case 0:
stPlayOption.fPlaybackSpeed = _DXSDK_PLAYBACK_SPD_1; // 1X
break;
case 1:
stPlayOption.fPlaybackSpeed = _DXSDK_PLAYBACK_SPD_2; // 1X
break;
case 2:
stPlayOption.fPlaybackSpeed = _DXSDK_PLAYBACK_SPD_4; // 1X
break;
case 3:
stPlayOption.fPlaybackSpeed = _DXSDK_PLAYBACK_SPD_6; // 1X
break;
default:
stPlayOption.fPlaybackSpeed = _DXSDK_PLAYBACK_SPD_1; // 1X
}
DxSearchPlaybackSetOption(m_hServer, &stPlayOption);
}
VOID CPelcoDX8100Ctrl::OnSearchCallback(HSERVER hServer, LPSEARCH_ITEM lpSearchItem)
{
if( !lpSearchItem ) //End of search
{
TRACE("End of Search.\n");
return;
}
else
{
LPSEARCH_ITEM lpstVidStream = lpSearchItem;
CTime TimeStamp(lpstVidStream->stFrameItem.stVidTimeStamp);// Video Time Stamp
m_stLastReceivedTime = lpstVidStream->stFrameItem.stVidTimeStamp;
CString strTmp;
strTmp.Format("%s-%d",TimeStamp.Format("%Y/%m/%d-%H:%M:%S"),lpstVidStream->stFrameItem.stVidTimeStamp.wMilliseconds);
VideoPartInfo(IDC_STATIC_V_TIMESTAMP,strTmp);
strTmp.Format("%d",lpstVidStream->nChannel+1);
TRACE("%s,",strTmp);
TRACE("%d\n",lpstVidStream->stFrameItem.uiVidBufSize );
CPelcoDX8100Ctrl::OnImageDisplayCallback(hServer, (LPST_LIVE_VID_ITEM)lpSearchItem);
}
}
double CPelcoDX8100Ctrl::GetStartTime()
{
return m_dStartTime;
}
void CPelcoDX8100Ctrl::SetStartTime(double newValue)
{
m_dStartTime = newValue;
SetModifiedFlag();
}
long CPelcoDX8100Ctrl::GetPlaybackSpeed()
{
return m_playbackSpeed;
}
void CPelcoDX8100Ctrl::SetPlaybackSpeed(long nNewValue)
{
m_playbackSpeed = nNewValue;
SetModifiedFlag();
}
void CPelcoDX8100Ctrl::Pause()
{
g_bPaused = true;
::DxPlaybackCtrl(m_hServer,_DXSDK_PLAYBACK_PAUSE);
}
void CPelcoDX8100Ctrl::PlaybackPlay()
{
g_bPaused = true;
if(g_pOverlayWnd)
delete g_pOverlayWnd;
_PlaybackCtrl();
_GetPlaybackOption();
::DxPlaybackCtrl(m_hServer, _DXSDK_PLAYBACK_FPLAY);
g_bPaused = false;
}
void CPelcoDX8100Ctrl::PlaybackReverse()
{
::DxPlaybackCtrl(m_hServer, _DXSDK_PLAYBACK_RPLAY);
_GetPlaybackOption();
}
void CPelcoDX8100Ctrl::PlaybackForward()
{
::DxPlaybackCtrl(m_hServer, _DXSDK_PLAYBACK_FPLAY);
_GetPlaybackOption();
}
void CPelcoDX8100Ctrl::PlaybackStop()
{
::DxPlaybackCtrl(m_hServer, _DXSDK_PLAYBACK_STOP);
_GetPlaybackOption();
}
void CPelcoDX8100Ctrl::PlaybackFirst()
{
::DxPlaybackCtrl(m_hServer, _DXSDK_PLAYBACK_FIRST);
_GetPlaybackOption();
}
void CPelcoDX8100Ctrl::PlaybackLast()
{
::DxPlaybackCtrl(m_hServer, _DXSDK_PLAYBACK_LAST);
_GetPlaybackOption();
}
void CPelcoDX8100Ctrl::ViewLive()
{
if(g_pOverlayWnd)
delete g_pOverlayWnd;
g_bPaused = false;
BeginLiveStream(m_CameraName );
}
void CPelcoDX8100Ctrl::VideoPartInfo(int id, CString strTemp)
{
if(g_pOverlayWnd == NULL)
return ;
CDC* pDC = g_pOverlayWnd->GetDC();
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(RGB(0,255,127));
g_pOverlayWnd->InvalidateRect(CRect(25, 15, 300, 30),TRUE );
pDC->DrawText(strTemp, strlen(strTemp), CRect(25, 15, 300, 30), DT_CENTER);
pDC = NULL;
delete pDC;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// PTZ Funtionality
//
void CPelcoDX8100Ctrl::Focusin()
{
DxPTZActCtrl(m_hServer,m_nCameraId,_DXPTZ_FOCUS_IN | _DX_PTZ_ACT_START , 0 );
}
void CPelcoDX8100Ctrl::Focusout()
{
DxPTZActCtrl(m_hServer,m_nCameraId,_DXPTZ_FOCUS_OUT | _DX_PTZ_ACT_START , 0 );
}
void CPelcoDX8100Ctrl::Irisclose()
{
DxPTZActCtrl(m_hServer,m_nCameraId,_DXPTZ_IRIS_CLOSE | _DX_PTZ_ACT_START , 0 );
}
void CPelcoDX8100Ctrl::Irisopen()
{
DxPTZActCtrl(m_hServer,m_nCameraId,_DXPTZ_IRIS_OPEN | _DX_PTZ_ACT_START , 0 );
}
void CPelcoDX8100Ctrl::PrptStop()
{
DxPTZActCtrl(m_hServer,m_nCameraId, _DX_PTZ_ACT_STOP , 0 );
}
void CPelcoDX8100Ctrl::Ptzdown()
{
DxPTZActCtrl(m_hServer,m_nCameraId,_DXPTZ_MOVE_BOTTOM | _DX_PTZ_ACT_START , GetPTZSpeed());
}
void CPelcoDX8100Ctrl::Ptzleft()
{
DxPTZActCtrl(m_hServer,m_nCameraId,_DXPTZ_MOVE_LEFT | _DX_PTZ_ACT_START , GetPTZSpeed());
}
void CPelcoDX8100Ctrl::Ptzright()
{
DxPTZActCtrl(m_hServer,m_nCameraId,_DXPTZ_MOVE_RIGHT | _DX_PTZ_ACT_START, GetPTZSpeed());
}
void CPelcoDX8100Ctrl::Ptzup()
{
DxPTZActCtrl(m_hServer,m_nCameraId,_DXPTZ_MOVE_TOP | _DX_PTZ_ACT_START , GetPTZSpeed());
}
void CPelcoDX8100Ctrl::PtzDL()
{
DxPTZActCtrl(m_hServer,m_nCameraId,_DXPTZ_MOVE_DL | _DX_PTZ_ACT_START , GetPTZSpeed());
}
void CPelcoDX8100Ctrl::PtzDR()
{
DxPTZActCtrl(m_hServer,m_nCameraId,_DXPTZ_MOVE_DR | _DX_PTZ_ACT_START , GetPTZSpeed());
}
void CPelcoDX8100Ctrl::PtzUL()
{
DxPTZActCtrl(m_hServer,m_nCameraId,_DXPTZ_MOVE_UL | _DX_PTZ_ACT_START , GetPTZSpeed());
}
void CPelcoDX8100Ctrl::PtzUR()
{
DxPTZActCtrl(m_hServer,m_nCameraId,_DXPTZ_MOVE_UR | _DX_PTZ_ACT_START , GetPTZSpeed());
}
void CPelcoDX8100Ctrl::Ptzstop()
{
DxPTZActCtrl(m_hServer,m_nCameraId,_DXPTZ_MOVE_LEFT | _DX_PTZ_ACT_STOP , GetPTZSpeed());
}
void CPelcoDX8100Ctrl::Zoomin()
{
DxPTZActCtrl(m_hServer,m_nCameraId,_DXPTZ_ZOOM_IN | _DX_PTZ_ACT_START , 0 );
}
void CPelcoDX8100Ctrl::Zoomout()
{
DxPTZActCtrl(m_hServer,m_nCameraId,_DXPTZ_ZOOM_OUT | _DX_PTZ_ACT_START , 0 );
}
void CPelcoDX8100Ctrl::Presetgoto()
{
if(m_nCameraId == -1 ) return;
::DxPTZActCtrl(m_hServer,m_nCameraId,_DXPTZ_GOTO_PRESET, m_sPresetId );
}
void CPelcoDX8100Ctrl::Presetset()
{
if(m_nCameraId == -1 ) return;
::DxPTZActCtrl(m_hServer,m_nCameraId,_DXPTZ_SET_PRESET, m_sPresetId );
}
void CPelcoDX8100Ctrl::Presetreset()
{
if(m_nCameraId == -1 ) return;
::DxPTZActCtrl(m_hServer,m_nCameraId,_DXPTZ_REMOVE_PRESET, m_sPresetId );
}
short CPelcoDX8100Ctrl::GetPresetId()
{
return m_sPresetId;
}
void CPelcoDX8100Ctrl::SetPresetId(short nNewValue)
{
m_sPresetId = nNewValue;
SetModifiedFlag();
}
void CPelcoDX8100Ctrl::ChangePlaybackSpeed()
{
_GetPlaybackOption();
}
Re: Access violation MFC/C++
Have you run it in the debugger to see where in the code it's getting this access violation?
Viggy
Re: Access violation MFC/C++
Well, I'm not going to try to understand all that. A few comments though....
This seems suspicious:
Code:
g_pOverlayWnd = NULL;
delete g_pOverlayWnd;
But even if you fix that, you're still dealing with raw pointers, which are error-prone. You'd be better off using smart pointers. Which compiler you have determines how easy that is, of course; anything very old and you'll have to rely on Boost for the good ones (std::auto_ptr is not recommended).
You are using memset() and memcpy() a lot. These are C functions, not designed to work with C++ objects. They'll be fine so long as your objects are plain-old-data, but if they have nontrivial constructors/destructors, virtual functions, or contain any objects with such, then you'll need to stop using them. Prefer std::fill() to memset() and std::copy() to memcpy().
You are using global variables. Occasionally useful, but always suspect, particularly in a multithreaded environment.
Re: Access violation MFC/C++
Thanks both for the quick replies. Unfortunantley Im having to write this .ocx in VC++ 6.0 because the vendor code api is not supported on anything other than Windows XP, Server 2003. We originally tried writting it in C++ 2010 but direct draw wasn't playing nice. So we put togather an XP machine with VC++ 6.0.
How can I better handle the following?
g_pOverlayWnd = NULL;
delete g_pOverlayWnd;
I've tried numerous ways and this was the only way to get it to properly destroy the global overlay.
We have to use the globals because the API uses static callbacks to display the overlay window on top of the control.
I have used the debugger but the call stack it returns is useless, seems like the access violation is bubbling up all the way into iexplore.exe before the violation gets caught.
This entire project has been a mess since the beginning.
Re: Access violation MFC/C++
Quote:
How can I better handle the following?
g_pOverlayWnd = NULL;
delete g_pOverlayWnd;
I've tried numerous ways and this was the only way to get it to properly destroy the global overlay.
Well....you aren't destroying the overlay there. If that's the only way you could get it to not crash, then perhaps part of the overlay is corrupt?
Re: Access violation MFC/C++
You are calling delete on a pointer that points to NOTHING. Lindley is right, you aren't deleting anything.
Generally you call delete first, then set the pointer to NULL.
For example.. you have,
Code:
if(g_pOverlayWnd)
delete g_pOverlayWnd;
... you need to set the pointer to NULL after deleting.
Otherwise.. when you later on run..
Code:
if(g_pOverlayWnd && g_pOverlayWnd->yadda....)
Guess what, g_pOverlayWnd isn't null so its going to try to access its function, which will crash since you previously deleted it.
Re: Access violation MFC/C++
Quote:
Originally Posted by
lbargers
We have to use the globals because the API uses static callbacks to display the overlay window on top of the control.
Actually that is not a reason to use global variables. The Windows API uses callbacks, and MFC and other wrappers have been created for Windows programmers.
A properly written OO wrapper removes the need for globals.
Regards,
Paul McKenzie
Re: Access violation MFC/C++
Just a little aside note.
simply does NOTHING.
So...
Quote:
Code:
if(g_pOverlayWnd)
delete g_pOverlayWnd;
...is like massaging a wooden leg. :D