正在调试camera驱动,用的是Marvell公司给的微软写的camera驱动框架,已经可以对ov2655芯片进行寄存器的读与写。运行摄像应用程序时,驱动就卡在了
|->Pin_IOControl( , , ,pOutbuf,,,)
| |-> case IOCTL_CS_BUFFERS:
| | |->case CS_ENQUEUE:
| | | |->EnqueueDescriptor( pCsDescriptor )
错误之处就是应用程序调用Pin_IoControl时,那个pOutbuf为NULL,故传递到EnqueueDescriptor( pCsDescriptor )中的pCsDescriptor也就为空了。这样,应用程序无法让camera驱动对buffer进行处理。真不知道为什么应用程序无法把pOutbuf传递进来。这个问题如同卡住了我的喉咙,让我窒息了好几天,没有任何进展。
高手快快出现吧,帮帮我这可怜的人吧。
引用: 引用 4 楼 terryzou 的回复:
S3c6410下的寄存器
[HKEY_LOCAL_MACHINE\Drivers\Capture\Camera]
"MemoryModel"=dword:2
"PinCount"=dword:3
关系到CSPROPERTY_BUFFER_MODE,不知道楼主配得是几,楼主配成2或者4试下
楼上的,我在驱动中直接把MemoryMode指定为BUFFER_CLIENT_UNLIMITED;如下:
m_SensorModeInfo[CAPTURE].MemoryModel = CSPROPERTY_BUFFER_CLIENT_UNLIMITED;
m_SensorModeInfo[CAPTURE].MaxNumOfBuffers = 1;
m_SensorModeInfo[CAPTURE].PossibleCount = 1;
m_SensorModeInfo[STILL].MemoryModel = CSPROPERTY_BUFFER_CLIENT_UNLIMITED;
m_SensorModeInfo[STILL].MaxNumOfBuffers = 1;
m_SensorModeInfo[STILL].PossibleCount = 1;
if( 3 == m_ulCTypes )
{
m_SensorModeInfo[PREVIEW].MemoryModel = CSPROPERTY_BUFFER_CLIENT_UNLIMITED;
m_SensorModeInfo[PREVIEW].MaxNumOfBuffers = 1;
m_SensorModeInfo[PREVIEW].PossibleCount = 1;
}
当运行摄像应用程序时,无法预览。驱动程序就在 RemoveBufferFromList()中的
while(( dwCounter < m_dwBufferCount ) && ( *ppCsStreamDesc == NULL ))
{
if( m_pStreamDescriptorList[ dwCounter ].pCsStreamDescriptorExternal != NULL )
{
__try
{
// We found one registered buffer. Let's return it.
*ppCsStreamDesc = m_pStreamDescriptorList[ dwCounter ].pCsStreamDescriptorExternal;
*ppMappedData = m_pStreamDescriptorList[ dwCounter ].csStreamDescriptorShadow.CsStreamHeader.Data; *ppUnmappedData = m_pStreamDescriptorList[ dwCounter ].pCsStreamDescriptorExternal->CsStreamHeader.Data;
m_pStreamDescriptorList[ dwCounter ].pCsStreamDescriptorExternal = NULL;
m_pStreamDescriptorList[ dwCounter ].csStreamDescriptorShadow.CsStreamHeader.Data = *ppUnmappedData;
break;
}
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
{
DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("PIN_IOControl: RemoveBufferFromList - Access Violation.\r\n"))) ;
RetVal = false;
}
}
dwCounter++;
}
LeaveCriticalSection( &m_csStreamBuffer );
if(NULL == *ppMappedData)
{
RetVal = false;
}
既*ppCsStreamDesc 和*ppMappedData 始终为NULL,在m_pStreamDescriptorList[]取不到可用地址。
经过进一步跟踪,发现EnqueueDescriptor( pCsDescriptor ) 这个函数没有执行,因为其参数为空。
微软说,应用程序是通过这个函数把buffer传递进来供驱动使用的。就是不明白,为什么buffer没有传进来。在Allocatebuffer()也分配成功了。
引用: 引用 5 楼 loongdao777 的回复:
引用 4 楼 terryzou 的回复:
S3c6410下的寄存器
[HKEY_LOCAL_MACHINE\Drivers\Capture\Camera]
"MemoryModel"=dword:2
"PinCount"=dword:3
关系到CSPROPERTY_BUFFER_MODE,不知道楼主配得是几,楼主配成2或者4试下
楼上的,我在驱动中直接把MemoryMode指定为BUFFER_CLIENT_UNLIMITED;如下:
? ? ? m_SensorModeInfo[CAPTURE].MemoryModel = CSPROPERTY_BUFFER_CLIENT_UNLIMITED;
? ? m_SensorModeInfo[CAPTURE].MaxNumOfBuffers = 1;
? ? m_SensorModeInfo[CAPTURE].PossibleCount = 1;
? ? m_SensorModeInfo[STILL].MemoryModel = CSPROPERTY_BUFFER_CLIENT_UNLIMITED;
? ? m_SensorModeInfo[STILL].MaxNumOfBuffers = 1;
? ? m_SensorModeInfo[STILL].PossibleCount = 1;
? ? if( 3 == m_ulCTypes )
? ? {
? ? ? ? m_SensorModeInfo[PREVIEW].MemoryModel = CSPROPERTY_BUFFER_CLIENT_UNLIMITED;
? ? ? ? m_SensorModeInfo[PREVIEW].MaxNumOfBuffers = 1;
? ? ? ? m_SensorModeInfo[PREVIEW].PossibleCount = 1;
? ? }
感觉是allocbuff的时候,没有成功,所以Dshow才会传空的BUFF过来,楼主把BUFF数量配为1,这个会在PinHandleConnectionRequests下的Iotctl为CSPROPERTY_TYPE_SET的时候重新给其值:
m_ulMaxNumOfBuffers = pCsAllocatorFraming->Frames ;这里是Microsoft建议的BUff数量,如果你不需要这么多BUFF,可以试着改为pCsAllocatorFraming->Frames = m_ulMaxNumOfBuffers;这样,用户就可以自己去定义BUFF的个数了.
楼主试下是否有这个问题
好像pCsAllocatorFraming->Frames传过来的大小为10.
改为pCsAllocatorFraming->Frames = m_ulMaxNumOfBuffers之后,
|->Pin_IOControl( , , ,pOutbuf,,,)
| |-> case IOCTL_CS_BUFFERS:
| | |->case CS_ENQUEUE:
| | | |->EnqueueDescriptor( pCsDescriptor )
这个函数调用都不调用了。
愁人呀。
BOOL CGPIODLLApp::CameraOpen(int width, int height)
{
//打开驱动
Camerahl = CreateFile (_T("CIS1:"), GENERIC_WRITE|GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
if(Camerahl==INVALID_HANDLE_VALUE )
{
return FALSE;
}
//打开摄像头
DeviceIoControl(Camerahl,CAM_IOCTL_MOVIE_START,NULL,0,NULL,0,NULL,NULL);
DeviceIoControl(Camerahl,IOCTL_CAM_SETGAMMA,NULL,0,NULL,0,NULL,NULL);
unsigned char i,pOut;
unsigned char inbuffer320240[][2]={
{ 0xfc, 0x00},
{ 0x02, 0x03}, // 1600*1200//00 02
{ 0xfc, 0x01},
{ 0x02, 0x77}
};// 03 OK 07 1OK;
unsigned char inbuffer640480[][2]={
{ 0xfc, 0x00},
{ 0x02, 0x02}, // 1600*1200//00 02
{ 0xfc, 0x01},
{ 0x02, 0x67}
};// 03 OK 07 1OK;
unsigned char inbuffer12801024[][2]={
{ 0xfc, 0x00},
{ 0x02, 0x01}, // 1600*1200//00 02
{ 0xfc, 0x01},
{ 0x02, 0x57}
};// 03 OK 07 1OK;
if( width==320 && height==240)
{
for(i=0;i<=(sizeof(inbuffer320240)/2);i++)
{
DeviceIoControl(Camerahl,IOCTL_CAM_WRITEREG, inbuffer320240, 2,&pOut ,1, NULL, NULL);
}
pOut=3;
DeviceIoControl(Camerahl,IOCTL_CAM_SETSCALE, &i, 1,&pOut ,1, NULL, NULL);
DeviceIoControl(Camerahl,CAM_IOCTL_MOVIE_START,NULL,0,NULL,0,NULL,NULL);
DeviceIoControl(Camerahl,IOCTL_CAM_SETGAMMA,NULL,0,NULL,0,NULL,NULL);
}
else if( width==640 && height==480)
{
for(i=0;i<=(sizeof(inbuffer640480)/2);i++)
{
DeviceIoControl(Camerahl,IOCTL_CAM_WRITEREG, inbuffer640480, 2,&pOut ,1, NULL, NULL);
}
pOut=2;
DeviceIoControl(Camerahl,IOCTL_CAM_SETSCALE, &i, 1,&pOut ,1, NULL, NULL);
DeviceIoControl(Camerahl,CAM_IOCTL_MOVIE_START,NULL,0,NULL,0,NULL,NULL);
DeviceIoControl(Camerahl,IOCTL_CAM_SETGAMMA,NULL,0,NULL,0,NULL,NULL);
}
else if( width==1280 && height==1024)
{
for(i=0;i<=(sizeof(inbuffer12801024)/2);i++)
{
DeviceIoControl(Camerahl,IOCTL_CAM_WRITEREG, inbuffer12801024, 2,&pOut ,1, NULL, NULL);
}
pOut=1;
DeviceIoControl(Camerahl,IOCTL_CAM_SETSCALE, &i, 1,&pOut ,1, NULL, NULL);
DeviceIoControl(Camerahl,CAM_IOCTL_MOVIE_START,NULL,0,NULL,0,NULL,NULL);
DeviceIoControl(Camerahl,IOCTL_CAM_SETGAMMA,NULL,0,NULL,0,NULL,NULL);
}
else
{
return FALSE;
}
return TRUE;
}
void CGPIODLLApp::CameraClose()
{
CloseHandle(Camerahl);
}
void CGPIODLLApp::CameraPhoto(unsigned char outBuff[])
{
char inBuff;
//读buffer操作 数据由pBufOut传出
DeviceIoControl(Camerahl,CAM_IOCTL_GET_LATEST_FRAME, &inBuff, sizeof(inBuff), outBuff ,sizeof(inBuff), NULL, NULL);
}
引用: 引用 17 楼 terryzou 的回复:
引用 16 楼 loongdao777 的回复:
因为在RemoveBufferFromList()函数中有下面的循环
while(( dwCounter < m_dwBufferCount ) && ( *ppCsStreamDesc == NULL ))
{
? 、、、
}
就死在这里面。
不应该死在这里的,因为m_dwBufferCount是你设定的BUff的个数,而dwCounter每循环一次都会加1,你查查你的m_dwBufferCount是多少。
个人感觉还是BUFF没有开成功,楼主看看运行时,内存用掉多少,会不会已经用光了
你分析的没问题,是我没表达清楚。
QCI中的DMA中断不停地调用HandlePinIO,而HandlePInIO在调用RemoveBufferFromList()时,里面的 while(( dwCounter < m_dwBufferCount ) && ( *ppCsStreamDesc == NULL ))
{
if( m_pStreamDescriptorList[ dwCounter ].pCsStreamDescriptorExternal != NULL )
{
、、、、
}
dwCounter++;
}
if语句无法进入,判断为NULL。
问题就这样。 m_pStreamDescriptorList[ dwCounter ].pCsStreamDescriptorExternal 始终为NULL。