📄 vidinput_bsd.cxx
字号:
// set the information
if (::ioctl(videoFd, METEORSINPUT, &channel) < 0)
return FALSE;
return TRUE;
}
BOOL PVideoInputDevice_BSDCAPTURE::SetColourFormat(const PString & newFormat)
{
if (!PVideoDevice::SetColourFormat(newFormat))
return FALSE;
ClearMapping();
frameBytes = CalculateFrameBytes(frameWidth, frameHeight, colourFormat);
return TRUE;
}
BOOL PVideoInputDevice_BSDCAPTURE::SetFrameRate(unsigned rate)
{
if (!PVideoDevice::SetFrameRate(rate))
return FALSE;
return TRUE;
}
BOOL PVideoInputDevice_BSDCAPTURE::GetFrameSizeLimits(unsigned & minWidth,
unsigned & minHeight,
unsigned & maxWidth,
unsigned & maxHeight)
{
if (!IsOpen())
return FALSE;
minWidth = videoCapability.minwidth;
minHeight = videoCapability.minheight;
maxWidth = videoCapability.maxwidth;
maxHeight = videoCapability.maxheight;
return TRUE;
}
BOOL PVideoInputDevice_BSDCAPTURE::SetFrameSize(unsigned width, unsigned height)
{
if (!PVideoDevice::SetFrameSize(width, height))
return FALSE;
ClearMapping();
frameBytes = CalculateFrameBytes(frameWidth, frameHeight, colourFormat);
return TRUE;
}
PINDEX PVideoInputDevice_BSDCAPTURE::GetMaxFrameBytes()
{
return GetMaxFrameBytesConverted(frameBytes);
}
BOOL PVideoInputDevice_BSDCAPTURE::GetFrameData(BYTE * buffer, PINDEX * bytesReturned)
{
if(frameRate>0) {
frameTimeError += msBetweenFrames;
do {
if ( !GetFrameDataNoDelay(buffer, bytesReturned))
return FALSE;
PTime now;
PTimeInterval delay = now - previousFrameTime;
frameTimeError -= (int)delay.GetMilliSeconds();
previousFrameTime = now;
} while(frameTimeError > 0) ;
return TRUE;
}
return GetFrameDataNoDelay(buffer,bytesReturned);
}
BOOL PVideoInputDevice_BSDCAPTURE::GetFrameDataNoDelay(BYTE * buffer, PINDEX * bytesReturned)
{
// Hack time. It seems that the Start() and Stop() functions are not
// actually called, so we will have to initialise the frame grabber
// here on the first pass through this GetFrameData() function
if (canMap < 0) {
struct meteor_geomet geo;
geo.rows = frameHeight;
geo.columns = frameWidth;
geo.frames = 1;
geo.oformat = METEOR_GEO_YUV_422 | METEOR_GEO_YUV_12;
// Grab even field (instead of interlaced frames) where possible to stop
// jagged interlacing artifacts. NTSC is 640x480, PAL/SECAM is 768x576.
if ( ((PVideoDevice::GetVideoFormat() == PAL) && (frameHeight <= 288))
|| ((PVideoDevice::GetVideoFormat() == SECAM) && (frameHeight <= 288))
|| ((PVideoDevice::GetVideoFormat() == NTSC) && (frameHeight <= 240)) ){
geo.oformat |= METEOR_GEO_EVEN_ONLY;
}
// set the new geometry
if (ioctl(videoFd, METEORSETGEO, &geo) < 0) {
return FALSE;
}
mmap_size = frameBytes;
videoBuffer = (BYTE *)::mmap(0, mmap_size, PROT_READ, 0, videoFd, 0);
if (videoBuffer < 0) {
return FALSE;
} else {
canMap = 1;
}
// put the grabber into continuous capture mode
int mode = METEOR_CAP_CONTINOUS;
if (ioctl(videoFd, METEORCAPTUR, &mode) < 0 ) {
return FALSE;
}
}
// Copy a snapshot of the image from the mmap buffer
// Really there should be some synchronisation here to avoid tearing
// in the image, but we will worry about that later
if (converter != NULL)
return converter->Convert(videoBuffer, buffer, bytesReturned);
memcpy(buffer, videoBuffer, frameBytes);
if (bytesReturned != NULL)
*bytesReturned = frameBytes;
return TRUE;
}
void PVideoInputDevice_BSDCAPTURE::ClearMapping()
{
if (canMap == 1) {
// better stop grabbing first
// Really this should be in the Stop() function, but that is
// not actually called anywhere.
int mode = METEOR_CAP_STOP_CONT;
ioctl(videoFd, METEORCAPTUR, &mode);
if (videoBuffer != NULL)
::munmap(videoBuffer, mmap_size);
canMap = -1;
videoBuffer = NULL;
}
}
BOOL PVideoInputDevice_BSDCAPTURE::VerifyHardwareFrameSize(unsigned width,
unsigned height)
{
// Assume the size is valid
return TRUE;
}
int PVideoInputDevice_BSDCAPTURE::GetBrightness()
{
if (!IsOpen())
return -1;
unsigned char data;
if (::ioctl(videoFd, METEORGBRIG, &data) < 0)
return -1;
frameBrightness = (data << 8);
return frameBrightness;
}
int PVideoInputDevice_BSDCAPTURE::GetContrast()
{
if (!IsOpen())
return -1;
unsigned char data;
if (::ioctl(videoFd, METEORGCONT, &data) < 0)
return -1;
frameContrast = (data << 8);
return frameContrast;
}
int PVideoInputDevice_BSDCAPTURE::GetHue()
{
if (!IsOpen())
return -1;
char data;
if (::ioctl(videoFd, METEORGHUE, &data) < 0)
return -1;
frameHue = ((data + 128) << 8);
return frameHue;
}
BOOL PVideoInputDevice_BSDCAPTURE::SetBrightness(unsigned newBrightness)
{
if (!IsOpen())
return FALSE;
unsigned char data = (newBrightness >> 8); // rescale for the ioctl
if (::ioctl(videoFd, METEORSBRIG, &data) < 0)
return FALSE;
frameBrightness=newBrightness;
return TRUE;
}
BOOL PVideoInputDevice_BSDCAPTURE::SetContrast(unsigned newContrast)
{
if (!IsOpen())
return FALSE;
unsigned char data = (newContrast >> 8); // rescale for the ioctl
if (::ioctl(videoFd, METEORSCONT, &data) < 0)
return FALSE;
frameContrast = newContrast;
return TRUE;
}
BOOL PVideoInputDevice_BSDCAPTURE::SetHue(unsigned newHue)
{
if (!IsOpen())
return FALSE;
char data = (newHue >> 8) - 128; // ioctl takes a signed char
if (::ioctl(videoFd, METEORSHUE, &data) < 0)
return FALSE;
frameHue=newHue;
return TRUE;
}
BOOL PVideoInputDevice_BSDCAPTURE::GetParameters (int *whiteness, int *brightness,
int *colour, int *contrast, int *hue)
{
if (!IsOpen())
return FALSE;
unsigned char data;
char signed_data;
if (::ioctl(videoFd, METEORGBRIG, &data) < 0)
return -1;
*brightness = (data << 8);
if (::ioctl(videoFd, METEORGCONT, &data) < 0)
return -1;
*contrast = (data << 8);
if (::ioctl(videoFd, METEORGHUE, &signed_data) < 0)
return -1;
*hue = ((data + 128) << 8);
// The bktr driver does not have colour or whiteness ioctls
// so set them to the current global values
*colour = frameColour;
*whiteness = frameWhiteness;
// update the global settings
frameBrightness = *brightness;
frameContrast = *contrast;
frameHue = *hue;
return TRUE;
}
BOOL PVideoInputDevice_BSDCAPTURE::TestAllFormats()
{
return TRUE;
}
// End Of File ///////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -