www.pudn.com > camera.rar > 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#include #include "Cs.h" #include "Csmedia.h" #include "CameraPDDProps.h" #include "dstruct.h" #include "dbgsettings.h" #include #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); }