📄 dc1394_control.c
字号:
/* * 1394-Based Digital Camera Control Library * Copyright (C) 2000 SMART Technologies Inc. * * Written by Gord Peters <GordPeters@smarttech.com> * Additions by Chris Urmson <curmson@ri.cmu.edu> * Additions by Damien Douxchamps <douxchamps@ieee.org> * * Acknowledgments: * Per Dalgas Jakobsen <pdj@maridan.dk> * - Added retries to ROM and CSR reads * - Nicer endianness handling * * Robert Ficklin <rficklin@westengineering.com> * - bug fixes * * Julie Andreotti <JulieAndreotti@smarttech.com> * - bug fixes * * Ann Dang <AnnDang@smarttech.com> * - bug fixes * * Dan Dennedy <dan@dennedy.org> * - bug fixes * * Yves Jaeger <yves.jaeger@fraenz-jaeger.de> * - software trigger functions * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include <string.h>#include <netinet/in.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/ioctl.h>#include <sys/mman.h>#include <errno.h>#include "config.h"#include "dc1394_control.h"#include "dc1394_internal.h"#include "kernel-video1394.h"/********************//* Base ROM offsets */ /********************/#define ROM_BUS_INFO_BLOCK 0x400U#define ROM_ROOT_DIRECTORY 0x414U#define CSR_CONFIG_ROM_END 0x800U/**********************************//* Configuration Register Offsets *//**********************************//* See the 1394-Based Digital Camera Spec. for definitions of these */#define REG_CAMERA_INITIALIZE 0x000U#define REG_CAMERA_V_FORMAT_INQ 0x100U#define REG_CAMERA_V_MODE_INQ_BASE 0x180U#define REG_CAMERA_V_RATE_INQ_BASE 0x200U#define REG_CAMERA_V_REV_INQ_BASE 0x2C0U#define REG_CAMERA_BASIC_FUNC_INQ 0x400U#define REG_CAMERA_FEATURE_HI_INQ 0x404U#define REG_CAMERA_FEATURE_LO_INQ 0x408U#define REG_CAMERA_ADV_FEATURE_INQ 0x480U#define REG_CAMERA_FEATURE_HI_BASE_INQ 0x500U#define REG_CAMERA_FEATURE_LO_BASE_INQ 0x580U#define REG_CAMERA_FRAME_RATE 0x600U#define REG_CAMERA_VIDEO_MODE 0x604U#define REG_CAMERA_VIDEO_FORMAT 0x608U#define REG_CAMERA_ISO_DATA 0x60CU#define REG_CAMERA_POWER 0x610U#define REG_CAMERA_ISO_EN 0x614U#define REG_CAMERA_MEMORY_SAVE 0x618U#define REG_CAMERA_ONE_SHOT 0x61CU#define REG_CAMERA_MEM_SAVE_CH 0x620U#define REG_CAMERA_CUR_MEM_CH 0x624U#define REG_CAMERA_SOFT_TRIGGER 0x62CU#define REG_CAMERA_DATA_DEPTH 0x630U#define REG_CAMERA_FEATURE_HI_BASE 0x800U#define REG_CAMERA_FEATURE_LO_BASE 0x880U#define REG_CAMERA_BRIGHTNESS 0x800U#define REG_CAMERA_EXPOSURE 0x804U#define REG_CAMERA_SHARPNESS 0x808U#define REG_CAMERA_WHITE_BALANCE 0x80CU#define REG_CAMERA_HUE 0x810U#define REG_CAMERA_SATURATION 0x814U#define REG_CAMERA_GAMMA 0x818U#define REG_CAMERA_SHUTTER 0x81CU#define REG_CAMERA_GAIN 0x820U#define REG_CAMERA_IRIS 0x824U#define REG_CAMERA_FOCUS 0x828U#define REG_CAMERA_TEMPERATURE 0x82CU#define REG_CAMERA_TRIGGER_MODE 0x830U#define REG_CAMERA_TRIGGER_DELAY 0x834U#define REG_CAMERA_WHITE_SHADING 0x838U#define REG_CAMERA_FRAME_RATE_FEATURE 0x83CU#define REG_CAMERA_ZOOM 0x880U#define REG_CAMERA_PAN 0x884U#define REG_CAMERA_TILT 0x888U#define REG_CAMERA_OPTICAL_FILTER 0x88CU#define REG_CAMERA_CAPTURE_SIZE 0x8C0U#define REG_CAMERA_CAPTURE_QUALITY 0x8C4U /***********************//* Macro definitions *//***********************/#define FEATURE_TO_VALUE_OFFSET(feature, offset) \ \ if ( (feature > FEATURE_MAX) || (feature < FEATURE_MIN) ) \ { \ return DC1394_FAILURE; \ } \ else if (feature < FEATURE_ZOOM) \ { \ offset= REG_CAMERA_FEATURE_HI_BASE; \ feature-= FEATURE_MIN; \ } \ else \ { \ offset= REG_CAMERA_FEATURE_LO_BASE; \ \ if (feature >= FEATURE_CAPTURE_SIZE) \ { \ feature+= 12; \ } \ feature-= FEATURE_ZOOM; \ \ } \ \ offset+= feature * 0x04U;#define FEATURE_TO_INQUIRY_OFFSET(feature, offset) \ \ if ( (feature > FEATURE_MAX) || (feature < FEATURE_MIN) ) \ { \ return DC1394_FAILURE; \ } \ else if (feature < FEATURE_ZOOM) \ { \ offset= REG_CAMERA_FEATURE_HI_BASE_INQ; \ feature-= FEATURE_MIN; \ } \ else \ { \ offset= REG_CAMERA_FEATURE_LO_BASE_INQ; \ \ if (feature >= FEATURE_CAPTURE_SIZE) \ { \ feature+= 12; \ } \ feature-= FEATURE_ZOOM; \ \ } \ \ offset+= feature * 0x04U;/**************************//* Constant definitions *//**************************/const char *dc1394_feature_desc[NUM_FEATURES] ={ "Brightness", "Exposure", "Sharpness", "White Balance", "Hue", "Saturation", "Gamma", "Shutter", "Gain", "Iris", "Focus", "Temperature", "Trigger", "Zoom", "Pan", "Tilt", "Optical Filter", "Capture Size", "Capture Quality"};/* These arrays define how many image quadlets there are in a packet given a mode and a frame rate This is defined in the 1394 digital camera spec */const int quadlets_per_packet_format_0[56] = { -1, -1, 15, 30, 60, 120, 240, 480, 10, 20, 40, 80, 160, 320, 640, 1280, 30, 60, 120, 240, 480, 960, 1920, 3840, 40, 80, 160, 320, 640, 1280, 2560, 5120, 60, 120, 240, 480, 960, 1920, 3840, 7680, 20, 40, 80, 160, 320, 640, 1280, 2560, 40, 80, 160, 320, 640, 1280, 2560, 5120}; const int quadlets_per_packet_format_1[64] = { -1, 125, 250, 500, 1000, 2000, 4000, 8000, -1, -1, 375, 750, 1500, 3000, 6000, -1, -1, -1, 125, 250, 500, 1000, 2000, 4000, 96, 192, 384, 768, 1536, 3072, 6144, -1, 144, 288, 576, 1152, 2304, 4608, -1, -1, 48, 96, 192, 384, 768, 1536, 3073, 6144, -1, 125, 250, 500, 1000, 2000, 4000, 8000, 96, 192, 384, 768, 1536, 3072, 6144, -1}; const int quadlets_per_packet_format_2[64] = { 160, 320, 640, 1280, 2560, 5120, -1, -1, 240, 480, 960, 1920, 3840, 7680, -1, -1, 80, 160, 320, 640, 1280, 2560, 5120, -1, 250, 500, 1000, 2000, 4000, 8000, -1, -1, 375, 750, 1500, 3000, 6000, -1, -1, -1, 125, 250, 500, 1000, 2000, 4000, 8000, -1, 160, 320, 640, 1280, 2560, 5120, -1, -1, 250, 500, 1000, 2000, 4000, 8000, -1, -1}; /**********************//* Internal functions *//**********************/int_dc1394_get_wh_from_format(int format, int mode, int *w, int *h) { switch(format) { case FORMAT_VGA_NONCOMPRESSED: switch(mode) { case MODE_160x120_YUV444: *w = 160;*h=120; return DC1394_SUCCESS; case MODE_320x240_YUV422: *w = 320;*h=240; return DC1394_SUCCESS; case MODE_640x480_YUV411: case MODE_640x480_YUV422: case MODE_640x480_RGB: case MODE_640x480_MONO: case MODE_640x480_MONO16: *w =640;*h=480; return DC1394_SUCCESS; default: return DC1394_FAILURE; } case FORMAT_SVGA_NONCOMPRESSED_1: switch(mode) { case MODE_800x600_YUV422: case MODE_800x600_RGB: case MODE_800x600_MONO: case MODE_800x600_MONO16: *w=800;*h=600; return DC1394_SUCCESS; case MODE_1024x768_YUV422: case MODE_1024x768_RGB: case MODE_1024x768_MONO: case MODE_1024x768_MONO16: *w=1024;*h=768; return DC1394_SUCCESS; default: return DC1394_FAILURE; } case FORMAT_SVGA_NONCOMPRESSED_2: switch(mode) { case MODE_1280x960_YUV422: case MODE_1280x960_RGB: case MODE_1280x960_MONO: case MODE_1280x960_MONO16: *w=1280;*h=960; return DC1394_SUCCESS; case MODE_1600x1200_YUV422: case MODE_1600x1200_RGB: case MODE_1600x1200_MONO: case MODE_1600x1200_MONO16: *w=1600;*h=1200; return DC1394_SUCCESS; default: return DC1394_FAILURE; } default: return DC1394_FAILURE; }} /******************************************************** _dc1394_get_quadlets_per_packet This routine reports the number of useful image quadlets per packet*********************************************************/int _dc1394_get_quadlets_per_packet(int format, int mode, int frame_rate) { int mode_index, frame_rate_index= frame_rate - FRAMERATE_MIN; switch(format) { case FORMAT_VGA_NONCOMPRESSED: mode_index= mode - MODE_FORMAT0_MIN; if ( ((mode >= MODE_FORMAT0_MIN) && (mode <= MODE_FORMAT0_MAX)) && ((frame_rate >= FRAMERATE_MIN) && (frame_rate <= FRAMERATE_MAX)) ) { return quadlets_per_packet_format_0[NUM_FRAMERATES*mode_index+frame_rate_index]; } else { printf("(%s) Invalid framerate (%d) or mode (%d)!\n", __FILE__, frame_rate, format); } break; case FORMAT_SVGA_NONCOMPRESSED_1: mode_index= mode - MODE_FORMAT1_MIN; if ( ((mode >= MODE_FORMAT1_MIN) && (mode <= MODE_FORMAT1_MAX)) && ((frame_rate >= FRAMERATE_MIN) && (frame_rate <= FRAMERATE_MAX)) ) { return quadlets_per_packet_format_1[NUM_FRAMERATES*mode_index+frame_rate_index]; } else { printf("(%s) Invalid framerate (%d) or mode (%d)!\n", __FILE__, frame_rate, format); } break; case FORMAT_SVGA_NONCOMPRESSED_2: mode_index= mode - MODE_FORMAT2_MIN; if ( ((mode >= MODE_FORMAT2_MIN) && (mode <= MODE_FORMAT2_MAX)) && ((frame_rate >= FRAMERATE_MIN) && (frame_rate <= FRAMERATE_MAX)) ) { return quadlets_per_packet_format_2[NUM_FRAMERATES*mode_index+frame_rate_index]; } else { printf("(%s) Invalid framerate (%d) or mode (%d)!\n", __FILE__, frame_rate, format); } break; default: printf("(%s) Quadlets per packet unkown for format %d!\n", __FILE__, format); break; } return -1;}/********************************************************** _dc1394_quadlets_from_format This routine reports the number of quadlets that make up a frame given the format and mode***********************************************************/int_dc1394_quadlets_from_format(int format, int mode) { switch (format) { case FORMAT_VGA_NONCOMPRESSED: switch(mode) { case MODE_160x120_YUV444: return 14400; //160x120*3/4 case MODE_320x240_YUV422: return 38400; //320x240/2 case MODE_640x480_YUV411: return 115200; //640x480x1.5/4 case MODE_640x480_YUV422: return 153600; //640x480/2 case MODE_640x480_RGB: return 230400; //640x480x3/4 case MODE_640x480_MONO: return 76800; //640x480/4 case MODE_640x480_MONO16: return 153600; //640x480/2 default: printf("(%s) Improper mode specified: %d\n", __FILE__, mode); break; } break; case FORMAT_SVGA_NONCOMPRESSED_1: switch(mode) { case MODE_800x600_YUV422: return 240000; //800x600/2 case MODE_800x600_RGB: return 360000; //800x600x3/4 case MODE_800x600_MONO: return 120000; //800x600/4 case MODE_1024x768_YUV422: return 393216; //1024x768/2 case MODE_1024x768_RGB: return 589824; //1024x768x3/4 case MODE_1024x768_MONO: return 196608; //1024x768/4 case MODE_800x600_MONO16: return 240000; //800x600/2 case MODE_1024x768_MONO16: return 393216; //1024x768/2 default: printf("(%s) Improper mode specified: %d\n", __FILE__, mode); break; } break; case FORMAT_SVGA_NONCOMPRESSED_2: switch (mode) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -