📄 camera_pdd.cpp
字号:
RETAILMSG(MSG_INOUT,(TEXT("++++++++++++++++++++GetSensorModeInfo\n")));
pSensorModeInfo->MemoryModel = m_SensorModeInfo[ulModeType].MemoryModel;
pSensorModeInfo->MaxNumOfBuffers = m_SensorModeInfo[ulModeType].MaxNumOfBuffers;
pSensorModeInfo->PossibleCount = m_SensorModeInfo[ulModeType].PossibleCount;
pSensorModeInfo->VideoCaps.DefaultVideoControlCaps = DefaultVideoControlCaps[ulModeType];
pSensorModeInfo->VideoCaps.CurrentVideoControlCaps = m_pModeVideoCaps[ulModeType].CurrentVideoControlCaps;
pSensorModeInfo->pVideoFormat = &m_pModeVideoFormat[ulModeType];
RETAILMSG(MSG_INOUT,(TEXT("--------------------GetSensorModeInfo\n")));
return ERROR_SUCCESS;
}
DWORD CCameraPdd::SetSensorModeFormat( ULONG ulModeType, PCS_DATARANGE_VIDEO pCsDataRangeVideo )
{
RETAILMSG(MSG_INOUT,(TEXT("++++++++++++++++++++SetSensorModeFormat %d\n"),ulModeType));
// MDD will take care of ulModeType. It will never be out of range. MDD will also ask for
// the format we support. We need not to check it here.
memcpy( &m_pCurrentFormat[ulModeType], pCsDataRangeVideo, sizeof ( CS_DATARANGE_VIDEO ) );
return ERROR_SUCCESS;
}
PVOID CCameraPdd::AllocateBuffer( ULONG ulModeType )
{
RETAILMSG(MSG_INOUT,(TEXT("++++++++++++++++++++AllocateBuffer\n")));
// Real PDD may want to save off this allocated pointer
// in an array.
//ULONG ulFrameSize = CS__DIBSIZE (m_pCurrentFormat[ulModeType].VideoInfoHeader.bmiHeader);
// return RemoteLocalAlloc( LPTR, ulFrameSize );
// In this PDD, we dont need it
return NULL;
}
DWORD CCameraPdd::DeAllocateBuffer( ULONG ulModeType, PVOID pBuffer )
{
RETAILMSG(MSG_INOUT,(TEXT("++++++++++++++++++++DeAllocateBuffer\n")));
// RemoteLocalFree( pBuffer );
return ERROR_SUCCESS;
}
DWORD CCameraPdd::RegisterClientBuffer( ULONG ulModeType, PVOID pBuffer )
{
RETAILMSG(MSG_INOUT,(TEXT("++++++++++++++++++++RegisterClientBuffer\n")));
// Real PDD may want to save pBuffer which is a pointer to buffer that DShow created.
return ERROR_SUCCESS;
}
DWORD CCameraPdd::UnRegisterClientBuffer( ULONG ulModeType, PVOID pBuffer )
{
RETAILMSG(MSG_INOUT,(TEXT("++++++++++++++++++++UnRegisterClientBuffer\n")));
// DShow is not going to use pBuffer (which was originally allocated by DShow) anymore. If the PDD
// is keeping a cached pBuffer pointer (in RegisterClientBuffer()) then this is the right place to
// stop using it and maybe set the cached pointer to NULL.
// Note: PDD must not delete this pointer as it will be deleted by DShow itself
return ERROR_SUCCESS;
}
DWORD CCameraPdd::HandleSensorModeCustomProperties( ULONG ulModeType, PUCHAR pInBuf, DWORD InBufLen, PUCHAR pOutBuf, DWORD OutBufLen, PDWORD pdwBytesTransferred )
{
RETAILMSG(MSG_INOUT,(TEXT("++++++++++++++++++++HandleSensorModeCustomProperties\n")));
DEBUGMSG( ZONE_IOCTL, ( _T("IOControl: Unsupported PropertySet Request\r\n")) );
return ERROR_NOT_SUPPORTED;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// The following code is only meant for this sample pdd
// The real PDD should not contain any of the code below.
// Instead the real PDD should implement its own FillPinBuffer()
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
extern "C" { WINGDIAPI HBITMAP WINAPI CreateBitmapFromPointer( CONST BITMAPINFO *pbmi, int iStride, PVOID pvBits); }
DWORD CCameraPdd::FillBuffer( ULONG ulModeType, PUCHAR pImage )
{
DWORD dwRet = 0;
INT CurrentFrame;
PCS_VIDEOINFOHEADER pCsVideoInfoHdr = &m_pCurrentFormat[ulModeType].VideoInfoHeader;
RETAILMSG(MSG_INOUT,(TEXT("++++++++++++++++++++FillBuffer\n")));
ASSERT(pCsVideoInfoHdr->bmiHeader.biSizeImage != 0);
if(pImage == NULL)
{
RETAILMSG(MSG_ERROR,(TEXT("pImage is null!\n")));
return 0;
}
// MDD will make sure that the buffer is sufficient for the image.
if (ulModeType == CAPTURE)
{
CurrentFrame = CameraGetCurrentFrameNum(VIDEO_CAPTURE_BUFFER);
RETAILMSG(MSG_ON,(TEXT("m_CameraHWVideoBuffers[%d].VirtAddr=0x%x\n"),CurrentFrame,m_CameraHWVideoBuffers[CurrentFrame].VirtAddr));
dwRet = pCsVideoInfoHdr->bmiHeader.biSizeImage;
memcpy(pImage, (void *)m_CameraHWVideoBuffers[CurrentFrame].VirtAddr, dwRet);
}
else if (ulModeType == STILL)
{
CurrentFrame = CameraGetCurrentFrameNum(STILL_CAPTURE_BUFFER);
RETAILMSG(MSG_ON,(TEXT("m_CameraHWStillBuffer.VirtAddr=0x%x\n"),m_CameraHWStillBuffer.VirtAddr));
dwRet = pCsVideoInfoHdr->bmiHeader.biSizeImage;
memcpy(pImage, (void *)m_CameraHWStillBuffer.VirtAddr, dwRet);
}
else if(ulModeType == PREVIEW)
{
CurrentFrame = CameraGetCurrentFrameNum(PREVIEW_CAPTURE_BUFFER);
dwRet = pCsVideoInfoHdr->bmiHeader.biSizeImage;
RETAILMSG(MSG_ON,(TEXT("m_CameraHWPreviewBuffers[%d].VirtAddr=0x%x\n"),CurrentFrame,m_CameraHWPreviewBuffers[CurrentFrame].VirtAddr));
memcpy(pImage, (void *)m_CameraHWPreviewBuffers[CurrentFrame].VirtAddr, dwRet);
}
RETAILMSG(MSG_INOUT,(TEXT("--------------------FillBuffer\n")));
// return the size of the image filled
return dwRet;
}
void CCameraPdd :: HandleCaptureInterrupt( ULONG ulModeTypeIn )
{
ULONG ulModeType;
RETAILMSG(MSG_INOUT,(TEXT("++++++++++++++++++++HandleCaptureInterrupt\n")));
if( m_bStillCapInProgress )
{
return;
}
if( ulModeTypeIn == CAPTURE)
{
ulModeType = CAPTURE;
}
else if ( m_ulCTypes == 3 && ulModeTypeIn == PREVIEW )
{
ulModeType = PREVIEW;
}
else
{
ASSERT(false);
return;
}
MDD_HandleIO( m_ppModeContext[ulModeType], ulModeType );
RETAILMSG(MSG_INOUT,(TEXT("------------------------HandleCaptureInterrupt %d\n"),ulModeType));
}
void CCameraPdd :: HandleStillInterrupt( )
{
RETAILMSG(MSG_INOUT,(TEXT("++++++++++++++++++++HandleStillInterrupt\n")));
MDD_HandleIO( m_ppModeContext[STILL], STILL );
m_bStillCapInProgress = false;
RETAILMSG(MSG_INOUT,(TEXT("--------------------HandleStillInterrupt\n")));
}
bool CCameraPdd::ReadMemoryModelFromRegistry()
{
HKEY hKey = 0;
DWORD dwType = 0;
DWORD dwSize = sizeof ( DWORD );
DWORD dwValue = -1;
RETAILMSG(MSG_INOUT,(TEXT("++++++++++++++++++++ReadMemoryModelFromRegistry\n")));
if( ERROR_SUCCESS != RegOpenKeyEx( HKEY_LOCAL_MACHINE, L"Drivers\\Capture\\Camera", 0, 0, &hKey ))
{
false;
}
if( ERROR_SUCCESS == RegQueryValueEx( hKey, L"MemoryModel", 0, &dwType, (BYTE *)&dwValue, &dwSize ) )
{
if( ( REG_DWORD == dwType )
&& ( sizeof( DWORD ) == dwSize )
&& (( dwValue == CSPROPERTY_BUFFER_DRIVER ) || ( dwValue == CSPROPERTY_BUFFER_CLIENT_LIMITED ) || ( dwValue == CSPROPERTY_BUFFER_CLIENT_UNLIMITED )))
{
for( int i=0; i<MAX_SUPPORTED_PINS ; i++ )
{
m_SensorModeInfo[i].MemoryModel = (CSPROPERTY_BUFFER_MODE) dwValue;
}
}
}
// Find out if we should be using some other number of supported modes. The only
// valid options are 2 or 3. Default to 2.
if ( ERROR_SUCCESS == RegQueryValueEx( hKey, L"PinCount", 0, &dwType, (BYTE *)&dwValue, &dwSize ) )
{
if ( REG_DWORD == dwType
&& sizeof ( DWORD ) == dwSize
&& 3 == dwValue )
{
m_ulCTypes = 3;
}
}
RegCloseKey( hKey );
return true;
}
bool CCameraPdd::AllocateHWBuffers(P_CAMERA_DMA_BUFFER_INFO pCamDmaBuf, ULONG ucBufferType)
{
RETAILMSG(MSG_INOUT,(TEXT("++++++++++++++++++++AllocateHWBuffers\n")));
return TRUE;
}
bool CCameraPdd::DeAllocateHWBuffers(ULONG ucBufferType)
{
RETAILMSG(MSG_INOUT,(TEXT("++++++++++++++++++++DeAllocateHWBuffers\n")));
return TRUE;
}
bool CCameraPdd::SetSensorFormat( ULONG ulModeType)
{
RETAILMSG(MSG_INOUT,(TEXT("++++++++++++++++++++SetSensorFormat\n")));
INT format;
PCS_VIDEOINFOHEADER pCsVideoInfoHdr = &m_pCurrentFormat[ulModeType].VideoInfoHeader;
UINT biWidth = pCsVideoInfoHdr->bmiHeader.biWidth;
UINT biHeight = abs(pCsVideoInfoHdr->bmiHeader.biHeight);
DWORD biBitCount = pCsVideoInfoHdr->bmiHeader.biBitCount;
DWORD biCompression = pCsVideoInfoHdr->bmiHeader.biCompression;
// Prepare buffers here for Preview and Still mode.
// Set Register for output
if ( (FOURCC_YUY2 == (biCompression & ~BI_SRCPREROTATE)))
{
format = OUTPUT_CODEC_YCBCR422;
}
else if((FOURCC_YV12 == (biCompression & ~BI_SRCPREROTATE)))
{
format = OUTPUT_CODEC_YCBCR420;
}
else
{
if(biBitCount == 24)
{
format = OUTPUT_CODEC_RGB24;
}
else
{
format = OUTPUT_CODEC_RGB16;
}
}
if (ulModeType == CAPTURE)
{
CameraSetFormat(biWidth, biHeight, format, VIDEO_CAPTURE_BUFFER);
if (!CameraPrepareBuffer(m_CameraHWVideoBuffers, VIDEO_CAPTURE_BUFFER) )
{
RETAILMSG(MSG_ERROR, ( _T("InitSensorMode: CameraPrepareBuffer() failed\r\n") ) );
return FALSE;
}
}
else if (ulModeType == STILL)
{
CameraSetFormat(biWidth, biHeight, format, STILL_CAPTURE_BUFFER);
if (!CameraPrepareBuffer(&m_CameraHWStillBuffer, STILL_CAPTURE_BUFFER))
{
RETAILMSG(MSG_ERROR, ( _T("InitSensorMode: CameraPrepareBuffer() failed\r\n") ) );
return FALSE;
}
}
else if(ulModeType == PREVIEW)
{
CameraSetFormat(biWidth, biHeight, format, PREVIEW_CAPTURE_BUFFER);
if (!CameraPrepareBuffer(m_CameraHWPreviewBuffers, PREVIEW_CAPTURE_BUFFER))
{
RETAILMSG(MSG_ERROR, ( _T("InitSensorMode: CameraPrepareBuffer() failed\r\n") ) );
return FALSE;
}
}
else
{
return FALSE;
}
return TRUE;
}
void CCameraPdd::SuspendCamera( )
{
if(m_bCameraVideoRunning)
{
m_bCameraVideoWasRunning = TRUE;
if (m_CsState[CAPTURE]== CSSTATE_RUN)
{
SetSensorState(CAPTURE, CSSTATE_PAUSE);
}
}
if(m_bCameraPreviewRunning)
{
m_bCameraPreviewWasRunning = TRUE;
if (m_CsState[PREVIEW]== CSSTATE_RUN)
{
SetSensorState(PREVIEW, CSSTATE_PAUSE);
}
}
if(m_iPinUseCount > 0)
{
CameraSleep();
CameraClockOn(FALSE);
}
}
void CCameraPdd::ResumeCamera( )
{
// Restart camera sensor if it was running before
if(m_iPinUseCount > 0)
{
CameraClockOn(TRUE);
CameraResume();
}
if(m_bCameraVideoWasRunning)
{
m_bCameraVideoWasRunning = FALSE;
SetSensorState(CAPTURE, CSSTATE_RUN);
}
if ( m_bCameraPreviewWasRunning )
{
m_bCameraPreviewWasRunning = FALSE;
SetSensorState(PREVIEW, CSSTATE_RUN);
}
}
void CameraVideoFrameCallback( DWORD dwContext )
{
CCameraPdd * pCamDevice = reinterpret_cast<CCameraPdd *>( dwContext );
// Video frame is ready - put it into stream
if (NULL != pCamDevice)
{
pCamDevice->HandleCaptureInterrupt(CAPTURE);
}
}
void CameraStillFrameCallback( DWORD dwContext )
{
CCameraPdd * pCamDevice = reinterpret_cast<CCameraPdd *>( dwContext );
// Still image frame is ready - put it into stream
if (NULL != pCamDevice)
{
pCamDevice->HandleStillInterrupt();
}
}
void CameraPreviewFrameCallback( DWORD dwContext )
{
CCameraPdd * pCamDevice = reinterpret_cast<CCameraPdd *>( dwContext );
// Video frame is ready - put it into stream
if (NULL != pCamDevice)
{
pCamDevice->HandleCaptureInterrupt(PREVIEW);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -