📄 camerapdd.cpp
字号:
if (ulModeType == CAPTURE)
{
if (!AllocateHWBuffers(VIDEO_CAPTURE_BUFFER) )
{
RETAILMSG(ZONE_ERROR, ( _T("InitSensorMode: AllocateHWBuffers() failed\r\n") ) );
hr = ERROR_INSUFFICIENT_BUFFER;
goto ErrorExit;
}
}
else if (ulModeType == STILL)
{
if (!AllocateHWBuffers(STILL_CAPTURE_BUFFER))
{
RETAILMSG(ZONE_ERROR, ( _T("InitSensorMode: AllocateHWBuffers() failed\r\n") ) );
hr = ERROR_INSUFFICIENT_BUFFER;
goto ErrorExit;
}
}
else
{
hr = ERROR_INVALID_PARAMETER;
goto ErrorExit;
}
m_ppModeContext[ulModeType] = ModeContext;
ErrorExit:
return hr;
}
DWORD CCameraPdd::DeInitSensorMode( ULONG ulModeType )
{
DWORD hr = ERROR_SUCCESS;
if (ulModeType == CAPTURE)
{
if (!DeAllocateHWBuffers(VIDEO_CAPTURE_BUFFER) )
{
RETAILMSG(ZONE_ERROR, ( _T("DeInitSensorMode: DeAllocateHWBuffers() failed\r\n") ) );
goto ErrorExit;
}
}
else if (ulModeType == STILL)
{
if (!DeAllocateHWBuffers(STILL_CAPTURE_BUFFER))
{
RETAILMSG(ZONE_ERROR, ( _T("DeInitSensorMode: DeAllocateHWBuffers() failed\r\n") ) );
goto ErrorExit;
}
}
else
{
hr = ERROR_INVALID_PARAMETER;
goto ErrorExit;
}
ErrorExit:
return hr;
}
DWORD CCameraPdd::SetSensorState( ULONG lModeType, CSSTATE csState )
{
DWORD dwError = ERROR_SUCCESS;
switch ( csState )
{
case CSSTATE_STOP:
m_CsState[lModeType] = CSSTATE_STOP;
if( (m_CsPrevState[lModeType] == CSSTATE_RUN) &&
(lModeType == CAPTURE))
{
StopHWCapture( );
}
m_CsPrevState[lModeType] = CSSTATE_STOP;
break;
case CSSTATE_PAUSE:
m_CsState[lModeType] = CSSTATE_PAUSE;
if( (m_CsPrevState[lModeType] == CSSTATE_RUN) &&
(lModeType == CAPTURE))
{
StopHWCapture( );
}
m_CsPrevState[lModeType] = CSSTATE_PAUSE;
break;
case CSSTATE_RUN:
ASSERT(lModeType == CAPTURE);
if (!m_bStillInProgress)
{
m_CsState[lModeType] = CSSTATE_RUN;
m_CsPrevState[lModeType] = CSSTATE_RUN;
if (!StartHWCapture())
{
RETAILMSG(ZONE_ERROR, ( _T("SetSensorState: StartHWCapture() failed\r\n") ) );
}
}
break;
default:
DEBUGMSG( ZONE_IOCTL|ZONE_ERROR, ( _T("IOControl(%08x): Incorrect State\r\n"), this ) );
dwError = ERROR_INVALID_PARAMETER;
}
return dwError;
}
DWORD CCameraPdd::TakeStillPicture( LPVOID pBurstModeInfo )
{
DWORD dwError = ERROR_SUCCESS;
//Ignore pBurstModeInfo
m_CsState[STILL] = CSSTATE_RUN;
m_bStillInProgress = TRUE;
PauseCapture();
if (!CaptureHWStillImage())
{
RETAILMSG(ZONE_ERROR, ( _T("TakeStillPicture: CaptureHWStillImage() failed\r\n") ) );
}
return dwError;
}
bool
CCameraPdd::PauseCapture( void )
{
if (m_CsState[CAPTURE]== CSSTATE_RUN)
{
SetSensorState(CAPTURE, CSSTATE_PAUSE);
}
return true;
}
DWORD CCameraPdd::GetSensorModeInfo( ULONG ulModeType, PSENSORMODEINFO pSensorModeInfo )
{
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];
return ERROR_SUCCESS;
}
DWORD CCameraPdd::SetSensorModeFormat( ULONG ulModeType, PCS_DATARANGE_VIDEO pCsDataRangeVideo )
{
// 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 chech it here.
// As we support only one mode for each type(Still and Preview), we need not to change
// the format. These formats are already set.
memcpy( &m_CurrentFormat[ulModeType], pCsDataRangeVideo, sizeof ( CS_DATARANGE_VIDEO ) );
return ERROR_SUCCESS;
}
PVOID CCameraPdd::AllocateBuffer( ULONG ulModeType )
{
// In this PDD, we dont need it
return NULL;
}
DWORD CCameraPdd::DeAllocateBuffer( ULONG ulModeType, PVOID pBuffer )
{
return ERROR_SUCCESS;
}
DWORD CCameraPdd::RegisterClientBuffer( ULONG ulModeType, PVOID pBuffer )
{
// In this PDD, we dont need it.
return ERROR_SUCCESS;
}
DWORD CCameraPdd::UnRegisterClientBuffer( ULONG ulModeType, PVOID pBuffer )
{
// 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
// This PDD does not use any cached pointers.
return ERROR_SUCCESS;
}
DWORD CCameraPdd::HandleSensorModeCustomProperties( ULONG ulModeType, PUCHAR pInBuf, DWORD InBufLen, PUCHAR pOutBuf, DWORD OutBufLen, PDWORD pdwBytesTransferred )
{
DEBUGMSG( ZONE_IOCTL, ( _T("IOControl: Unsupported PropertySet Request\r\n")) );
return ERROR_NOT_SUPPORTED;
}
bool CCameraPdd::AllocateHWBuffers( ULONG ucBufferType )
{
P_CAMERA_DMA_BUFFER_INFO pCamDmaBuf;
// Allocate buffers for motion video and still image
for (int i = 0; i < (VIDEO_CAPTURE_BUFFER == ucBufferType ? MAX_HW_FRAMES : 1); i++)
{
pCamDmaBuf = VIDEO_CAPTURE_BUFFER == ucBufferType ? &(m_CameraHWVideoBuffers[i]) : &m_CameraHWStillBuffer;
// Set the size field to 0x0 so we can query to find what size we need
// The driver will fill in the size field for us.
// Then add 4K to that so that we have room to 4K align the buffer.
pCamDmaBuf->size = 0;
CameraPrepareBuffer(pCamDmaBuf, ucBufferType);
// Must 4K align the memory
pCamDmaBuf->pBuf = reinterpret_cast<DWORD *>(malloc(pCamDmaBuf->size + 4096));
if (pCamDmaBuf->pBuf == 0x0)
{
DEBUGMSG(ZONE_FUNCTION|ZONE_ERROR, (_T("AllocateHWBuffers: Not enough memory to allocate %d bytes for Camera Buffer.\r\n"), pCamDmaBuf->size)) ;
return false;
}
pCamDmaBuf->VirtAddr = reinterpret_cast<DWORD>(pCamDmaBuf->pBuf);
// Align the buffer to 4K boundary
if (pCamDmaBuf->VirtAddr & 0xFFF)
{
pCamDmaBuf->VirtAddr += 0x1000 - (pCamDmaBuf->VirtAddr & 0xFFF);
}
// Now that we have allocated enough memory, go ahead and prepare the buffer
if (!CameraPrepareBuffer(pCamDmaBuf, ucBufferType))
{
DEBUGMSG(ZONE_FUNCTION|ZONE_ERROR, (_T("AllocateHWBuffers: Unable to prepare DMA buffer.\r\n"), pCamDmaBuf->size)) ;
return false;
}
// Set the DMA buffer memory to uncacheable, unbufferable
VirtualSetAttributes(reinterpret_cast<void *>(pCamDmaBuf->VirtAddr), pCamDmaBuf->size, 0, 0xC, NULL);
DEBUGMSG(ZONE_INIT, (_T("AllocateHWBuffers: Buffer allocated for %s pin [0x%08x - %d bytes].\r\n"),\
STILL_CAPTURE_BUFFER == ucBufferType ? L"still" : L"capture/preview", pCamDmaBuf->VirtAddr, pCamDmaBuf->size));
}
return true;
}
bool CCameraPdd::DeAllocateHWBuffers( ULONG ucBufferType )
{
P_CAMERA_DMA_BUFFER_INFO pCamDmaBuf;
// DeAllocate buffers for motion video and still image
for (int i = 0; i < (VIDEO_CAPTURE_BUFFER == ucBufferType ? MAX_HW_FRAMES : 1); i++)
{
pCamDmaBuf = VIDEO_CAPTURE_BUFFER == ucBufferType ? &(m_CameraHWVideoBuffers[i]) : &m_CameraHWStillBuffer;
if (pCamDmaBuf->pBuf)
{
CameraUnprepareBuffer(pCamDmaBuf, ucBufferType);
free(pCamDmaBuf->pBuf);
pCamDmaBuf->pBuf = NULL;
DEBUGMSG(ZONE_INIT, (_T("DeAllocateHWBuffers: Buffer deallocated for %s pin [0x%08x - %d bytes].\r\n"),\
STILL_CAPTURE_BUFFER == ucBufferType ? L"still" : L"capture/preview", pCamDmaBuf->VirtAddr, pCamDmaBuf->size));
}
}
return true;
}
bool CCameraPdd::GetCurrentHWBuffer(
ULONG ulPinId,
P_CAMERA_DMA_BUFFER_INFO pCamDmaBuffer
)
{
bool fRet = false;
if( NULL != pCamDmaBuffer)
{
if (CeSafeCopyMemory( pCamDmaBuffer, (STILL == ulPinId) ? &m_CameraHWStillBuffer : &m_CameraHWVideoBuffers[m_ulCurrentFrame],
sizeof(CAMERA_DMA_BUFFER_INFO)))
fRet = true;
}
return fRet;
}
bool CCameraPdd::StartHWCapture( )
{
if (!m_bCameraHWRunning)
{
// Mainstone II: Start streaming video out of sensor
DEBUGMSG( ZONE_WARN, ( _T("StartHWCapture(%08x): run camera sensor\r\n"), this ) );
// Reset current frame counter
m_ulCurrentFrame = 0;
// Submit the h/w dma buffers to the camera driver.
for (int i = 0; i < MAX_HW_FRAMES; i++)
{
CameraSubmitBuffer(&m_CameraHWVideoBuffers[i], VIDEO_CAPTURE_BUFFER);
}
CameraStartVideoCapture();
m_bCameraHWRunning = true;
}
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -