📄 s3c6400_camera.cpp
字号:
}
CameraSetCodecRegister(Video_Buffer.Width, Video_Buffer.Height, Video_Buffer.Format);
}
else if(format == STILL_CAPTURE_BUFFER)
{
size = Still_Buffer.FrameSize;
s6400CAM->CICOYSA1 = (UINT32)(PhysCodecAddr.LowPart);
s6400CAM->CICOYSA2 = s6400CAM->CICOYSA1;
s6400CAM->CICOYSA3 = s6400CAM->CICOYSA1;
s6400CAM->CICOYSA4 = s6400CAM->CICOYSA1;
if(OUTPUT_CODEC_YCBCR420 == Still_Buffer.Format)
{
sizeY = Still_Buffer.Width*Still_Buffer.Height;
sizeC = Still_Buffer.Width*Still_Buffer.Height/4;
/*
s6400CAM->CICOCBSA1=s6400CAM->CICOYSA1+sizeY;
s6400CAM->CICOCBSA2=s6400CAM->CICOCBSA1;
s6400CAM->CICOCBSA3=s6400CAM->CICOCBSA1;
s6400CAM->CICOCBSA4=s6400CAM->CICOCBSA1;
s6400CAM->CICOCRSA1=s6400CAM->CICOCBSA1+sizeC;
s6400CAM->CICOCRSA2=s6400CAM->CICOCRSA1;
s6400CAM->CICOCRSA3=s6400CAM->CICOCRSA1;
s6400CAM->CICOCRSA4=s6400CAM->CICOCRSA1;*/
// In DSHOW CB and Cr are changed.
s6400CAM->CICOCRSA1=s6400CAM->CICOYSA1+sizeY;
s6400CAM->CICOCRSA2=s6400CAM->CICOCRSA1;
s6400CAM->CICOCRSA3=s6400CAM->CICOCRSA1;
s6400CAM->CICOCRSA4=s6400CAM->CICOCRSA1;
s6400CAM->CICOCBSA1=s6400CAM->CICOCRSA1+sizeC;
s6400CAM->CICOCBSA2=s6400CAM->CICOCBSA1;
s6400CAM->CICOCBSA3=s6400CAM->CICOCBSA1;
s6400CAM->CICOCBSA4=s6400CAM->CICOCBSA1;
}
CameraSetCodecRegister(Still_Buffer.Width, Still_Buffer.Height, Still_Buffer.Format);
}
else if(format == PREVIEW_CAPTURE_BUFFER)
{
size = Preview_Buffer.FrameSize;
s6400CAM->CIPRYSA1=(UINT32)(PhysPreviewAddr.LowPart);
s6400CAM->CIPRYSA2=s6400CAM->CIPRYSA1+size;
s6400CAM->CIPRYSA3=s6400CAM->CIPRYSA2+size;
s6400CAM->CIPRYSA4=s6400CAM->CIPRYSA3+size;
if(OUTPUT_CODEC_YCBCR420 == Preview_Buffer.Format)
{
sizeY = Preview_Buffer.Width*Preview_Buffer.Height;
sizeC = Preview_Buffer.Width*Preview_Buffer.Height/4;
/*
s6400CAM->CIPRCBSA1=s6400CAM->CIPRYSA1+sizeY;
s6400CAM->CIPRCBSA2=s6400CAM->CIPRYSA2+sizeY;
s6400CAM->CIPRCBSA3=s6400CAM->CIPRYSA3+sizeY;
s6400CAM->CIPRCBSA4=s6400CAM->CIPRYSA4+sizeY;
s6400CAM->CIPRCRSA1=s6400CAM->CIPRCBSA1+sizeC;
s6400CAM->CIPRCRSA2=s6400CAM->CIPRCBSA2+sizeC;
s6400CAM->CIPRCRSA3=s6400CAM->CIPRCBSA3+sizeC;
s6400CAM->CIPRCRSA4=s6400CAM->CIPRCBSA4+sizeC; */
// In DSHOW CB and Cr are changed.
s6400CAM->CIPRCRSA1=s6400CAM->CIPRYSA1+sizeY;
s6400CAM->CIPRCRSA2=s6400CAM->CIPRYSA2+sizeY;
s6400CAM->CIPRCRSA3=s6400CAM->CIPRYSA3+sizeY;
s6400CAM->CIPRCRSA4=s6400CAM->CIPRYSA4+sizeY;
s6400CAM->CIPRCBSA1=s6400CAM->CIPRCRSA1+sizeC;
s6400CAM->CIPRCBSA2=s6400CAM->CIPRCRSA2+sizeC;
s6400CAM->CIPRCBSA3=s6400CAM->CIPRCRSA3+sizeC;
s6400CAM->CIPRCBSA4=s6400CAM->CIPRCRSA4+sizeC;
}
CameraSetPreviewRegister(Preview_Buffer.Width, Preview_Buffer.Height, Preview_Buffer.Format);
}
else
{
//CameraClockOn(FALSE);
return FALSE;
}
//CameraClockOn(FALSE);
RETAILMSG(CAM_INOUT,(TEXT("------------------CameraSetRegisters\n")));
return TRUE;
}
BOOL InitializeBuffer()
{
DMA_ADAPTER_OBJECT Adapter1, Adapter2;
RETAILMSG(CAM_INOUT,(TEXT("++++++++++++++++++InitializeBuffer\n")));
memset(&Adapter1, 0, sizeof(DMA_ADAPTER_OBJECT));
Adapter1.InterfaceType = Internal;
Adapter1.ObjectSize = sizeof(DMA_ADAPTER_OBJECT);
memset(&Adapter2, 0, sizeof(DMA_ADAPTER_OBJECT));
Adapter2.InterfaceType = Internal;
Adapter2.ObjectSize = sizeof(DMA_ADAPTER_OBJECT);
pCodecVirtAddr = (PBYTE)HalAllocateCommonBuffer(&Adapter1, CAPTURE_BUFFER_SIZE, &PhysCodecAddr, FALSE);
if (pCodecVirtAddr == NULL)
{
RETAILMSG(CAM_ERR, (TEXT("CameraPrepareBuffer() - Failed to allocate DMA buffer for CODEC Path.\r\n")));
return FALSE;
}
pPreviewVirtAddr = (PBYTE)HalAllocateCommonBuffer(&Adapter2, PREVIEW_BUFFER_SIZE, &PhysPreviewAddr, FALSE);
if (pPreviewVirtAddr == NULL)
{
RETAILMSG(CAM_ERR, (TEXT("CameraPrepareBuffer() - Failed to allocate DMA buffer for Preview Path.\r\n")));
return FALSE;
}
RETAILMSG(CAM_INOUT,(TEXT("------------------InitializeBuffer\n")));
return TRUE;
}
BOOL DeinitializeBuffer()
{
DMA_ADAPTER_OBJECT Adapter1,Adapter2;
RETAILMSG(CAM_INOUT,(TEXT("++++++++++++++++++DeinitializeBuffer\n")));
memset(&Adapter1, 0, sizeof(DMA_ADAPTER_OBJECT));
Adapter1.InterfaceType = Internal;
Adapter1.ObjectSize = sizeof(DMA_ADAPTER_OBJECT);
memset(&Adapter2, 0, sizeof(DMA_ADAPTER_OBJECT));
Adapter2.InterfaceType = Internal;
Adapter2.ObjectSize = sizeof(DMA_ADAPTER_OBJECT);
if(pCodecVirtAddr != NULL)
{
HalFreeCommonBuffer(&Adapter1, 0, PhysCodecAddr, (PVOID)pCodecVirtAddr, FALSE);
pCodecVirtAddr = NULL;
}
if(pPreviewVirtAddr != NULL)
{
HalFreeCommonBuffer(&Adapter2, 0, PhysPreviewAddr, (PVOID)pPreviewVirtAddr, FALSE);
pPreviewVirtAddr = NULL;
}
RETAILMSG(CAM_INOUT,(TEXT("-------------------DeinitializeBuffer\n")));
return TRUE;
}
BOOL InterruptInitialize()
{
DWORD threadID; // thread ID
BOOL bSuccess;
RETAILMSG(CAM_INOUT,(TEXT("+++++++++++++++++++InterruptInitialize\n")));
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &g_CamIrq_C, sizeof(UINT32), &g_CamSysIntr_C, sizeof(UINT32), NULL))
{
RETAILMSG(CAM_ERR, (TEXT("ERROR: Failed to request sysintr value for Camera interrupt.\r\n")));
return FALSE;
}
CaptureEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!CaptureEvent)
{
RETAILMSG(CAM_ERR,(TEXT("Fail to create camera interrupt event\r\n")));
return FALSE;
}
bSuccess = InterruptInitialize(g_CamSysIntr_C, CaptureEvent, NULL, 0);
if (!bSuccess)
{
RETAILMSG(CAM_ERR,(TEXT("Fail to initialize camera interrupt event\r\n")));
return FALSE;
}
CaptureThread = CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)CameraCaptureThread,
0,
0,
&threadID);
if (NULL == CaptureThread ) {
RETAILMSG(CAM_ERR,(TEXT("Create Camera Thread Fail\r\n")));
return FALSE;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &g_CamIrq_P, sizeof(UINT32), &g_CamSysIntr_P, sizeof(UINT32), NULL))
{
RETAILMSG(CAM_ERR, (TEXT("ERROR: Failed to request sysintr value for Camera interrupt.\r\n")));
return FALSE;
}
PreviewEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!PreviewEvent)
{
RETAILMSG(CAM_ERR,(TEXT("Fail to create camera interrupt event\r\n")));
return FALSE;
}
bSuccess = InterruptInitialize(g_CamSysIntr_P, PreviewEvent, NULL, 0);
if (!bSuccess)
{
RETAILMSG(CAM_ERR,(TEXT("Fail to initialize camera interrupt event\r\n")));
return FALSE;
}
PreviewThread = CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)CameraPreviewThread,
0,
0,
&threadID);
if (NULL == PreviewThread ) {
RETAILMSG(CAM_ERR,(TEXT("Create Camera Thread Fail\r\n")));
return FALSE;
}
RETAILMSG(CAM_INOUT,(TEXT("-------------------InterruptInitialize %d %d\n"),g_CamSysIntr_C,g_CamSysIntr_P));
return TRUE;
}
DWORD WINAPI CameraCaptureThread(void)
{
DWORD dwCause;
while(TRUE)
{
dwCause = WaitForSingleObject(CaptureEvent, INFINITE);
if (dwCause == WAIT_OBJECT_0)
{
if(CodecFrameCnt >= 2)
{
CodecFrameCnt = 3;
if(StillOn)
{
//s6400INT->INTSUBMSK |= (1<<IRQ_SUB_CAM_C);
//while((s6400CAM->CICOSTATUS & (1<<28)) == 0) // check VSYNC
//{
// nop
// Sleep(1);
//}
// Stop Capture
s6400CAM->CICOSCCTRL &= ~(CAM_CODEC_SACLER_START_BIT);
s6400CAM->CIIMGCPT &= ~((CAM_CODEC_SCALER_CAPTURE_ENABLE_BIT));
while((s6400CAM->CICOSTATUS & (1<<21)) == 1) // check Codec path disable
{
;
}
pfnCameraHandleStillFrame(dwCameraDriverContext);
// Restart Capture
s6400CAM->CICOSCCTRL |=(CAM_CODEC_SACLER_START_BIT);
s6400CAM->CIIMGCPT |=(CAM_CAMIF_GLOBAL_CAPTURE_ENABLE_BIT)|(CAM_CODEC_SCALER_CAPTURE_ENABLE_BIT);
//s6400INT->INTSUBMSK &= ~(1<<IRQ_SUB_CAM_C);
}
else if(VideoOn)
{
pfnCameraHandleVideoFrame(dwCameraDriverContext);
}
}
else
{
CodecFrameCnt++;
}
s6400CAM->CIGCTRL |= (1<<19);
InterruptDone(g_CamSysIntr_C);
}
else
{
RETAILMSG(CAM_ERR, (TEXT("[CAM_HW] InterruptThread : Exit %d, Cause %d\r\n"), GetLastError(), dwCause));
}
}
return 0;
}
DWORD WINAPI CameraPreviewThread(void)
{
DWORD dwCause;
while(TRUE)
{
dwCause = WaitForSingleObject(PreviewEvent, INFINITE);
if (dwCause == WAIT_OBJECT_0)
{
if(PreviewFrameCnt >= 2)
{
PreviewFrameCnt = 3;
pfnCameraHandlePreviewFrame(dwCameraDriverContext);
}
else
{
PreviewFrameCnt ++;
}
s6400CAM->CIGCTRL |= (1<<18);
InterruptDone(g_CamSysIntr_P);
}
else
{
RETAILMSG(CAM_ERR, (TEXT("[CAM_HW] InterruptThread : Exit %d, Cause %d\r\n"), GetLastError(), dwCause));
}
}
return 0;
}
void CameraSetClockDiv()
{
MODULE_DESCRIPTOR value;
int div;
ModuleGetFormat(value);
div = (int)(CAM_CLK_SOURCE / (float)value.Clock + 0.5) - 1;
RETAILMSG(CAM_MSG,(TEXT("[CAM] CameraSetClockDiv = %d\n"),div));
s6400PWR->CLK_DIV0 = (s6400PWR->CLK_DIV0 & ~(0xf<<20)) | ((div & 0xf)<< 20); // CAMCLK is divided..
}
void CameraSleep()
{
}
void CameraResume()
{
RETAILMSG(CAM_INOUT,(TEXT("+++++++++++++++ [CAM] CameraResume\n")));
// CameraSetClockDiv();
// 1. Camera IO setup
CameraGpioInit();
// 2. Camera Clock setup
//CameraClockOn(TRUE);
// 3. camera module reset
CameraModuleReset();
// 4. Write Setting for Module using I2C
ModuleWriteBlock();
// 5. Camera i/f reset
CameraInterfaceReset();
// 6. Initialize I/F source register
CameraCaptureSourceSet();
// 7. Camera Clock Off
//CameraClockOn(FALSE);
RETAILMSG(CAM_INOUT,(TEXT("---------------- [CAM] CameraResume\n")));
}
int CameraZoom(int value)
{
MODULE_DESCRIPTOR moduleValue;
UINT32 offsetValueWidth,offsetValueHeight;
ModuleGetFormat(moduleValue);
offsetValueWidth = value * CAM_OFFSET_STEP;
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;
}
gHorOffset1 = offsetValueWidth;
gVerOffset1 = offsetValueHeight;
gHorOffset2 = offsetValueWidth;
gVerOffset2 = offsetValueHeight;
RETAILMSG(CAM_MSG,(TEXT("[CAM] offsetValueWidth=%d offsetValueHeight=%d\n"),offsetValueWidth,offsetValueHeight));
CameraSetScaler(Preview_Buffer.Width, Preview_Buffer.Height, PREVIEW_PATH);
CameraSetScaler(Video_Buffer.Width, Video_Buffer.Height, CODEC_PATH);
return TRUE;
}
void CameraSetScaler(UINT32 width, UINT32 height, int path)
{
UINT32 H_Shift, V_Shift, PreHorRatio, PreVerRatio, MainHorRatio, MainVerRatio;
UINT32 ScaleUp_H, ScaleUp_V, SrcWidth, SrcHeight, WinOfsEn;
MODULE_DESCRIPTOR moduleValue;
RETAILMSG(CAM_INOUT,(TEXT("+++++++++++++++++++CameraSetScaler\n")));
if(width == 0 || height == 0) return;
ModuleGetFormat(moduleValue);
SrcWidth=moduleValue.SourceHSize-moduleValue.SourceHOffset*2-gHorOffset1-gHorOffset2;
SrcHeight=moduleValue.SourceVSize-moduleValue.SourceVOffset*2-gVerOffset1-gVerOffset2;
RETAILMSG(CAM_MSG,(TEXT("[CAM] width=%d height=%d SrcWidth=%d SrcHeight=%d\n"),width,height,SrcWidth,SrcHeight));
if((moduleValue.SourceHSize > SrcWidth) || (moduleValue.SourceVSize > SrcHeight))
{
WinOfsEn=1;
}
s6400CAM->CIWDOFST = (WinOfsEn<<31)|((moduleValue.SourceHOffset+gHorOffset1) <<16)|(moduleValue.SourceVOffset+gVerOffset1);
s6400CAM->CIDOWSFT2 = ((moduleValue.SourceHOffset+gHorOffset2) <<16)|(moduleValue.SourceVOffset+gVerOffset2);
CalculatePrescalerRatioShift(SrcWidth, width, &PreHorRatio, &H_Shift);
CalculatePrescalerRatioShift(SrcHeight, height, &PreVerRatio, &V_Shift);
MainHorRatio=(SrcWidth<<8)/(width<<H_Shift);
MainVerRatio=(SrcHeight<<8)/(height<<V_Shift);
if(SrcWidth>=width) ScaleUp_H=0; //down
else ScaleUp_H=1; //up
if(SrcHeight>=height) ScaleUp_V=0;
else ScaleUp_V=1;
switch(path)
{
case PREVIEW_PATH:
s6400CAM->CIPRSCPRERATIO=((10-H_Shift-V_Shift)<<28)|(PreHorRatio<<16)|(PreVerRatio);
s6400CAM->CIPRSCPREDST=((SrcWidth/PreHorRatio)<<16)|(SrcHeight/PreVerRatio);
s6400CAM->CIPRSCCTRL = (s6400CAM->CIPRSCCTRL & ~((0x1<<31)|(0x1<<30)|(0x1<<29)|(0x1ff<<16)|(0x1ff<<0)))
|(0<<31)|(ScaleUp_H<<30)|(ScaleUp_V<<29)|(MainHorRatio<<16)|(MainVerRatio);
break;
case CODEC_PATH:
s6400CAM->CICOSCPRERATIO=((10-H_Shift-V_Shift)<<28)|(PreHorRatio<<16)|(PreVerRatio);
s6400CAM->CICOSCPREDST=((SrcWidth/PreHorRatio)<<16)|(SrcHeight/PreVerRatio);
s6400CAM->CICOSCCTRL=(s6400CAM->CICOSCCTRL & ~((0x1<<31)|(0x1<<30)|(0x1<<29)|(0x1ff<<16)|(0x1ff<<0)))
|(0<<31)|(ScaleUp_H<<30)|(ScaleUp_V<<29)|(MainHorRatio<<16)|(MainVerRatio);
break;
}
RETAILMSG(CAM_INOUT,(TEXT("-------------------CameraSetScaler\n")));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -