已卡我100个小时----pxa310 wince6.0 camera 驱动问题

nanhe   2010-1-26 17:10 楼主
    正在调试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传递进来。这个问题如同卡住了我的喉咙,让我窒息了好几天,没有任何进展。
    高手快快出现吧,帮帮我这可怜的人吧。

回复评论 (27)

自己先顶一个再说!
点赞  2010-1-26 17:35
我再顶!!!
点赞  2010-1-26 17:40
先帮顶下。

MARK.
点赞  2010-1-26 18:36
S3c6410下的寄存器
[HKEY_LOCAL_MACHINE\Drivers\Capture\Camera]
        "MemoryModel"=dword:2
        "PinCount"=dword:3
关系到CSPROPERTY_BUFFER_MODE,不知道楼主配得是几,楼主配成2或者4试下
点赞  2010-1-26 18:44
引用: 引用 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;
    }
点赞  2010-1-26 19:13
楼主能不能Trace下,给多点调试信息。
点赞  2010-1-26 19:50
顶,学习
点赞  2010-1-26 19:51
当运行摄像应用程序时,无法预览。驱动程序就在 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()也分配成功了。
点赞  2010-1-26 21:24
其主要困难不太清楚,DShow应用程序与camera驱动buffer的传递机制,什么时候应用程序分配buffer,什么时候Dshow应用程序把ideal状态下的buffer传递给驱动,让其处理。现在是Dshow应用程序传递进来的buffer地址为空。
点赞  2010-1-26 21:28
我再顶上去。
点赞  2010-1-27 08:22
引用: 引用 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的个数了.
楼主试下是否有这个问题
点赞  2010-1-27 10:01
好像pCsAllocatorFraming->Frames传过来的大小为10.
改为pCsAllocatorFraming->Frames = m_ulMaxNumOfBuffers之后,
                                |->Pin_IOControl( , , ,pOutbuf,,,)
                            | |-> case IOCTL_CS_BUFFERS:
                            | | |->case CS_ENQUEUE:
                            | | | |->EnqueueDescriptor( pCsDescriptor )
这个函数调用都不调用了。
   愁人呀。
点赞  2010-1-27 11:07
我再顶,等高人!
点赞  2010-1-27 12:50
能否把开始启动摄像头到出错的所有信息都贴上来看看.方便分析
点赞  2010-1-27 13:51
引用: 引用 14 楼 terryzou 的回复:
能否把开始启动摄像头到出错的所有信息都贴上来看看.方便分析

\\\
PIN_IOControl: RemoveBufferFromList-dwCounter is 0
PIN_IOControl: RemoveBufferFromList-*ppMappedData is NULL
\\\\
\\\
就这样循环下去
点赞  2010-1-27 13:55
因为在RemoveBufferFromList()函数中有下面的循环

while(( dwCounter < m_dwBufferCount ) && ( *ppCsStreamDesc == NULL ))

  、、、

就死在这里面。
点赞  2010-1-27 13:57
引用: 引用 16 楼 loongdao777 的回复:
因为在RemoveBufferFromList()函数中有下面的循环

while(( dwCounter < m_dwBufferCount ) && ( *ppCsStreamDesc == NULL ))

? 、、、

就死在这里面。

不应该死在这里的,因为m_dwBufferCount是你设定的BUff的个数,而dwCounter每循环一次都会加1,你查查你的m_dwBufferCount是多少。
个人感觉还是BUFF没有开成功,楼主看看运行时,内存用掉多少,会不会已经用光了
点赞  2010-1-27 14:10
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);
}
点赞  2010-1-27 14:13
引用: 引用 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。
   
点赞  2010-1-27 14:26
12下一页
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复