📄 camera.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
//
// (C) Copyright 2006 Marvell International Ltd.
// All Rights Reserved
//
#include <windows.h>
#include <pm.h>
#include "Cs.h"
#include "Csmedia.h"
#include "CameraPDDProps.h"
#include "dstruct.h"
#include "dbgsettings.h"
#include <Camera.h>
#include "CameraDriver.h"
#include "PinDriver.h"
#include "camerapdd.h"
#include "pdd_private.h"
TCHAR *dev_name = L"CAM1";
void CCameraPdd::init_ipm_client()
{
//set up IPM
//TCHAR szTemp[MAX_PATH];
IPM_STATUS_T status;
is_ipm_enabled = FALSE;
ipm_block_ref_count = 0;
// IPM Registration:
status = IPM_Register(dev_name, &(ipm_client_id) ,3000);
if ( status==IPM_STATUS_SUCCESS)
{
DWORD dwProcState;
DEBUGMSG(ZONE_IOCTL,(L"CAM: [%s] Registration Completed, client id is %d\r\n",dev_name, ipm_client_id));
dwProcState = IPM_PROCESSOR_D0_RDY | IPM_PROCESSOR_RING_OSC_RDY | IPM_PROCESSOR_D2_RDY| IPM_PROCESSOR_D1_RDY; // Initial
// Notify IPM
DEBUGMSG(ZONE_IOCTL,(L"CAM: [%s] Initial Notify IPM Ready For Processor state. dwProcState=%x \r\n", dev_name, dwProcState));
if (IPM_NotifyReadyForProcState(ipm_client_id, dwProcState ,3000) != IPM_STATUS_SUCCESS)
DEBUGMSG(ZONE_IOCTL,(L"CAM: [%s] Notify IPM Ready For Processor state for driver FAILED\r\n", dev_name));
is_ipm_enabled = TRUE;
}
else if(status == IPM_STATUS_IPM_DISABLED)
DEBUGMSG(ZONE_IOCTL,(L"CAM: [%s] NOIPM \r\n", dev_name));
else
DEBUGMSG(ZONE_IOCTL,(L"CAM: [%s] Registration Failed, IPM Error %d\r\n", dev_name, status));
}
void CCameraPdd::set_ipm_block(BOOL is_on)
{
if (!is_ipm_enabled)
return;
if (is_on)
{
ipm_block_ref_count++;
if (ipm_block_ref_count > 1)
return;
}
else
{
if (ipm_block_ref_count)
{
ipm_block_ref_count--;
if (ipm_block_ref_count)
return;
} else
return;
}
DEBUGMSG(ZONE_IOCTL,(L"CAM: set_ipm_block %d, ref count %d!\r\n", is_on, ipm_block_ref_count));
DWORD dwProcState;
dwProcState = IPM_PROCESSOR_D0_RDY
| IPM_PROCESSOR_RING_OSC_RDY
| IPM_PROCESSOR_D2_RDY
| IPM_PROCESSOR_D1_RDY; // Initial
if (ipm_block_ref_count)
dwProcState = IPM_PROCESSOR_D0_RDY;
IPM_STATUS_T status;
status = IPM_NotifyReadyForProcState(ipm_client_id, dwProcState, 1000);
if (status != IPM_STATUS_SUCCESS)
DEBUGMSG( ZONE_IOCTL, ( _T("CAM: camera IPM_NotifyReadyForProcState failed!\r\n")) );
if (ipm_block_ref_count)
status = IPM_SetFreqChangeBlock(ipm_client_id, 1000);
else
status = IPM_ReleaseFreqChangeBlock(ipm_client_id, 1000);
if (status != IPM_STATUS_SUCCESS)
DEBUGMSG( ZONE_IOCTL, ( _T("CAM: camera IPM_SetFreqChangeBlock failed!\r\n")) );
}
void CCameraPdd::power_on()
{
qci_clock_enable(1);
qci_set_interface(sensor->get_qci_interface());
sensor->set_power_mode(1);
Sleep(1);
}
bool CCameraPdd::detect_sensor()
{
set_ipm_block(1);
power_on();
qci_enable();
Sleep(150);
bool detected = sensor->detect();
if (detected)
sensor->stop_capture();
is_sensor_on = 1;
set_ipm_block(0);
return detected;
}
void CCameraPdd::power_off()
{
qci_stop_capture();
sensor->set_power_mode(0);
qci_clock_enable(0);
is_sensor_on = 0;
}
void CCameraPdd::set_capture_format(int sensor_format,
FrameSize sensor_size,
format_t* qci_format)
{
qci_master_timing_t timing;
timing.width = qci_format->width - 1;
timing.height = qci_format->height - 1;
if (qci_format->format != sensor_format)
timing.height++;
timing.timing = sensor->get_timing();
sensor->set_frame_format(sensor_format, sensor_size);
qci_set_master_timing(&timing);
qci_set_image_format(sensor_format, qci_format->format);
qci_set_frame_format(qci_format);
}
void CCameraPdd::start_capture(ULONG mode)
{
set_ipm_block(1);
PCS_VIDEOINFOHEADER video_info;
video_info = &m_pCurrentFormat[mode].VideoInfoHeader;
UINT32 width = video_info->bmiHeader.biWidth;
UINT32 height = video_info->bmiHeader.biHeight;
qci_image_proc_cfg_t qci_cfg;
qci_image_proc_cfg_t* qci_cfg_ptr = 0;
float *coe;
if (!is_sensor_on)
detect_sensor();
camera_cfg = sensor->get_camera_cfg(video_info, mode);
set_capture_format(camera_cfg->sensor_format,
camera_cfg->sensor_size,
&camera_cfg->qci_format);
// coefficent for color conversion.
if (camera_cfg->color_cfg)
{
coe = camera_cfg->color_cfg->color_correct_coe;
qci_cfg.coe.k00 = QCI_COE_CONVERT(0.299 * coe[0] + 0.587 * coe[3] + 0.114 * coe[6]);
qci_cfg.coe.k01 = QCI_COE_CONVERT(0.299 * coe[1] + 0.587 * coe[4] + 0.114 * coe[7]);
qci_cfg.coe.k02 = QCI_COE_CONVERT(0.299 * coe[2] + 0.587 * coe[5] + 0.114 * coe[8]);
qci_cfg.coe.k10 = QCI_COE_CONVERT(-0.16874 * coe[0] -0.33126 * coe[3] + 0.5 * coe[6]);
qci_cfg.coe.k11 = QCI_COE_CONVERT(-0.16874 * coe[1] -0.33126 * coe[4] + 0.5 * coe[7]);
qci_cfg.coe.k12 = QCI_COE_CONVERT(-0.16874 * coe[2] -0.33126 * coe[5] + 0.5 * coe[8]);
qci_cfg.coe.k20 = QCI_COE_CONVERT(0.5 * coe[0] -0.41869 * coe[3] - 0.08131 * coe[6]);
qci_cfg.coe.k21 = QCI_COE_CONVERT(0.5 * coe[1] -0.41869 * coe[4] - 0.08131 * coe[7]);
qci_cfg.coe.k22 = QCI_COE_CONVERT(0.5 * coe[2] -0.41869 * coe[5] - 0.08131 * coe[8]);
qci_cfg.scale = 0;
qci_cfg.black_level = camera_cfg->color_cfg->black_level;
qci_cfg.lut = camera_cfg->color_cfg->gama;
qci_cfg_ptr = &qci_cfg;
}
// CMU will not be enabled when input is raw data
if (camera_cfg->qci_format.format != PXA_CAMERA_IMAGE_FORMAT_RAW10)
qci_set_image_proc_cfg(qci_cfg_ptr);
#define DEFAULT_STILL_SKIPS 2
qci_start_capture(mode == STILL? DEFAULT_STILL_SKIPS : 0);
sensor->start_capture();
}
void CCameraPdd::stop_capture()
{
sensor->stop_capture();
qci_stop_capture();
set_ipm_block(0);
}
const UINT32 color_proc_max_width = 1280;
const UINT32 color_proc_max_height = 1024;
void fill_plane(PUCHAR dest, plane_t* plane, UINT32 size)
{
DEBUGMSG(ZONE_IOCTL,(L"CAM: DestAddr:0x%08x, BufAddr:0x%08x, size:%d\r\n", dest, plane->buf.buf, size));
memcpy(dest, plane->buf.buf, plane->buf.size);
}
void fill_plane_cb_cr(PUCHAR dest, PUCHAR src,
UINT32 width, UINT32 height)
{
for (UINT32 i = 0; i < height; i++)
{
memcpy(dest, src, width);
dest += width;
src += width << 1;
}
}
void fill_buffer_yv12(PUCHAR* dest_plane, frame_t* frame)
{
format_t *format = &frame->list->format;
UINT32 y_size = format->width * format->height;
fill_plane(dest_plane[0], &frame->plane[0], y_size);
DEBUGMSG(ZONE_IOCTL,(L"CAM: DestAddr:0x%08x, BufAddr:0x%08x, cbcr...", dest_plane[2], frame->plane[1].buf.buf));
fill_plane_cb_cr(dest_plane[2], (PUCHAR)frame->plane[1].buf.buf,
format->width >> 1, format->height >> 1);
DEBUGMSG(ZONE_IOCTL,(L"CAM: DestAddr:0x%08x, BufAddr:0x%08x, cbcr...", dest_plane[1], frame->plane[2].buf.buf));
fill_plane_cb_cr(dest_plane[1], (PUCHAR)frame->plane[2].buf.buf,
format->width >> 1, format->height >> 1);
}
#define CROP_RGGB
void convert_rggb10_rgb565(UINT16 *dst, UINT16 *src,
UINT32 dst_width, UINT32 dst_height,
UINT32 src_width, UINT32 src_height)
{
UINT32 src_x0_pos = 0;
UINT32 src_pos = 0;
UINT32 line_step = src_height / dst_height / 2;
line_step *= 2;
UINT32 col_step = src_width / dst_width / 2;
col_step *= 2;
UINT32 src_size = src_width * src_height;
#ifdef CROP_RGGB
line_step = 2;
col_step = 2;
#endif
UINT32 line, col;
for (line = 0; line < dst_height && (src_x0_pos + src_width) < src_size; line++)
{
for (col = 0; col < dst_width && (src_pos + 1 - src_x0_pos) < src_width; col++)
{
UINT16 r = src[src_pos];
UINT16 g = (src[src_pos + 1] + src[src_pos + src_width]) >> 1;
UINT16 b = src[src_pos + src_width + 1];
dst[line * dst_width + col] = ((r >> 5) << 11) | ((g >> 4) << 5) | (b >> 5);
src_pos += col_step;
}
src_x0_pos += src_width * line_step;
src_pos = src_x0_pos;
}
}
#ifndef _CALLBACK
#define _CALLBACK __STDCALL
#endif
void* _CALLBACK ippiMalloc(int size)
{
return malloc(size);
}
void _CALLBACK ippiFree(void* pSrcBuf)
{
free(pSrcBuf);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -