关于wince6.0 摄像头驱动分辨率设置,尤其是scaler功能使用的认识

作者:gooogleman@foxmail.com 

在DRIVERS\CAMERAFILTER\CAMERA_PDD\camera_pdd.cpp有

void

CCameraPdd::GetVideoFormatList(

   DWORD dwSensorID

   )

{

   RETAILMSG(CAM_INOUT,(_T("[%s] %s -dwSensorID=%d\r\n"), DBG_MSG_HEADER, _T(__FUNCTION__),dwSensorID));

   

   DWORD hr = ERROR_SUCCESS;

   int i;

   bool bForCETK=false;

   

//    bForCETK=IsForMSTestKit();

   

   switch ( dwSensorID )

   {

   case SYSLSI_OV3640:

       // Video Format initialization

       i = 0;

     

       m_pModeVideoFormat[CAPTURE].pCsDataRangeVideo[i++]  = &DCAM_StreamMode_YV12_640x480_30;     

       m_pModeVideoFormat[CAPTURE].ulAvailFormats          = i;

 

       // Still Format initialization

       i = 0;

 

       // With OV3640 Sensor module, IJPG is used forStill shot, and there is no test kit.

       // The user should dump the camera stilloutput pin buffer to check frame data

         // bForCETK=false

       if(bForCETK)

       {

            // CETKcan test only RGB format.

            //m_pModeVideoFormat[STILL].pCsDataRangeVideo[i++]    = &DCAM_StreamMode_RGB565_2048x1536_30;

              m_pModeVideoFormat[STILL].pCsDataRangeVideo[i++]    = &DCAM_StreamMode_YV12_2048x1536_30;

       }

       else

       {

            // UseDefault Format

            // YVformat also can be used. actually it shows faster performance than RGB format.

            //m_pModeVideoFormat[STILL].pCsDataRangeVideo[i++]    = &DCAM_StreamMode_RGB565_2048x1536_30;

              m_pModeVideoFormat[STILL].pCsDataRangeVideo[i++]    = &DCAM_StreamMode_YV12_2048x1536_30;

       }

       m_pModeVideoFormat[STILL].ulAvailFormats            = i;

        

       // if preview pins supports

       if( MAX_SUPPORTED_PINS == m_ulCTypes )

       {

            i = 0;

            if(bForCETK)    // bForCETK=false

            {

                //CETK can test only RGB format.

               m_pModeVideoFormat[PREVIEW].pCsDataRangeVideo[i++]  =&DCAM_StreamMode_RGB565_640x480_30;                           

            }

            else

            {

                // YVformat also can be used. actually it shows faster performance than RGB format.

               m_pModeVideoFormat[PREVIEW].pCsDataRangeVideo[i++]  = &DCAM_StreamMode_RGB565_640x480_30;                          

            }

           m_pModeVideoFormat[PREVIEW].ulAvailFormats          = i;

       }

 

       break;

   }

}

 

CAPTURE——录像从上面可以看出是DCAM_StreamMode_YV12_640x480_30 ,是YUV的640*480 的分辨率

STILL——拍照 : DCAM_StreamMode_YV12_2048x1536_30是 YUV 2048*1056 的分辨率

PREVIEW——预览 :DCAM_StreamMode_RGB565_640x480_30RGB565 格式 640*480 分辨率

这里我觉得有点奇怪的是,LCD 分辨率很多都只有320*240 ,为什么预览能够显示比LCD分辨率还大的图形呢?这个到底是怎么实现的?难道是在wince 显示驱动里面做了一些什么处理的?在电脑同样有这种显现,比如500W的摄像头是怎么在一个1440*900 的分辨率的显示器上显示出来的?这个摄像头显示分辨率比显示器的分辨率还大,这个是怎么处理的呢?!

         好,这次解决这个问题吧。

 

 

 

 

 

在这里有上面的参数传递配置信息

DWORD CCameraPdd::GetSensorModeInfo(ULONG ulModeType, PSENSORMODEINFO pSensorModeInfo )

{

   RETAILMSG(CAM_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(CAM_INOUT,(TEXT("--------------------GetSensorModeInfo\n")));

   return ERROR_SUCCESS;

}

 

 

在下面函数有

bool

CCameraDevice::GetPDDPinInfo()

{

   SENSORMODEINFO SensorModeInfo;

   if( NULL == m_pStrmInstances )

   {

       return false;

   }

 

   for( UINT i=0; i <m_AdapterInfo.ulCTypes; i++ )

   {

       if( ERROR_SUCCESS != PDDGetPinInfo( i, &SensorModeInfo ))

       {

            returnfalse ;

       }

       m_pStrmInstances[i].ulPossibleCount = SensorModeInfo.PossibleCount ;

       m_pStrmInstances[i].VideoCaps.DefaultVideoControlCaps =SensorModeInfo.VideoCaps.DefaultVideoControlCaps;

       m_pStrmInstances[i].VideoCaps.CurrentVideoControlCaps = SensorModeInfo.VideoCaps.CurrentVideoControlCaps;

       m_pStrmInstances[i].pVideoFormat= SensorModeInfo.pVideoFormat;

       

       if( SensorModeInfo.MemoryModel ==CSPROPERTY_BUFFER_DRIVER &&

            ( NULL ==m_PDDFuncTbl.PDD_AllocateBuffer || NULL == m_PDDFuncTbl.PDD_DeAllocateBuffer ))

       {

            returnfalse;

       }

 

       if( SensorModeInfo.MemoryModel !=CSPROPERTY_BUFFER_DRIVER &&

            ( NULL ==m_PDDFuncTbl.PDD_RegisterClientBuffer || NULL == m_PDDFuncTbl.PDD_UnRegisterClientBuffer) )

       {

            returnfalse;

       }

   }

 

   return true;

 

}

 

 

 

 

在底层驱动里面有这样设置输入的摄像头分辨率的

voidCameraHal::SetSourceRegister(int ituxxx, int uvoffset, intorder422, UINT32 hSize, UINT32 vSize)       // Set source registers

{

    EnterCriticalSection(&m_csHWregister);

 

   CAMIF_MSG((_T("[CAMIF] ++%s()\r\n"),_T(__FUNCTION__)));

// In Camera mode, this value can be YUV422 or IJPG  输入摄像头格式设置

m_currentContext.SourceFormat= CAM_FORMAT_YCBCR422_1PLANE;       m_currentContext.SourceOrder422 = order422;

   m_currentContext.SourceHSize = hSize;

   m_currentContext.SourceVSize = vSize;

 

   m_regCAM->CISRCFMT = (ituxxx<<BP_SELECT_ITU_INTERFACE) |

                        (uvoffset<<BP_UVOFFSET) |

                         (0<<BP_IN16BIT)|

                         (hSize<<BP_SRCHSIZE_CAM) |

                        (order422<<BP_ORDER422_CAM) |

                         (vSize<<BP_SRCVSIZE_CAM);

 

   CAMIF_MSG((_T("[CAMIF] --%s() : hSize =%d  vSize = %d  CISRCFMT=0x%X\r\n"), _T(__FUNCTION__),hSize, vSize, m_regCAM->CISRCFMT));

   LeaveCriticalSection(&m_csHWregister);

}

 

 

 

下面是设置摄像头数据经过摄像头DMA后出来的分辨率设置

// Get IMG Type (With,Height, Format, Order, Plane)

// Todo: Add more Image Format

voidCameraHal::SetTargetRegister(UINT32 width, UINT32 height, CAM_IMG_FORMATFormat)        //set target register

{

   //EnterCriticalSection(&m_csHWregister);

   CAMIF_MSG((_T("[CAMIF] ++%s()Width=%d  Height=%d  Format=%d\r\n"),_T(__FUNCTION__), width, height, Format));

   //fightercuiOUTFMT_YUV420_23PLANE

   DWORD DMAOutFormat = OUTFMT_YUV422_23PLANE;             //Default value = 0

   DWORD OutRGBFormat = OUTRGB_RGB565;                     //Default value = 0(Don't care)

   //fightercui OUTDMA_YUV_3PLANE

   DWORD OutPlaneFormat = OUTDMA_YUV_2PLANE;               //Default value = 0(Don't care)

   DWORD OutOrderCbCr_2Plane = OUTDMA_YUV_2PLANE_CBCR_LITTLE;  // Default value =0(Dont' care)

   DWORD OutOrder422_1Plane = OUTDMA_YUV422_1PLANE_YCBYCR; // Default value = 0(Don't care)

 

 

   switch(Format)

   {

   case CAM_FORMAT_IJPG:

       // Just fake Camera IP. take all data fromCamera Module, bypassing data to upper buffer

       width = m_moduleDesc.JpegSpoofWidth;

       height = m_moduleDesc.JpegSpoofHeight;

       

       DMAOutFormat = OUTFMT_YUV422_1PLANE;        //< Thiswill determine writing method

       OutOrder422_1Plane = OUTDMA_YUV422_1PLANE_CBYCRY;

       break;

   case CAM_FORMAT_YCBCR422_1PLANE: // YUV422 3/2/1 Plane

       DMAOutFormat = OUTFMT_YUV422_1PLANE;     

       break;

   case CAM_FORMAT_RGB16:

       DMAOutFormat = OUTFMT_RGB;

       OutRGBFormat = OUTRGB_RGB565;

       break;

   case CAM_FORMAT_RGB24:

       DMAOutFormat = OUTFMT_RGB;

       OutRGBFormat = OUTRGB_RGB888;

       break;

   case CAM_FORMAT_YCBCR444:     // YUV444 2/3Plane, Not yet implemented

       break;

   case CAM_FORMAT_YCBCR420_3PLANE:

//    case CAM_FORMAT_YV12:

       DMAOutFormat = OUTFMT_YUV420_23PLANE;

       OutPlaneFormat = OUTDMA_YUV_3PLANE;

       break;

   case CAM_FORMAT_YCBCR420_2PLANE:     // YUV420 2/3Plane(YUV420 2Plane = NV12)

//    case CAM_FORMAT_NV12:

   default:

       DMAOutFormat = OUTFMT_YUV420_23PLANE;

       OutOrderCbCr_2Plane = OUTDMA_YUV_2PLANE_CBCR_LITTLE;

       OutPlaneFormat = OUTDMA_YUV_2PLANE;

       break;

   }

 

   EnterCriticalSection(&m_csHWregister);   

   // Don't care about rotation and flip

    m_regCAM->CITRGFMT = (DMAOutFormat) |

                       (width<<BP_TARGETHSIZE) |

                       (height<<BP_TARGETVSIZE);

   m_regCAM->CIOCTRL = (OutOrderCbCr_2Plane) |

                       (OutPlaneFormat) |

                       (OutOrder422_1Plane);   // LASTIRQEn willbe set later in CaptureControl on JPEG Still capturing

   m_regCAM->CISCCTRL = (CSC_R2Y_WIDE)|

                       (CSC_Y2R_WIDE)|

                       (0<<BP_LCDPATHEN)|

                       (0<<BP_INTERLACE) |

                        (3<<BP_INRGB_FMT)|      // Reserved

                       (OutRGBFormat)|

                       (0<<BP_EXT_RGB);

 

   LeaveCriticalSection(&m_csHWregister);                           

   

   CAMIF_MSG((_T("[CAMIF] ++%s() CITRGFMT=0x%x  CISCCTRL=0x%x Format=%d\r\n"), _T(__FUNCTION__),

                    m_regCAM->CITRGFMT,m_regCAM->CISCCTRL));

                   

   if( Format != CAM_FORMAT_IJPG)

   {

       SetScaler(width, height);

   }

 

   EnterCriticalSection(&m_csHWregister);   

   // 3. Output DMA Setting

   m_regCAM->CIORGOSIZE = DST_WIDTH(width) |DST_HEIGHT(height);   // For Ouput DMA

 

   if(m_CamOperationMode == STILL_CAPTURE)

   {

       m_regCAM->CICPTSEQ = 0xC0000000;   // Accept only two frame, but first frame willbe discarded.   

#if USE_CAPTURE_FRAME_CONTROL

       // If use 1 Camera IP for all Still&VideoCapture and preview, there is no need to discard

#if USE_STEPBYSTEP_CONTROL

       m_regCAM->CIIMGCPT |= (1<<BP_CPT_FREN) |(0<<BP_CPT_FRMOD);    // Step-by-Step shot.

#else

       m_regCAM->CIIMGCPT |= (1<<BP_CPT_FREN) |(1<<BP_CPT_FRMOD) | (2<<BP_CPT_FRCNT);    // Frame CountMode, 1 Frame capture

#endif

#endif

   }

   else

   {

       m_regCAM->CICPTSEQ = 0xFFFFFFFF;   // For some reason this value canchanged??   

       m_regCAM->CIIMGCPT &= ~(1<<BP_CPT_FREN); // Disable Capture Frame Control

   }

   m_regCAM->CIMSCTRL &= ~(BM_SEL_DMA_CAM);    // For transitionfrom Post Processor mode

   m_regCAM->CIIYOFF = 0;

   m_regCAM->CIICBOFF = 0;

   m_regCAM->CIICROFF = 0;

 

   LeaveCriticalSection(&m_csHWregister);   

 

   CAMIF_MSG((_T("[CAMIF] --%s()\r\n"),_T(__FUNCTION__)));

   //LeaveCriticalSection(&m_csHWregister);

}

 

这里还有一个很重要的函数,设置摄像头scaler寄存器进行scaler!真是好东西

// From Camera Input

voidCameraHal::SetScaler(UINT32 DstWidth, UINT32 DstHeight)

{

    UINT32 SrcWidth, SrcHeight;   

   

   CAMIF_MSG((_T("[CAMIF] ++%s()DstWidth=%d  DstHeight=%d\r\n"),_T(__FUNCTION__), DstWidth, DstHeight));

   

   if(DstWidth == 0 || DstHeight == 0) return;

 

   CAMIF_MSG((_T("[CAMIF] ++%s()HOffset=(%d,%d), VOffset=(%d,%d), SrcSize(%d,%d)\r\n"),_T(__FUNCTION__),

               m_currentContext.offset.HorOffset,

                m_currentContext.offset.HorOffset2,

               m_currentContext.offset.VerOffset,

               m_currentContext.offset.VerOffset2,

                m_currentContext.SourceHSize,

               m_currentContext.SourceVSize));   

           

   SrcWidth = m_currentContext.SourceHSize -m_currentContext.offset.HorOffset - m_currentContext.offset.HorOffset2;

   SrcHeight = m_currentContext.SourceVSize -m_currentContext.offset.VerOffset - m_currentContext.offset.VerOffset2;

 

    SetScaler(SrcWidth,SrcHeight, DstWidth, DstHeight);

 

   CAMIF_MSG((_T("[CAMIF] --%s()\r\n"),_T(__FUNCTION__)));

}

 

// For Post Processor

voidCameraHal::SetScaler(UINT32 dwCropInHSize, UINT32 dwCropInVSize, UINT32dwResizedOutHSize, UINT32 dwResizedOutVSize)

{

   unsigned intPreHozRatio, PreVerRatio;

   unsigned intMainHozShift, MainVerShift;

 

   EnterCriticalSection(&m_csHWregister);   

   // 图像放大

    if(dwCropInHSize <= dwResizedOutHSize)

   {

       m_regCAM->CISCCTRL = (m_regCAM->CISCCTRL & ~(BM_SCALEUP_H)) |SCALE_UP_H;

   }

   else

   {

       m_regCAM->CISCCTRL = (m_regCAM->CISCCTRL & ~(BM_SCALEUP_H)) |SCALE_DOWN_H;

}

// 图像放大

    if(dwCropInVSize <= dwResizedOutVSize)

   {

       m_regCAM->CISCCTRL = (m_regCAM->CISCCTRL & ~(BM_SCALEUP_V)) |SCALE_UP_V;

   }

   else

   {

       m_regCAM->CISCCTRL = (m_regCAM->CISCCTRL & ~(BM_SCALEUP_V)) |SCALE_DOWN_V;

   }

   LeaveCriticalSection(&m_csHWregister);   

   

   if (GetPrescalerShiftvalue(&MainHozShift,dwCropInHSize, dwResizedOutHSize))

   {

       PreHozRatio = (1<<MainHozShift);

   }

   else

   {

       // Out of Range, Todo: Set Safe Value

       PreHozRatio = (1<<MainHozShift);

   }

   if(GetPrescalerShiftvalue(&MainVerShift, dwCropInVSize, dwResizedOutVSize))

   {

       PreVerRatio = (1<<MainVerShift);

   }

   else

   {

       // Out of Range, Todo: Set Safe Value

       PreVerRatio = (1<<MainVerShift);

   }

   CAMIF_MSG((_T("[CAMIF] ++%s()Src(%d,%d), Dst(%d,%d), Pre(%d,%d) Main(%d,%d)\r\n"),_T(__FUNCTION__),

                            dwCropInHSize,dwCropInVSize, dwResizedOutHSize, dwResizedOutVSize,

                            PreHozRatio,PreVerRatio, MainHozShift, MainVerShift));

 

   EnterCriticalSection(&m_csHWregister);   

   m_regCAM->CISCPRERATIO =PRESCALE_SHFACTOR(10-(MainHozShift+MainVerShift)) |PRESCALE_H_RATIO(PreHozRatio) | PRESCALE_V_RATIO(PreVerRatio);

   m_regCAM->CISCPREDST =PRESCALE_WIDTH(dwCropInHSize/PreHozRatio) |PRESCALE_HEIGHT(dwCropInVSize/PreVerRatio);;

   m_regCAM->CISCCTRL = (m_regCAM->CISCCTRL & ~(BM_MAINHORRATIO |BM_MAINVERRATIO)) |

                           MAINSCALE_H_RATIO((dwCropInHSize<<8)/(dwResizedOutHSize<<MainHozShift))|

                           MAINSCALE_V_RATIO((dwCropInVSize<<8)/(dwResizedOutVSize<<MainVerShift));

     CAMIF_MSG((_T("[CAMIF] ++%s()@@@@m_regCAM=0x%x+++++++++)\r\n"),_T(__FUNCTION__),m_regCAM));  //wille 0228

   m_regCAM->CITAREA = dwResizedOutHSize * dwResizedOutVSize;

   LeaveCriticalSection(&m_csHWregister);       

}

 

这个几个函数非常有用,写的很好,可复用性很高,下面看看他们在哪里被调用了就知道了。

 

 

 

 

在下面的函数中也做了一些初始化。

MODULE_STATUS OV3640::Init()

{

    RETAILMSG(LOG&MSG_OV3640_LOG, (_T("[%s] %s\r\n"), MODULE_NAME,_T(__FUNCTION__)));

 

   PHYSICAL_ADDRESS    ioPhysicalBase= {0,0};

 

   // GPIO Virtual alloc

   ioPhysicalBase.LowPart = S5PC100_BASE_REG_PA_GPIO;

   m_regIOP = (S5PC100_GPIO_REG *)MmMapIoSpace(ioPhysicalBase, sizeof(S5PC100_GPIO_REG), FALSE);

   if (m_regIOP == NULL)

   {

       CAMIF_ERR((_T("[CAMIF:ERR] ++%s():m_regIOP DrvLib_MapIoSpace failed!\r\n"), _T(__FUNCTION__)));

       return MOD_STATUS_FAIL;

   }

 

   m_oCommIF = new CamCommI2C();

   if(!m_oCommIF)

   {

       CAMIF_ERR((_T("[CAMIF:ERR] ++%s():Cannot create Comm Instance!\r\n"), _T(__FUNCTION__)));   

       return MOD_STATUS_FAIL;

   }

 

   ModuleDescriptor.ModuleID = SYSLSI_OV3640;

    ModuleDescriptor.ITUXXX =OV3640_MODULE_ITUXXX;

    ModuleDescriptor.MIPI = OV3640_MODULE_MIPI;

    ModuleDescriptor.LANE = OV3640_MODULE_LANE;

    ModuleDescriptor.JPEG =OV3640_MODULE_JPEG;   

    ModuleDescriptor.UVOffset =OV3640_MODULE_UVOFFSET;

    ModuleDescriptor.SourceHSize =OV3640_MODULE_HSIZE;

    ModuleDescriptor.Order422 =OV3640_MODULE_YUVORDER;

    ModuleDescriptor.SourceVSize =OV3640_MODULE_VSIZE;

    ModuleDescriptor.Clock =OV3640_MODULE_CLOCK;

    ModuleDescriptor.Codec =OV3640_MODULE_CODEC;

    ModuleDescriptor.HighRst =OV3640_MODULE_HIGHRST;

    ModuleDescriptor.SourceHOffset =OV3640_MODULE_HOFFSET;

    ModuleDescriptor.SourceVOffset =OV3640_MODULE_VOFFSET;

    ModuleDescriptor.InvPCLK =OV3640_MODULE_INVPCLK;

    ModuleDescriptor.InvVSYNC =OV3640_MODULE_INVVSYNC;

    ModuleDescriptor.InvHREF =OV3640_MODULE_INVHREF;

    ModuleDescriptor.JpegSpoofHeight =OV3640_MODULE_JpegSpoofHeight;

    ModuleDescriptor.JpegSpoofWidth =OV3640_MODULE_JpegSpoofWidth;

 

   RETAILMSG(0,(_T("%s ModuleDescriptorDump:%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\r\n"),_T(__FUNCTION__),

   ModuleDescriptor.ITUXXX,

   ModuleDescriptor.MIPI,

   ModuleDescriptor.LANE,

   ModuleDescriptor.JPEG,

   ModuleDescriptor.UVOffset,

   ModuleDescriptor.SourceHSize,

   ModuleDescriptor.Order422,

   ModuleDescriptor.SourceVSize,

   ModuleDescriptor.Clock,

   ModuleDescriptor.Codec,

   ModuleDescriptor.HighRst,

   ModuleDescriptor.SourceHOffset,

   ModuleDescriptor.SourceVOffset,

   ModuleDescriptor.InvPCLK,

   ModuleDescriptor.InvVSYNC,

   ModuleDescriptor.InvHREF,

   ModuleDescriptor.JpegSpoofHeight,

   ModuleDescriptor.JpegSpoofWidth

   ));

 

   return MOD_STATUS_SUCCESS;

}

 

/*================================================*/

 

//========================================================

//  OV3640 default mode

#defineOV3640_MODULE_ITUXXX         CAM_ITU601

#defineOV3640_MODULE_MIPI           (0)

#defineOV3640_MODULE_LANE          (DATA_LANE_1)

#defineOV3640_MODULE_JPEG           (0)

#defineOV3640_MODULE_YUVORDER      CAM_ORDER_YCBYCR

 

// 这个输出是拍照的输出,预览的呢?在哪里?

#define OV3640_MODULE_HSIZE          2048

#define OV3640_MODULE_VSIZE          1536

#defineOV3640_MODULE_HOFFSET        0

#defineOV3640_MODULE_VOFFSET        0

#defineOV3640_MODULE_UVOFFSET      CAM_UVOFFSET_0

#defineOV3640_MODULE_CLOCK          24000000

#defineOV3640_MODULE_CODEC         CAM_FORMAT_YCBCR422_23PLANE

#defineOV3640_MODULE_HIGHRST        0        // This isaffected by Electic circuit for reset or power control PIN, BB37->0,SMDK->1

#defineOV3640_MODULE_INVPCLK        0

#defineOV3640_MODULE_INVVSYNC       1

#defineOV3640_MODULE_INVHREF        0

#defineOV3640_MODULE_JpegSpoofHeight  1536

#defineOV3640_MODULE_JpegSpoofWidth   2048

//========================================================

//  OV3640 infomation

#defineOV3640_JPEG_MAX_SIZE          2048*1536

 

 

不过我发现这个130W 和 300W上面的配置居然也一样,why?

 

找到关键点了!

 

 

DWORD CusCam_Zoom(DWORD ZoomRatio,UINT32 uCamID)

{

   MODULE_DESCRIPTOR moduleValue;

   UINT32 offsetValueWidth,offsetValueHeight;

   

   ModuleGetFormat(&moduleValue);

   //

   offsetValueWidth = (ZoomRatio+1) * CAM_OFFSET_STEP; // TODO: Need to calculate accureately

   offsetValueHeight = (int)(offsetValueWidth* (moduleValue.SourceVSize/(float)moduleValue.SourceHSize));

   offsetValueHeight = (offsetValueHeight<<1)>>1;

   

   if( offsetValueWidth*2 >(moduleValue.SourceHSize-16) || offsetValueHeight*2 > (moduleValue.SourceVSize-8))

   {

       return FALSE;

   }

   

   oCtxCamera[uCamID].pCameraIF->SetOffsetRegister(offsetValueWidth,offsetValueWidth, offsetValueHeight, offsetValueHeight);

   

   CUSCAM_INF((TEXT("[CAM]offsetValueWidth=%d   offsetValueHeight=%d\n"),offsetValueWidth,offsetValueHeight));

   

   if(oCtxCamera[uCamID].pCameraIF->GetOperationMode()== PREVIEW_CAPTURE)

   {

       oCtxCamera[uCamID].pCameraIF->SetScaler(Preview_Buffer.Width,Preview_Buffer.Height);

   }

   else if(oCtxCamera[uCamID].pCameraIF->GetOperationMode()== VIDEO_CAPTURE)

   {

       oCtxCamera[uCamID].pCameraIF->SetScaler(Video_Buffer.Width,Video_Buffer.Height);   

   }

   else if(oCtxCamera[uCamID].pCameraIF->GetOperationMode()== STILL_CAPTURE)

   {

       oCtxCamera[uCamID].pCameraIF->SetScaler(Still_Buffer.Width,Still_Buffer.Height);                   

   }

 

   return TRUE;

 

}

 

红色部分oCtxCamera[uCamID].pCameraIF->SetScaler(Preview_Buffer.Width,Preview_Buffer.Height);那哪里来的?找到这里

// Todo Move to CustomCamera

intCusCam_CameraSetFormat(UINT32 width, UINT32 height, CAM_IMG_FORMAT format, int BufferType, UINT32 uCamID)

{

   CAM_IMGTYPE_ARGS ImgInfo;

   ImgInfo.imgtype.width = width;

   ImgInfo.imgtype.height = height;

   ImgInfo.imgtype.outputFormat = format;

   ImgInfo.imgtype.outputOrder = 0;

   ImgInfo.imgtype.outputPlane = 0;

   

   CAMIF_MSG((TEXT("%s ++%s()\n"),DBG_MSG_HEADER, _T(__FUNCTION__)));

   if(BufferType == VIDEO_CAPTURE)

   {

       Video_Buffer.Width = width;

       Video_Buffer.Height = height;

       Video_Buffer.Format = format;

       CusCam_SetVideoSize(&ImgInfo, uCamID);

   }

   else if(BufferType== STILL_CAPTURE)

   {

       Still_Buffer.Width = width;

       Still_Buffer.Height = height;

       Still_Buffer.Format = format;

       CusCam_SetStillSize(&ImgInfo, uCamID);

   }

   else if(BufferType == PREVIEW_CAPTURE)

    {

       Preview_Buffer.Width = width;

       Preview_Buffer.Height = height;

       Preview_Buffer.Format = format;

       CusCam_SetPreviewSize(&ImgInfo, uCamID);

    }

   else

   {

       return FALSE;

   }

   CAMIF_MSG((TEXT("%s --%s()\n"),DBG_MSG_HEADER, _T(__FUNCTION__)));

   return TRUE;

}

 

 

看看CusCam_CameraSetFormat哪里被调用了——在CAM_Camera_API_Proc函数里面有:

case IOCTL_CAM_PREPAREBUFFER:

       {

            // In :BUFFER_DESC

            // Out :P_CAMERA_DMA_BUFFER_INFO

            BUFFER_DESC *pArgs;

 

            RETAILMSG(CAM_ZONE_TEMP, (_T("[CAM] %s() : IOCTL_CAM_PREPAREBUFFER\n\r"),_T(__FUNCTION__)));

 

            if(!pBufIn|| dwLenIn < sizeof(BUFFER_DESC))

            {

                DEBUGMSG(CAM_ZONE_ERROR,(TEXT("Invalid Buffer : pBufIn:0x%x, dwLenIn:%d\n"),pBufIn, dwLenIn));

                bRet = FALSE;

                break;

            }

           

            pArgs = (BUFFER_DESC *)pBufIn;// 通过这个pBufin传递进来

            CusCam_CameraSetFormat(pArgs->Width,pArgs->Height, pArgs->Format, pArgs->Type, uCamID);

 

            if(!pBufOut|| dwLenOut < sizeof(CAMERA_DMA_BUFFER_INFO))

            {

                DEBUGMSG(CAM_ZONE_ERROR,(TEXT("Invalid Buffer : pBufOut:0x%x, dwLenOut:%d\n"),pBufOut, dwLenOut));

                bRet = FALSE;

                break;

            }

 

            bRet =CusCam_CameraPrepareBuffer((P_CAMERA_DMA_BUFFER_INFO)pBufOut, pArgs->Type,uCamID);

       }

       break;

 

继续跟进,在CAM_IOControl里面找到了

//-----------------------------------------------------------------------------------------

       // Camera Control Interface

       case IOCTL_CAM_INIT:

       case IOCTL_CAM_DEINIT:

       case IOCTL_CAM_RESET:

       case IOCTL_CAM_PREVIEW_START:

       case IOCTL_CAM_PREVIEW_GETFRAME:

       case IOCTL_CAM_PREVIEW_STOP:

       case IOCTL_CAM_STILLCUT:

       case IOCTL_CAM_VIDEO_START:

       case IOCTL_CAM_VIDEO_GETFRAME:

       case IOCTL_CAM_VIDEO_STOP:

       case IOCTL_CAM_SET_PREVIEWSOURCE:

       case IOCTL_CAM_SET_STILLSOURCE:

       case IOCTL_CAM_SET_VIDEOSOURCE:

       case IOCTL_CAM_SET_PREVIEWSIZE: // 这里!

       case IOCTL_CAM_SET_STILLSIZE:

       case IOCTL_CAM_SET_VIDEOSIZE:

       case IOCTL_CAM_SET_PROPERTY:

       case IOCTL_CAM_GET_ERROR:

       case IOCTL_CAM_SETCALLBACK:

       case IOCTL_CAM_INIT_SENSOR:

       case IOCTL_CAM_GETCURRENTFRAMENUM:

       case IOCTL_CAM_PREPAREBUFFER:

       case IOCTL_CAM_SET_OPERATIONMODE:

       case IOCTL_CAM_SET_REGISTER:

       case IOCTL_CAM_CAPTURECONTROL:

       case IOCTL_CAM_ZOOM:

       case IOCTL_CAM_CLOCK_ONOFF:

       case IOCTL_CAM_SET_PCLK:

       case IOCTL_CAM_SET_DMA_PARAMETER:

       case IOCTL_CAM_DEINIT_SENSOR:       

            RetVal = CAM_Camera_API_Proc(pOpenHead, dwCode,pBufIn, dwLenIn, pBufOut, dwLenOut, pdwActualOut);

            break;

 

先这样,明天早上再看看,应该可以找到问题点的了,等着解开答案的时刻吧!

Come on!继续

 

bool CCameraPdd::SetSensorFormat( ULONGulModeType)

{

   RETAILMSG(CAM_INOUT,(TEXT("%s %s(%d)\n"), DBG_MSG_HEADER, _T(__FUNCTION__), ulModeType));   

   CAM_IMG_FORMAT format;

   DWORD dwBytes;

   // Target Format

   PCS_VIDEOINFOHEADER pCsVideoInfoHdr =&m_pCurrentFormat[ulModeType].VideoInfoHeader;

//   MODULE_DESCRIPTOR ModuleDesc;

   // Camera Sensor Source Format  

//   ModuleGetFormat(&ModuleDesc);

   

   UINT biWidth        =pCsVideoInfoHdr->bmiHeader.biWidth;

   UINT biHeight       =abs(pCsVideoInfoHdr->bmiHeader.biHeight);

   DWORD biBitCount    =pCsVideoInfoHdr->bmiHeader.biBitCount;

   DWORD biCompression = pCsVideoInfoHdr->bmiHeader.biCompression;

 

   RETAILMSG(CAM_MSG,(TEXT("%s VideoInfoHeader:%d,%d,%d,0x%x)\n"), DBG_MSG_HEADER,

                            biWidth, biHeight,biBitCount, biCompression));   

   // Prepare buffers here for Preview and Still mode.

   if ( (FOURCC_YUY2 == (biCompression & ~BI_SRCPREROTATE)))

    {

       // YUYV(YCrYCb)

       format = CAM_FORMAT_YCBCR422_1PLANE;

    }

/*   

   else if ((FOURCC_UYVY == (biCompression & ~BI_SRCPREROTATE)))

    {

       // UYVY(CbYCrY)

       format = CAM_FORMAT_CBYCRY422_1PLANE;

    }

*/   

   else if((FOURCC_YV12 == (biCompression & ~BI_SRCPREROTATE)))

    {

       format = CAM_FORMAT_YV12;

    }

   else if((FOURCC_NV12 == (biCompression & ~BI_SRCPREROTATE)))

    {

       format = CAM_FORMAT_NV12;

    }

   else if((CS_BI_BITFIELDS == (biCompression & ~BI_SRCPREROTATE)))

    {

       if(biBitCount == 24)

       {

           // BPP 3

           format = CAM_FORMAT_RGB24;

       }

       else

       {

           // BPP 2

           format = CAM_FORMAT_RGB16;

       }

    }

   else if((FOURCC_IJPG == (biCompression & ~BI_SRCPREROTATE)))

    {

       format = CAM_FORMAT_IJPG;

    }

   RETAILMSG(CAM_MSG,(TEXT("%s format:%d\n"), DBG_MSG_HEADER,

                            format));

 

   // Set Camera Source Size?

 

   if (ulModeType == CAPTURE)

    {

       BUFFER_DESC VideoBuffer;

       VideoBuffer.Height = biHeight;

       VideoBuffer.Width = biWidth;

       VideoBuffer.Format = format;

       VideoBuffer.Type = VIDEO_CAPTURE;

 

       // Set Target Video Size

       if ( !DeviceIoControl(g_hVideoCamera, IOCTL_CAM_SET_VIDEOSIZE,&VideoBuffer, sizeof(BUFFER_DESC), &m_CameraHWVideoBuffers,sizeof(CAMERA_DMA_BUFFER_INFO), &dwBytes, NULL) )

       {

           RETAILMSG(CAM_ERR, (_T("%s --%s() : IOCTL_CAM_SET_VIDEOSIZEFailed\n\r"), DBG_MSG_HEADER, _T(__FUNCTION__)));

       }

   

       if ( !DeviceIoControl(g_hVideoCamera, IOCTL_CAM_PREPAREBUFFER,&VideoBuffer, sizeof(BUFFER_DESC), &m_CameraHWVideoBuffers,sizeof(CAMERA_DMA_BUFFER_INFO), &dwBytes, NULL) )

       {

           RETAILMSG(CAM_ERR, (_T("%s --%s() : IOCTL_CAM_PREPAREBUFFERFailed\n\r"), DBG_MSG_HEADER, _T(__FUNCTION__)));

       }

    }

   else if (ulModeType == STILL)

    {

       BUFFER_DESC StillBuffer;

       StillBuffer.Height = biHeight;

       StillBuffer.Width = biWidth;

       StillBuffer.Format = format;

       StillBuffer.Type = STILL_CAPTURE;

 

       if ( !DeviceIoControl(g_hVideoCamera, IOCTL_CAM_SET_STILLSIZE, &StillBuffer,sizeof(BUFFER_DESC), &m_CameraHWStillBuffer,sizeof(CAMERA_DMA_BUFFER_INFO), &dwBytes, NULL) )

       {

           RETAILMSG(CAM_ERR, (_T("%s --%s() : IOCTL_CAM_SET_STILLSIZEFailed\n\r"), DBG_MSG_HEADER, _T(__FUNCTION__)));

       }

   

        if ( !DeviceIoControl(g_hVideoCamera,IOCTL_CAM_PREPAREBUFFER, &StillBuffer, sizeof(BUFFER_DESC),&m_CameraHWStillBuffer, sizeof(CAMERA_DMA_BUFFER_INFO), &dwBytes, NULL))

       {

           RETAILMSG(CAM_ERR, (_T("%s --%s() : IOCTL_CAM_PREPAREBUFFERFailed\n\r"), DBG_MSG_HEADER, _T(__FUNCTION__)));

       }

    }

   else if(ulModeType == PREVIEW)

{/*

UINT biWidth        =pCsVideoInfoHdr->bmiHeader.biWidth;

    UINT biHeight       =abs(pCsVideoInfoHdr->bmiHeader.biHeight);

    DWORD biBitCount    = pCsVideoInfoHdr->bmiHeader.biBitCount;

    DWORD biCompression =pCsVideoInfoHdr->bmiHeader.biCompression;

*/

       BUFFER_DESCPreviewBuffer;

       PreviewBuffer.Height = biHeight;

       PreviewBuffer.Width = biWidth;

        PreviewBuffer.Format = format;

       PreviewBuffer.Type = PREVIEW_CAPTURE;

 

        if ( !DeviceIoControl(g_hPreviewCamera,IOCTL_CAM_SET_PREVIEWSIZE, &PreviewBuffer, sizeof(BUFFER_DESC),&m_CameraHWPreviewBuffers, sizeof(CAMERA_DMA_BUFFER_INFO), &dwBytes,NULL) )

       {

           RETAILMSG(CAM_ERR, (_T("%s --%s() : IOCTL_CAM_SET_PREVIEWSIZEFailed\n\r"), DBG_MSG_HEADER, _T(__FUNCTION__)));

       }

   

       if ( !DeviceIoControl(g_hPreviewCamera,IOCTL_CAM_PREPAREBUFFER, &PreviewBuffer, sizeof(BUFFER_DESC),&m_CameraHWPreviewBuffers, sizeof(CAMERA_DMA_BUFFER_INFO), &dwBytes,NULL) )

       {

           RETAILMSG(CAM_ERR, (_T("%s --%s() : IOCTL_CAM_PREPAREBUFFERFailed\n\r"), DBG_MSG_HEADER, _T(__FUNCTION__)));

       }

    }

   else

    {

       return FALSE;

    }

 

   return TRUE;

}

 

这个缓存设置是从这里来的

// Target Format

    PCS_VIDEOINFOHEADER pCsVideoInfoHdr =&m_pCurrentFormat[ulModeType].VideoInfoHeader;

UINTbiWidth        =pCsVideoInfoHdr->bmiHeader.biWidth;

   UINT biHeight       =abs(pCsVideoInfoHdr->bmiHeader.biHeight);

   DWORD biBitCount    =pCsVideoInfoHdr->bmiHeader.biBitCount;

DWORDbiCompression = pCsVideoInfoHdr->bmiHeader.biCompression;

 

//------------------------------------------------------------------------------------------

也有CAM_Camera_API_Proc函数中也有

BOOLCAM_Camera_API_Proc(

    PHW_OPEN_INFO pOpenHead,

    DWORD dwCode,

    PBYTE pBufIn,

    DWORD dwLenIn,

    PBYTE pBufOut,

    DWORD dwLenOut,

    PDWORD pdwActualOut

    )

 

 

case IOCTL_CAM_PREPAREBUFFER:

        {

            // In : BUFFER_DESC

            // Out : P_CAMERA_DMA_BUFFER_INFO

            BUFFER_DESC *pArgs;

 

            RETAILMSG(CAM_ZONE_TEMP,(_T("[CAM] %s() : IOCTL_CAM_PREPAREBUFFER\n\r"), _T(__FUNCTION__)));

 

            if(!pBufIn || dwLenIn <sizeof(BUFFER_DESC))

            {

               DEBUGMSG(CAM_ZONE_ERROR,(TEXT("Invalid Buffer : pBufIn:0x%x,dwLenIn:%d\n"), pBufIn, dwLenIn));

                bRet = FALSE;

                break;

            }

            

            pArgs = (BUFFER_DESC *)pBufIn;

 

           CusCam_CameraSetFormat(pArgs->Width, pArgs->Height,pArgs->Format, pArgs->Type, uCamID);

 

            if(!pBufOut || dwLenOut <sizeof(CAMERA_DMA_BUFFER_INFO))

            {

                DEBUGMSG(CAM_ZONE_ERROR,(TEXT("InvalidBuffer : pBufOut:0x%x, dwLenOut:%d\n"), pBufOut, dwLenOut));

                bRet = FALSE;

                break;

            }

 

            bRet =CusCam_CameraPrepareBuffer((P_CAMERA_DMA_BUFFER_INFO)pBufOut, pArgs->Type, uCamID);

        }

        break;

 

 

最终还是回到CAM_IOControl 函数里面。

 

 

 

 

 

 

 

我日日,我日日日日日,这个还是在应用程序设置的

在微软源代码的cameraapp 源码里面有

 

memset(&bmi, 0, sizeof(bmi));

    bmi.bmiHeader.biSize        = sizeof(BITMAPINFOHEADER);

    bmi.bmiHeader.biWidth       = m_lDefaultWidth; // 获取实际屏幕宽度

    // negative height so we have a top downbitmap

    bmi.bmiHeader.biHeight      = -m_lDefaultHeight;// 获取屏幕实际高度

   bmi.bmiHeader.biPlanes      = 1;

   bmi.bmiHeader.biBitCount    = 24;

bmi.bmiHeader.biCompression =BI_RGB;

 

hr = m_pVideoWindow->get_Width(&m_lDefaultWidth);

hr = m_pVideoWindow->get_Height(&m_lDefaultHeight);

 

#defineIMessengerIMWindow_get_Height(This,plHeight)    \

   (This)->lpVtbl -> get_Height(This,plHeight)

 

至于是怎么传递给下层的,就要看看这些帖子了

http://www.geekpage.jp/en/programming/directshow/

http://www.gamedev.net/page/resources/_/technical/directx-and-xna/the-basics-to-using-directshow-r1345

 

http://bbs.csdn.net/topics/350151338

http://bbs.csdn.net/topics/320191752

 

 

还有,我发现一个问题,就是我VGA上大分辨率显示的时候,这个预览图画并没有被VGA分辨率决定,而是640*480 。难道LCD 分辨率比摄像头预览数据大就会由摄像头的出来的数据分辨率决定?!

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值