作者: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://bbs.csdn.net/topics/350151338
http://bbs.csdn.net/topics/320191752
还有,我发现一个问题,就是我VGA上大分辨率显示的时候,这个预览图画并没有被VGA分辨率决定,而是640*480 。难道LCD 分辨率比摄像头预览数据大就会由摄像头的出来的数据分辨率决定?!