📄 video4avc1394.cxx
字号:
/* * This file is essentially a rewrite of video4dc1394.cxx * Check that one for more explanations * * A lot of code "borrowed" from * - dvgrab.c from libdv (http://libdv.sf.net/) * - kino (http://kino.schirmacher.de/) * - video4dc1394.cxx from ptlib * - ... probably others too * * The code is highly experimental. * You should expect any of : * - plenty of segfaults * - loss of performance * - not working at all for you * * Known Bugs / Limitations / Room for improvement (feel free to patch/suggest) * - Colors are no good after a Convert * Can someone look at the code and tell me what I have to tell the convert function * that my source colors are? I thought it is pure RGB24, but obviously not. * Dumping the binary data directly to a PPM file works like a charm, though :-/ * - Occasional segfaults (I think these are fixed, but don't be surprised if it works not) * - grabs first camera by default (not sure how to go about selection of cameras/ports) * - still haven't figured what the channel parameter in start_iso_rcv(handle,channel) means, * but it seems that we are in for a long wait if channel != 63 * - code depends on libavc1394 to figure out if a device is a camera * I am not really sure there isn't a smarter way of going about it * since capturing video only requires libraw1394 (for the moment) * Maybe we can drop that dependency? * - Still not sure how to go about setting frame size. * Resizing manually at the moment, since the frame size of a captured frame * from an AVC camera is not settable. * An AVC camera supports either NTSC (720x480) or PAL (720x576) resolution * and the only way to check which one it is, seems to be to parse the header * of a captured frame. Will wait for a suggestion on the proper way to handle it. * - bus resets not handled (yet?) * - Still not sure what to use the device name for (beats me :( ) * - not sure if TRY_1394AVC and TRY_1394DC will not break something if used at the same time * - Overuse of PTRACE? * - I am not sure how most of the stuff works * - ... everything else * * Technical Notes * ------------------------------------------------------------ * * Test Environment: * This module was tested against: * Hardware: * AthlonXP 1800+ * Asus A7S333 * Sony DCR-TRV20 NTSC (http://www.sony.jp/products/Consumer/VD/DCR-TRV20/) * Texas Instruments TSB12LV26 IEEE-1394 Controller * Software: * Linux vanilla kernel 2.4.20 * libraw1394 0.9.0 * libavc1394 0.4.1 * libdv 0.98 * * Author: Georgi Georgiev <chutz@gg3.net> * */#pragma implementation "videoio1394avc.h"#include <ptlib.h>#include <ptlib/videoio.h>#include <ptlib/videoio1394avc.h>#include <ptlib/vconvert.h>#include <ptlib/file.h>#include <sys/utsname.h>//#define ESTIMATE_CAPTURE_PERFORMANCE#ifdef ESTIMATE_CAPTURE_PERFORMANCE// for debuggingstatic PInt64 start_time;static int num_captured;#endif#ifndef RAW_BUFFER_SIZE#define RAW_BUFFER_SIZE 512#endif static u_int8_t raw_buffer[RAW_BUFFER_SIZE];///////////////////////////////////////////////////////////////////////////////// PVideoInput1394AVCPVideoInput1394AvcDevice::PVideoInput1394AvcDevice(){ PTRACE(3, "PVideo1394AvcDevice::PVideo1394AvcDevice()"); handle = NULL; is_capturing = FALSE; capturing_duration = 10000; // arbitrary large value suffices dv_decoder = NULL;}PVideoInput1394AvcDevice::~PVideoInput1394AvcDevice(){ Close();}static int kernel_version_ok(void){ PTRACE(3, "kernel_version_ok()"); raw1394handle_t handle; handle = raw1394_new_handle(); if (handle == NULL && errno == 0) { return FALSE; } raw1394_destroy_handle(handle); return TRUE;}BOOL PVideoInput1394AvcDevice::Open(const PString & devName, BOOL startImmediate){ PTRACE(3, "PVideoInput1394AvcDevice::Open"); if (!kernel_version_ok()) { PTRACE(0, "The Linux kernel version is not compatible"); return FALSE; } if (IsOpen()) { PTRACE(0, "You cannot open PVideoInput1394AvcDevice twice."); return FALSE; }// Haven't figure how to use DMA, but let's set anyways// Not sure what we need device name for anyway if (devName == "/dev/raw1394") UseDMA = FALSE; // Don't forget /dev/video1394/0 else if (strncmp(devName, "/dev/video1394", 14) == 0) UseDMA = TRUE; else { PTRACE(0, "devName must be /dev/raw1394 or /dev/video1394*"); return FALSE; } // See if devName is accessible. if (!PFile::Exists(devName)) { PTRACE(1, devName << " is not accessible."); return FALSE; } /*----------------------------------------------------------------------- * Open ohci and asign handle to it *-----------------------------------------------------------------------*/ handle = raw1394_new_handle(); if (handle==NULL) { PTRACE(0, "Unable to aquire a raw1394 handle" "did you insmod the drivers?\n"); return FALSE; } /*----------------------------------------------------------------------- * get the camera nodes and describe them as we find them *-----------------------------------------------------------------------*/ // Still not letting the user choose a camera though struct raw1394_portinfo g_pinf[16]; int num_cards = raw1394_get_port_info(handle, g_pinf, 16); if (num_cards < 0) { PTRACE(0,"Couldn't get card info"); raw1394_destroy_handle(handle); handle = NULL; return FALSE; } for (int i=0;i<num_cards;i++) { PTRACE(3, "Found card "<< g_pinf[i].name << " with " << g_pinf[i].nodes << " nodes"); } GetAvcCameras(); if (numCameras < 1) { PTRACE(0, "no cameras found"); raw1394_destroy_handle(handle); handle = NULL; return FALSE; }// SetFrameSize(CIFHeight, CIFWidth); /* frameWidth = CIFHeight; frameHeight = CIFWidth;// colourFormat = "UYVY422"; colourFormat = "RGB24"; */ frameWidth = CIFWidth; frameHeight = CIFHeight; colourFormat = "RGB24F"; desiredFrameHeight = CIFHeight; desiredFrameWidth = CIFWidth; desiredColourFormat = "RGB24F"; capturing_duration = 10000; // arbitrary large value suffices deviceName = devName; // select the specified input and video format if (!SetChannel(channelNumber) || !SetVideoFormat(videoFormat)) { PTRACE(1, "SetChannel() or SetVideoFormat() failed"); Close(); return FALSE; } if (startImmediate && !Start()) { Close(); return FALSE; } PTRACE(3, "Successfully opened avc1394"); return TRUE;}BOOL PVideoInput1394AvcDevice::IsOpen() { return handle != NULL;}BOOL PVideoInput1394AvcDevice::Close(){ PTRACE(3, "Close()"); if (IsOpen()) { if (IsCapturing()) Stop(); raw1394_destroy_handle(handle); handle = NULL; return TRUE; } else return FALSE;}BOOL PVideoInput1394AvcDevice::Start(){ PTRACE(3, "Start()"); if (!IsOpen()) return FALSE; if (IsCapturing()) return TRUE; /* if (frameWidth == 320 && frameHeight == 240) ; else if (frameWidth == 160 && frameHeight == 120) ; else { PTRACE(1, "Frame size is neither 320x240 or 160x120" << frameWidth << "x" << frameHeight); return FALSE; } */ PTRACE(1, "Using " << deviceName << " at channel " << channelNumber); /*----------------------------------------------------------------------- * have the camera start sending us data *-----------------------------------------------------------------------*/ // will figure channel numbers later // channelNumber = 63?? if (raw1394_set_iso_handler(handle, 63, & RawISOHandler)!= NULL) { PTRACE (0, "Cannot set_iso_handler"); return FALSE; }#if 0 // channelNumber 63 if (raw1394_start_iso_rcv(handle, 63) < 0) { PTRACE (0, "Cannot start_iso_rcv"); return FALSE; }#endif is_capturing = TRUE;#ifdef ESTIMATE_CAPTURE_PERFORMANCE PTime now; start_time = now.GetTimestamp(); num_captured = 0;#endif return TRUE;}BOOL PVideoInput1394AvcDevice::Stop(){ PTRACE(3,"Stop()"); if (IsCapturing()) { // channelNumber #if 0 raw1394_stop_iso_rcv(handle, 63); #endif is_capturing = FALSE; return TRUE; } else return FALSE;}BOOL PVideoInput1394AvcDevice::IsCapturing(){ return is_capturing;}PStringList PVideoInput1394AvcDevice::GetInputDeviceNames(){ PTRACE(3, "GetInputDeviceNames()"); PStringList list;// The control of the device does not require the device name anywhere, but still... if (PFile::Exists("/dev/raw1394")) list.AppendString("/dev/raw1394"); if (PFile::Exists("/dev/video1394/0")) // DEVFS naming scheme for (int i=0; ; i++) { PString devname = PString("/dev/video1394/") + PString(i); if (PFile::Exists(devname)) list.AppendString(devname); else break; } else if (PFile::Exists("/dev/video1394")) /* traditional naming */ list.AppendString("/dev/video1394"); return list;}BOOL PVideoInput1394AvcDevice::SetVideoFormat(VideoFormat newFormat){ PTRACE(3, "SetVideoFormat("<<newFormat<<")"); if (!PVideoDevice::SetVideoFormat(newFormat)) { PTRACE(3,"PVideoDevice::SetVideoFormat\t failed for format "<<newFormat); return FALSE; } return TRUE;}int PVideoInput1394AvcDevice::GetBrightness(){ return -1;}BOOL PVideoInput1394AvcDevice::SetBrightness(unsigned newBrightness){ return FALSE;}int PVideoInput1394AvcDevice::GetHue(){ return -1;}BOOL PVideoInput1394AvcDevice::SetHue(unsigned newHue){ return FALSE;}int PVideoInput1394AvcDevice::GetContrast(){ return -1;}BOOL PVideoInput1394AvcDevice::SetContrast(unsigned newContrast){ return FALSE;}BOOL PVideoInput1394AvcDevice::SetColour(unsigned newColour) { return -1;}int PVideoInput1394AvcDevice::GetColour(){ return -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -